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.
This commit is contained in:
2026-08-30 21:33:25 +02:00
parent 050cb55bf9
commit 207c778f3a
108 changed files with 37 additions and 37 deletions

View File

@@ -0,0 +1,113 @@
using DocumentService.Application.Common.Configuration;
using DocumentService.Application.Common.Interfaces;
using DocumentService.Domain.Common.Exceptions;
using FluentValidation;
using MediatR;
using Microsoft.Extensions.Options;
namespace DocumentService.Application.ExtractZugferd;
/// <summary>
/// Command to extract ZUGFeRD XML from a PDF document
/// </summary>
public record ExtractZugferdCommand : IRequest<ZugferdExtractionResult>
{
/// <summary>
/// PDF document stream. Must be positioned at the beginning (Position = 0).
/// </summary>
public required Stream PdfStream { get; init; }
}
/// <summary>
/// Handler for ExtractZugferdCommand.
/// Extracts ZUGFeRD XML from PDF and returns XML content
/// </summary>
public class ExtractZugferdCommandHandler(
IPdfProcessor pdfProcessor,
IOptions<ZugferdSettings> settings)
: IRequestHandler<ExtractZugferdCommand, ZugferdExtractionResult>
{
private readonly ZugferdSettings _settings = settings.Value;
public async Task<ZugferdExtractionResult> Handle(ExtractZugferdCommand request, CancellationToken cancellationToken)
{
// Get all attachments
var attachmentInfo = await pdfProcessor.CheckAttachmentsAsync(request.PdfStream);
// Find ZUGFeRD XML file using configured names and patterns
var zugferdAttachment = attachmentInfo.Attachments.FirstOrDefault(a =>
_settings.ZugferdFileNames.Any(name =>
a.FileName.Equals(name, StringComparison.OrdinalIgnoreCase)) ||
_settings.ZugferdFileNamePatterns.Any(pattern =>
a.FileName.Contains(pattern, StringComparison.OrdinalIgnoreCase)));
if (zugferdAttachment == null)
{
throw new NotFoundException("ZUGFeRD XML not found in PDF attachments");
}
// Reset stream position for extraction
request.PdfStream.Position = 0;
// Extract all attachments as ZIP
byte[] zipBytes = await pdfProcessor.ExtractAttachmentsAsync(request.PdfStream);
// Find ZUGFeRD XML in ZIP
using var zipStream = new MemoryStream(zipBytes);
using var zipArchive = new System.IO.Compression.ZipArchive(zipStream, System.IO.Compression.ZipArchiveMode.Read);
var zugferdEntry = zipArchive.Entries.FirstOrDefault(e =>
e.Name.Equals(zugferdAttachment.FileName, StringComparison.OrdinalIgnoreCase));
if (zugferdEntry == null)
{
throw new NotFoundException($"ZUGFeRD XML '{zugferdAttachment.FileName}' not found in extracted attachments");
}
// Read XML content
using var entryStream = zugferdEntry.Open();
using var reader = new StreamReader(entryStream);
string xmlContent = await reader.ReadToEndAsync(cancellationToken);
return new ZugferdExtractionResult
{
FileName = zugferdAttachment.FileName,
XmlContent = xmlContent,
FileSize = zugferdAttachment.SizeBytes
};
}
}
/// <summary>
/// Validator for ExtractZugferdCommand.
/// </summary>
public class ExtractZugferdCommandValidator : AbstractValidator<ExtractZugferdCommand>
{
public ExtractZugferdCommandValidator()
{
RuleFor(x => x.PdfStream)
.NotNull()
.WithMessage("PDF stream is required");
}
}
/// <summary>
/// Result DTO for ZUGFeRD extraction
/// </summary>
public record ZugferdExtractionResult
{
/// <summary>
/// ZUGFeRD XML file name
/// </summary>
public required string FileName { get; init; }
/// <summary>
/// ZUGFeRD XML content as string
/// </summary>
public required string XmlContent { get; init; }
/// <summary>
/// File size in bytes
/// </summary>
public long FileSize { get; init; }
}