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.
91 lines
2.7 KiB
C#
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");
|
|
});
|
|
}
|
|
}
|