refactor(AnnotationDto): split AnnotationDto into AnnotationCreateDto and AnnotationDto

- Introduced AnnotationCreateDto for creation-specific properties
- AnnotationDto now inherits from AnnotationCreateDto and includes Id, AddedWhen, ChangedWhen, and ChangedWho
- Added Type property to AnnotationCreateDto
 - remove CreateAnnotationCommand
This commit is contained in:
tekh 2025-10-21 11:42:01 +02:00
parent 0ca54fe1fe
commit 8ae0f79365
7 changed files with 31 additions and 186 deletions

View File

@ -1,136 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Query;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.Annotations.Commands;
/// <summary>
///
/// </summary>
public record CreateAnnotationCommand : EnvelopeReceiverQueryBase, IRequest<IEnumerable<Signature>>
{
private static readonly JsonSerializerOptions SerializerOptions = new()
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = null
};
/// <summary>
///
/// </summary>
[JsonIgnore]
public string PSPDFKitInstantJSON
{
set => PSPDFKitInstant = JsonSerializer.Deserialize<dynamic>(value, SerializerOptions) ?? new ExpandoObject();
}
/// <summary>
///
/// </summary>
[JsonIgnore]
public ExpandoObject PSPDFKitInstant { get; set; } = null!;
}
/// <summary>
///
/// </summary>
public static class CreateAnnotationCommandExtensions
{
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="envelopeKey"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<IEnumerable<Signature>> CreateAnnotation(this ISender sender, string envelopeKey, CancellationToken cancel = default)
=> sender.Send(new CreateAnnotationCommand() { Key = envelopeKey }, cancel);
}
/// <summary>
///
/// </summary>
public class CreateAnnotationCommandHandler : IRequestHandler<CreateAnnotationCommand, IEnumerable<Signature>>
{
/// <summary>
///
/// </summary>
private readonly IRepository<Signature> _signRepo;
/// <summary>
///
/// </summary>
private readonly IRepository<Annotation> _annotRepo;
/// <summary>
///
/// </summary>
/// <param name="signRepo"></param>
/// <param name="annotRepo"></param>
public CreateAnnotationCommandHandler(IRepository<Signature> signRepo, IRepository<Annotation> annotRepo)
{
_signRepo = signRepo;
_annotRepo = annotRepo;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<IEnumerable<Signature>> Handle(CreateAnnotationCommand request, CancellationToken cancel)
{
var query = _signRepo.Query;
#region Envelope Query
if (request.Envelope.Id is int envelopeId)
query = query.Where(annot => annot.Document.EnvelopeId == envelopeId);
if (request.Envelope.Uuid is string envelopeUuid)
query = query.Where(annot => annot.Document.Envelope!.Uuid == envelopeUuid);
#endregion
// Receiver Query
query = query.Where(request.Receiver);
var elements = await query.ToListAsync(cancel);
foreach (var element in elements)
{
var annots = ParsePSPDFKitInstant(request.PSPDFKitInstant, element.Id)
.Select(annot => new Annotation()
{
ElementId = element.Id,
Name = annot.Key,
Value = annot.Value,
AddedWhen = DateTime.UtcNow
});
element.Annotations = await _annotRepo.CreateAsync(annots, cancel);
}
return elements;
}
/// <summary>
///
/// </summary>
/// <param name="instant"></param>
/// <param name="elementId"></param>
/// <returns></returns>
public static Dictionary<string, string> ParsePSPDFKitInstant(ExpandoObject instant, int elementId)
{
Dictionary<string, string> annots = new();
// parse json here
return annots;
}
}

View File

@ -1,20 +0,0 @@
using AutoMapper;
using EnvelopeGenerator.Application.Annotations.Commands;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Annotations;
/// <summary>
///
/// </summary>
public class MappingProfile : Profile
{
/// <summary>
///
/// </summary>
public MappingProfile()
{
CreateMap<CreateAnnotationCommand, Annotation>()
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
}
}

View File

@ -3,13 +3,8 @@
/// <summary>
///
/// </summary>
public record AnnotationDto
public record AnnotationCreateDto
{
/// <summary>
///
/// </summary>
public long Id { get; init; }
/// <summary>
///
/// </summary>
@ -25,6 +20,22 @@ public record AnnotationDto
/// </summary>
public string Value { get; init; } = null!;
/// <summary>
///
/// </summary>
public string Type { get; init; } = null!;
}
/// <summary>
///
/// </summary>
public record AnnotationDto : AnnotationCreateDto
{
/// <summary>
///
/// </summary>
public long Id { get; init; }
/// <summary>
///
/// </summary>

View File

@ -51,6 +51,8 @@ public class MappingProfile : Profile
CreateMap<ReceiverDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
CreateMap<AnnotationCreateDto, Annotation>()
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
// Messaging mappings
// for GTX messaging

View File

@ -1,4 +1,4 @@
using EnvelopeGenerator.Application.Annotations.Commands;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Domain.Constants;
@ -12,7 +12,7 @@ namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned;
/// </summary>
/// <param name="Instant"></param>
/// <param name="Structured"></param>
public record PsPdfKitAnnotation(ExpandoObject Instant, IEnumerable<CreateAnnotationCommand> Structured);
public record PsPdfKitAnnotation(ExpandoObject Instant, IEnumerable<AnnotationCreateDto> Structured);
/// <summary>
///

View File

@ -1,4 +1,5 @@
using EnvelopeGenerator.Application.Annotations.Commands;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned.Handlers;
@ -11,15 +12,15 @@ public class AnnotationHandler : INotificationHandler<DocSignedNotification>
/// <summary>
///
/// </summary>
private readonly ISender _sender;
private readonly IRepository<Annotation> _repo;
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
public AnnotationHandler(ISender sender)
/// <param name="repository"></param>
public AnnotationHandler(IRepository<Annotation> repository)
{
_sender = sender;
_repo = repository;
}
/// <summary>
@ -28,11 +29,6 @@ public class AnnotationHandler : INotificationHandler<DocSignedNotification>
/// <param name="notification"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task Handle(DocSignedNotification notification, CancellationToken cancel) => _sender.Send(new CreateAnnotationCommand()
{
Envelope = new() { Id = notification.EnvelopeId },
Receiver = new() { Id = notification.ReceiverId },
PSPDFKitInstant = notification.PsPdfKitAnnotation.Instant
}, cancel);
}
public Task Handle(DocSignedNotification notification, CancellationToken cancel)
=> _repo.CreateAsync(notification.PsPdfKitAnnotation.Structured, cancel);
}

View File

@ -1,5 +1,4 @@
using EnvelopeGenerator.Application.Annotations.Commands;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Notifications.RemoveSignature;
using MediatR;
using Microsoft.AspNetCore.Mvc;
@ -28,11 +27,4 @@ public class TestAnnotationController : ControllerBase
await _mediator.Publish(new RemoveSignatureNotification(uuid));
return Ok();
}
[HttpPost("{envelopeKey}")]
public async Task<IActionResult> Create([FromRoute] string envelopeKey, CancellationToken cancel)
{
var annot = await _mediator.CreateAnnotation(envelopeKey, cancel);
return Ok(annot);
}
}