Files
DocumentService/DocumentService.Application/AddAttachments/AddAttachmentsCommand.cs
TekH 207c778f3a Refactor: Rename DocumentOperator to DocumentService
Updated project and solution files to rename and restructure
`DocumentOperator` to `DocumentService`. Modified project
references in `DocumentService.API.csproj`, `DocumentService.Application.csproj`,
and `DocumentService.Infrastructure.csproj` to reflect the new
naming convention. Updated `DocumentService.sln` to remove
old project references, add new ones, and adjust configuration
and nested project mappings accordingly. This change aligns
the project structure with the new naming convention.
2026-08-30 21:33:25 +02:00

91 lines
2.7 KiB
C#

using DocumentService.Application.Common.Interfaces;
using FluentValidation;
using MediatR;
namespace DocumentService.Application.AddAttachments;
/// <summary>
/// Command to add one or more attachments to a PDF document (supports PDF/A-3)
/// </summary>
public record AddAttachmentsCommand : IRequest<byte[]>
{
/// <summary>
/// PDF document stream. Must be positioned at the beginning (Position = 0).
/// </summary>
public required Stream PdfStream { get; init; }
/// <summary>
/// List of attachments to embed (filename, content, optional MIME type)
/// </summary>
public required IReadOnlyList<AttachmentFile> Attachments { get; init; }
}
/// <summary>
/// Represents a file to be attached to a PDF
/// </summary>
public record AttachmentFile
{
/// <summary>
/// File name (e.g., "invoice.xml", "document.pdf")
/// </summary>
public required string FileName { get; init; }
/// <summary>
/// File content as byte array
/// </summary>
public required byte[] Content { get; init; }
/// <summary>
/// MIME type (optional, e.g., "application/xml", "application/pdf")
/// If not provided, will be inferred from file extension
/// </summary>
public string? MimeType { get; init; }
}
/// <summary>
/// Handler for AddAttachmentsCommand
/// </summary>
public class AddAttachmentsCommandHandler(IPdfProcessor pdfProcessor)
: IRequestHandler<AddAttachmentsCommand, byte[]>
{
public async Task<byte[]> Handle(AddAttachmentsCommand request, CancellationToken cancellationToken)
{
// Convert to tuple list for IPdfProcessor
var attachmentTuples = request.Attachments
.Select(a => (a.FileName, a.Content, a.MimeType))
.ToList();
return await pdfProcessor.AddAttachmentsAsync(request.PdfStream, attachmentTuples);
}
}
/// <summary>
/// Validator for AddAttachmentsCommand
/// </summary>
public class AddAttachmentsCommandValidator : AbstractValidator<AddAttachmentsCommand>
{
public AddAttachmentsCommandValidator()
{
RuleFor(x => x.PdfStream)
.NotNull()
.WithMessage("PDF stream is required");
RuleFor(x => x.Attachments)
.NotNull()
.NotEmpty()
.WithMessage("At least one attachment is required");
RuleForEach(x => x.Attachments).ChildRules(attachment =>
{
attachment.RuleFor(a => a.FileName)
.NotEmpty()
.WithMessage("Attachment file name is required");
attachment.RuleFor(a => a.Content)
.NotNull()
.NotEmpty()
.WithMessage("Attachment content is required");
});
}
}