From b49482137fd5b413dfe78ab3011d668499b0cfc7 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 30 Jan 2026 15:04:05 +0100 Subject: [PATCH] Add ReadOnlyController for envelope sharing flows Introduced ReadOnlyController to manage read-only envelope sharing. Added a POST endpoint for authorized users to create read-only receivers, send notification emails, and record sharing events in envelope history. Includes error handling and logging throughout the process. --- .../Controllers/ReadOnlyController.cs | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 EnvelopeGenerator.GeneratorAPI/Controllers/ReadOnlyController.cs diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/ReadOnlyController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/ReadOnlyController.cs new file mode 100644 index 00000000..775f1bb8 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/ReadOnlyController.cs @@ -0,0 +1,95 @@ +using DigitalData.Core.Abstraction.Application.DTO; +using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly; +using EnvelopeGenerator.Application.Common.Interfaces.Services; +using EnvelopeGenerator.Domain.Constants; +using EnvelopeGenerator.GeneratorAPI.Extensions; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; + +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Manages read-only envelope sharing flows. +/// +[Route("api/[controller]")] +[ApiController] +public class ReadOnlyController : ControllerBase +{ + private readonly ILogger _logger; + private readonly IEnvelopeReceiverReadOnlyService _readOnlyService; + private readonly IEnvelopeMailService _mailService; + private readonly IEnvelopeHistoryService _historyService; + + /// + /// Initializes a new instance of the class. + /// + public ReadOnlyController(ILogger logger, IEnvelopeReceiverReadOnlyService readOnlyService, IEnvelopeMailService mailService, IEnvelopeHistoryService historyService) + { + _logger = logger; + _readOnlyService = readOnlyService; + _mailService = mailService; + _historyService = historyService; + } + + /// + /// Creates a new read-only receiver for the current envelope. + /// + /// Creation payload. + [HttpPost] + [Authorize(Roles = ReceiverRole.FullyAuth)] + public async Task CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto) + { + var authReceiverMail = User.GetAuthReceiverMail(); + if (authReceiverMail is null) + { + _logger.LogError("EmailAddress claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto)); + return Unauthorized(); + } + + var envelopeId = User.GetAuthEnvelopeId(); + if (envelopeId is null) + { + _logger.LogError("Envelope Id claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto)); + return Unauthorized(); + } + + createDto.AddedWho = authReceiverMail; + createDto.EnvelopeId = envelopeId; + + var creationRes = await _readOnlyService.CreateAsync(createDto: createDto); + + if (creationRes.IsFailed) + { + _logger.LogNotice(creationRes); + return StatusCode(StatusCodes.Status500InternalServerError); + } + + var readRes = await _readOnlyService.ReadByIdAsync(creationRes.Data.Id); + if (readRes.IsFailed) + { + _logger.LogNotice(creationRes); + return StatusCode(StatusCodes.Status500InternalServerError); + } + + var newReadOnly = readRes.Data; + + return await _mailService.SendAsync(newReadOnly).ThenAsync(SuccessAsync: async _ => + { + var histRes = await _historyService.RecordAsync((int)createDto.EnvelopeId, createDto.AddedWho, EnvelopeStatus.EnvelopeShared); + if (histRes.IsFailed) + { + _logger.LogError("Although the envelope was sent as read-only, the EnvelopeShared history could not be saved. Create DTO:\n{createDto}", JsonConvert.SerializeObject(createDto)); + _logger.LogNotice(histRes.Notices); + } + + return Ok(); + }, + + Fail: (msg, ntc) => + { + _logger.LogNotice(ntc); + return StatusCode(StatusCodes.Status500InternalServerError); + }); + } +}