diff --git a/docs/schema/V1/swagger.verified.json b/docs/schema/V1/swagger.verified.json index bcde68739..37754ac46 100644 --- a/docs/schema/V1/swagger.verified.json +++ b/docs/schema/V1/swagger.verified.json @@ -231,7 +231,7 @@ "type": "string" }, "process": { - "description": "Optional process identifier used to indicate a business process this dialog belongs to ", + "description": "Optional process identifier used to indicate a business process this dialog belongs to", "nullable": true, "type": "string" }, @@ -262,7 +262,7 @@ ] }, "systemLabel": { - "description": "Set the system label of the dialog Migration purposes ", + "description": "Set the system label of the dialog Migration purposes", "nullable": true, "oneOf": [ { @@ -751,6 +751,13 @@ }, "type": "array" }, + "id": { + "description": "A self-defined UUIDv7 may be provided to support idempotent creation of transmission attachments. If not provided, a new UUIDv7 will be generated.", + "example": "01913cd5-784f-7d3b-abef-4c77b1f0972d", + "format": "guid", + "nullable": true, + "type": "string" + }, "urls": { "description": "The URLs associated with the attachment, each referring to a different representation of the attachment.", "items": { @@ -4089,6 +4096,13 @@ }, "type": "array" }, + "id": { + "description": "A self-defined UUIDv7 may be provided to support idempotent creation of transmission attachments. If not provided, a new UUIDv7 will be generated.", + "example": "01913cd5-784f-7d3b-abef-4c77b1f0972d", + "format": "guid", + "nullable": true, + "type": "string" + }, "urls": { "description": "The URLs associated with the attachment, each referring to a different representation of the attachment.", "items": { diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommand.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommand.cs index f6e4beebd..e8dd6fc0e 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommand.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommand.cs @@ -117,5 +117,11 @@ private async Task EnsureNoExistingUserDefinedIds(DialogEntity dialog, Cancellat { _domainContext.AddError(DomainFailure.EntityExists(existingTransmissionIds)); } + + var existingTransmissionAttachmentIds = await _db.GetExistingIds(dialog.Transmissions.SelectMany(t => t.Attachments), cancellationToken); + if (existingTransmissionAttachmentIds.Count != 0) + { + _domainContext.AddError(DomainFailure.EntityExists(existingTransmissionAttachmentIds)); + } } } diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs index 113924872..a9da828ef 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs @@ -277,6 +277,10 @@ public CreateDialogTransmissionAttachmentDtoValidator( IValidator> localizationsValidator, IValidator urlValidator) { + RuleFor(x => x.Id) + .IsValidUuidV7() + .UuidV7TimestampIsInPast(); + RuleFor(x => x.DisplayName) .SetValidator(localizationsValidator); RuleFor(x => x.Urls) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogDto.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogDto.cs index 3722710c3..3d706fe9f 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogDto.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogDto.cs @@ -67,7 +67,7 @@ public class CreateDialogDto public DateTimeOffset? DueAt { get; set; } /// - /// Optional process identifier used to indicate a business process this dialog belongs to + /// Optional process identifier used to indicate a business process this dialog belongs to /// public string? Process { get; set; } /// @@ -104,7 +104,7 @@ public class CreateDialogDto public DialogStatus.Values Status { get; set; } /// - /// Set the system label of the dialog Migration purposes + /// Set the system label of the dialog Migration purposes /// public SystemLabel.Values? SystemLabel { get; set; } /// @@ -527,6 +527,12 @@ public sealed class CreateDialogDialogAttachmentUrlDto public sealed class CreateDialogTransmissionAttachmentDto { + /// + /// A self-defined UUIDv7 may be provided to support idempotent creation of transmission attachments. If not provided, a new UUIDv7 will be generated. + /// + /// 01913cd5-784f-7d3b-abef-4c77b1f0972d + public Guid? Id { get; set; } + /// /// The display name of the attachment that should be used in GUIs. /// diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/MappingProfile.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/MappingProfile.cs index bd3591f2f..aa7d94d00 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/MappingProfile.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/MappingProfile.cs @@ -81,8 +81,7 @@ public MappingProfile() .ForMember(dest => dest.ActorType, opt => opt.Ignore()) .ForMember(dest => dest.ActorTypeId, opt => opt.MapFrom(src => src.ActorType)); - CreateMap() - .ForMember(x => x.Id, opt => opt.Ignore()); + CreateMap(); CreateMap() .ForMember(x => x.Id, opt => opt.Ignore()) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs index 4aaac0441..421857dba 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommand.cs @@ -282,6 +282,17 @@ private async Task AppendTransmission(DialogEntity dialog, UpdateDialogDto dto, return; } + var newTransmissionAttachments = newDialogTransmissions + .SelectMany(x => x.Attachments) + .ToList(); + + var existingTransmissionAttachmentIds = await _db.GetExistingIds(newTransmissionAttachments, cancellationToken); + if (existingTransmissionAttachmentIds.Count != 0) + { + _domainContext.AddError(DomainFailure.EntityExists(existingTransmissionAttachmentIds)); + return; + } + dialog.Transmissions.AddRange(newDialogTransmissions); // Tell ef explicitly to add transmissions as new to the database. _db.DialogTransmissions.AddRange(newDialogTransmissions); diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs index 1cf5b1c11..77cee4e86 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs @@ -114,6 +114,10 @@ public UpdateDialogTransmissionAttachmentDtoValidator( IValidator> localizationsValidator, IValidator urlValidator) { + RuleFor(x => x.Id) + .IsValidUuidV7() + .UuidV7TimestampIsInPast(); + RuleFor(x => x.DisplayName) .SetValidator(localizationsValidator); RuleFor(x => x.Urls) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogDto.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogDto.cs index 8182b048d..1c388a844 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogDto.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogDto.cs @@ -510,6 +510,12 @@ public sealed class UpdateDialogDialogAttachmentUrlDto public sealed class UpdateDialogTransmissionAttachmentDto { + /// + /// A self-defined UUIDv7 may be provided to support idempotent creation of transmission attachments. If not provided, a new UUIDv7 will be generated. + /// + /// 01913cd5-784f-7d3b-abef-4c77b1f0972d + public Guid? Id { get; set; } + /// /// The display name of the attachment that should be used in GUIs. ///