Application Handler Tests:
- ValidatePdfHandlerTests: PdfStream = new MemoryStream(pdfBytes)
- ValidatePdfAQueryHandlerTests: PdfStream = new MemoryStream(pdfBytes)
- CheckPdfAttachmentsQueryHandlerTests: PdfStream = new MemoryStream(pdfBytes)
- Remove Base64/PdfBytes property usage
Infrastructure Tests:
- DevExpressSwissQrCodeProcessorTests: LoadTestPdf() returns Stream
- All test methods use 'using var stream' pattern
- Add test: ExtractSwissQrCodeAsync_StreamNotAtBeginning_ThrowsBadRequestException
Result: All unit tests pass with Stream-based API
Deleted:
- PdfProcessingException: Obsolete, DevExpress exceptions now propagate naturally
- SwissQrCodeNotFoundException: Moved to Application layer (feature-specific exception)
Rationale:
- PdfProcessingException was wrapping library exceptions unnecessarily
- Better to let infrastructure exceptions propagate → middleware handles as 500
- SwissQrCodeNotFoundException is application-level concern, not domain
Remove FormatException/ArgumentException handling:
- These are framework exceptions, not application-specific
- May come from internal libraries (false positives for 400 Bad Request)
- Controllers now wrap Base64 conversion with BadRequestException explicitly
Remove PdfProcessingException handling:
- Exception type removed (obsolete)
- DevExpress exceptions now propagate naturally → 500 Internal Server Error
Current exception mapping:
- ValidationException (FluentValidation) → 400 Bad Request
- BadRequestException (custom) → 400 Bad Request
- NotFoundException (custom) → 404 Not Found
- SwissQrCodeNotFoundException (custom) → 404 Not Found
- All others → 500 Internal Server Error
- Unit tests for CheckPdfAttachmentsQueryHandler (3 tests)
- Integration tests for PdfAttachmentController (14 tests covering both multipart and JSON endpoints)
- Tests verify: attachment detection, metadata extraction, empty PDF handling, validation errors
- All tests using Stream API (mocks with It.IsAny<Stream>())
- Total: 17 new tests, all passing
- Move PdfMetadata, PdfAMetadata from Domain.Models.ValueObjects to Application.Common.DTOs
- Move AttachmentInfo, AttachmentMetadata from Domain.Models.ValueObjects to Application.Common.DTOs
- Reason: DTOs belong in Application layer, Domain should have zero external dependencies (Clean Architecture)
Removed detailed description of the `raw` parameter in XML
documentation for two methods in `SwissQrCodeController`.
Updated `<returns>` tag to simplify the explanation by
removing conditional details based on the `raw` parameter.
These changes affect methods handling multipart/form-data
PDF input and Base64 JSON input.
- Removed `<Folder>` elements in `DocumentOperator.Domain.csproj`
and replaced them with `<Compile Remove>`, `<EmbeddedResource Remove>`,
and `<None Remove>` to exclude specific directories.
- Removed unused `using DocumentOperator.Domain.Exceptions;` directive.
- Simplified `Split` method syntax for delimiter specification.
- Updated `return` statements to use concise parameter syntax.
- Removed page number validation logic in `DevExpressSwissQrCodeProcessor`.
- Replaced default page scanning logic with modern range expression.
- Overall, improved code clarity, reduced redundancy, and modernized syntax.
- Add 'raw' query parameter to both ExtractFromFile and ExtractFromBase64 methods
- Returns raw QR text lines when raw=true, parsed Bill object when raw=false (default)
- Remove obsolete 'references' parameter (not part of QR extraction logic)
- Add XML documentation for raw parameter
- Update ExceptionHandlingMiddleware to handle BadRequestException
- Update unit tests to assert (Bill, string[]) tuple return
- Update integration tests for new response structure (Bill + RawLines)
- Fix exception message assertion in DevExpressSwissQrCodeProcessorTests
- All 34 tests passing, 6 skipped (require real Swiss QR Bill PDFs)
- Add [Serializable] attribute to all custom exceptions
- Add protected constructors for serialization support
- Add XML documentation comments
- Update SwissQrCodeNotFoundException message format
- Change return type to tuple (Bill, string[])
- Remove custom parsing methods (ParseSwissQrBillContent, MapAddress, DetermineReferenceType)
- Use Codecrete QRBill.DecodeQrCodeText() for parsing
- Add SkiaSharp.QrCode v1.0.0 for QR decoding
- Remove obsolete ZXing and System.Drawing dependencies
- Add StringExtensions for QR code detection
- Raw lines properly split and trimmed from QR text
- Change SwissQrCodeExtractionResult to use Bill + RawLines
- Update ISwissQrCodeProcessor to return tuple (Bill, string[])
- Add Codecrete.SwissQRBill.Generator v3.4.0 package reference
- Update ExtractSwissQrCodeQuery handler to use AutoMapper for Bill->DTO mapping
- Remove References property from query (not needed for QR extraction)
- Add SwissQrBillDto, AddressDto, AlternativeSchemeDto for Codecrete Bill mapping
- Add BadRequestException to Domain exceptions
- DTOs include [Obsolete] warnings for deprecated fields (AddressLine1/2)
Introduced the `DualInputDocumentFilter` class to merge Swagger operations with the same path but different `[Consumes]` attributes (`multipart/form-data` and `application/json`) into a single operation. This ensures both content types are visible in the Swagger UI.
Updated `SwaggerConfiguration.cs` to:
- Resolve conflicting actions by keeping the first variant.
- Register the `DualInputDocumentFilter` to enable content type merging.
Integration test updates:
- PdfValidationControllerTests.cs (new)
- Test /api/pdf/validation/validate endpoint
- Test BOTH multipart/form-data AND Base64 JSON
- ExtractSwissQrCodeEndpointTests.cs (updated)
- Update endpoint path to /api/swissqrcode/extract
- Test BOTH input formats
Unit test updates:
- ValidatePdfHandlerTests.cs:
- Update for Query + Handler co-location
- Test AutoMapper integration
- ExtractSwissQrCodeHandlerTests.cs:
- Update for Query + Handler co-location
- Test AutoMapper integration
Deleted:
- DocumentEndpointsTests.cs (Minimal API tests, no longer relevant)
Result: 20/20 tests passing, Controller endpoint coverage
- Upgrade AutoMapper from 12.0.1 to 16.2.0
- Remove deprecated AutoMapper.Extensions.Microsoft.DependencyInjection v12.0.1
(deprecated 25 May 2023, DI moved to main package in v13.0+)
- Update DI registration: AddAutoMapper(cfg => {}, typeof(MappingProfile))
(v13.0+ requires Action<IMapperConfigurationExpression> + marker type)
Security fix:
- Resolves NU1903 vulnerability (GHSA-rvv3-g6hj-g44x DoS in v12.0.1)
Result: AutoMapper v16.2.0, 0 security warnings, all tests passing
Comprehensive architecture documentation including:
- Clean Architecture with Controller-based API (NOT Minimal API)
- Vertical slice architecture pattern
- Exception-based error handling (no Result<T>)
- Feature-driven development approach
- Primary constructor coding standards
- Git commit guidelines
- Swiss QR Bill backward compatibility decisions
Key decisions documented:
- Windows-only targeting (no Linux support needed)
- Support BOTH multipart/form-data AND Base64 JSON
- Separate endpoints for Combined Address (K-Type) legacy support
- Multi-tenancy deferred until after all sync features complete
Add missing XML doc comments to resolve CS1591 warnings:
- SerilogConfiguration: Class comment
- SwaggerConfiguration: Class and AddSwaggerDocumentation() method
- ExceptionHandlingMiddleware: Constructor and InvokeAsync() method
- RequestLoggingMiddleware: Placeholder class comment
- TenantResolutionMiddleware: Placeholder class comment
- Program: Partial class comment for integration test access
Result: 0 CS1591 warnings in DocumentOperator.API project