Files
DocumentService/DocumentOperator.Application/Common/DTOs/SwissQrCodeExtractionResult.cs
TekH d6e3a5fda1 refactor: Restructure Application layer with vertical slices and AutoMapper
Vertical slice architecture:

  - Move Features/Documents/{UseCase}/ to {UseCase}/Queries/

  - Query + Handler in SAME file (co-located)

  - Validator in separate file (single responsibility)

New structure:

  - ValidatePdf/Queries/ValidatePdfQuery.cs (Query + Handler)

  - ValidatePdf/Queries/ValidatePdfQueryValidator.cs

  - SwissQrCode/Queries/ExtractSwissQrCodeQuery.cs (Query + Handler)

  - SwissQrCode/Queries/ExtractSwissQrCodeQueryValidator.cs

AutoMapper integration:

  - Add Common/Mapping/MappingProfile.cs

  - Map PdfMetadata -> PdfValidationResult (domain -> DTO)

  - Map SwissQrCodeData -> SwissQrCodeExtractionResult (domain -> DTO)

  - Controllers now thin: pass request to MediatR, AutoMapper handles mapping

DTO improvements:

  - Rename: ValidatePdfResponse -> PdfValidationResult (business-friendly)

  - Rename: ExtractSwissQrCodeResponse -> SwissQrCodeExtractionResult

  - Support BOTH byte[] and Base64Pdf string (XOR validation)

  - Use modern C# 12 collection expressions

Code quality:

  - Use PascalCase for primary constructor parameters

  - Fix LoggingBehavior logging format

Deleted old structure:

  - Features/Documents/ValidatePdf/ (old horizontal structure)

  - Features/Documents/ExtractSwissQrCode/ (old horizontal structure)

  - Common/DTOs/{Request|Response} (replaced with {Result})

Result: Vertical slices, AutoMapper v16.2.0, thin controllers
2026-07-07 19:01:05 +02:00

117 lines
3.6 KiB
C#

namespace DocumentOperator.Application.Common.DTOs;
/// <summary>
/// Response containing extracted Swiss QR Code data and passed-through references.
/// </summary>
/// <param name="References">Reference strings passed through from the request</param>
/// <param name="QrCodeData">Parsed Swiss QR Code data from the last page of the PDF</param>
/// <example>
/// {
/// "references": ["REF-001", "REF-002"],
/// "qrCodeData": {
/// "qrType": "SPC",
/// "version": "0200",
/// "codingType": "1",
/// "iban": "CH4431999123000889012",
/// "creditor": {
/// "addressType": "S",
/// "name": "Robert Schneider AG",
/// "street": "Rue du Lac",
/// "buildingNumber": "1268",
/// "postalCode": "2501",
/// "city": "Biel",
/// "country": "CH"
/// },
/// "amount": 1949.75,
/// "currency": "CHF",
/// "referenceType": "QRR",
/// "reference": "210000000003139471430009017"
/// }
/// }
/// </example>
public record SwissQrCodeExtractionResult(
IReadOnlyList<string> References,
SwissQrCodeDataDto QrCodeData
);
/// <summary>
/// Swiss QR Code data according to Swiss QR Bill Standard 2.0.
/// Contains all fields defined in the Swiss Payment Standards.
/// </summary>
public record SwissQrCodeDataDto(
/// <summary>QR type - always "SPC" for Swiss Payment Code</summary>
string QrType,
/// <summary>Version of the Swiss QR Code standard (e.g., "0200" for version 2.0)</summary>
string Version,
/// <summary>Character set code (always "1" for UTF-8)</summary>
string CodingType,
/// <summary>IBAN of the creditor (payee)</summary>
string Iban,
/// <summary>Creditor (payee) information</summary>
AddressDataDto Creditor,
/// <summary>Ultimate creditor information (optional)</summary>
AddressDataDto? UltimateCreditor,
/// <summary>Payment amount (null if not specified)</summary>
decimal? Amount,
/// <summary>Currency code (CHF or EUR)</summary>
string Currency,
/// <summary>Ultimate debtor (payer) information (optional)</summary>
AddressDataDto? UltimateDebtor,
/// <summary>Reference type: "QRR" (QR Reference), "SCOR" (Creditor Reference ISO 11649), or "NON" (No Reference)</summary>
string ReferenceType,
/// <summary>Payment reference (format depends on ReferenceType)</summary>
string? Reference,
/// <summary>Unstructured message (max 140 characters)</summary>
string? UnstructuredMessage,
/// <summary>Bill information (structured data for automated processing)</summary>
string? BillInformation,
/// <summary>Alternative procedure parameters (up to 2 entries)</summary>
IReadOnlyList<string>? AlternativeProcedureParameters
);
/// <summary>
/// Address data in Swiss QR Code (creditor or debtor).
/// Can be either structured (S) or combined (K) format.
/// </summary>
public record AddressDataDto(
/// <summary>Address type: "S" for structured, "K" for combined</summary>
string AddressType,
/// <summary>Name of person or company</summary>
string Name,
/// <summary>Street name (structured address only)</summary>
string? Street,
/// <summary>Building number (structured address only)</summary>
string? BuildingNumber,
/// <summary>Address line 1 (combined address only)</summary>
string? AddressLine1,
/// <summary>Address line 2 (combined address only)</summary>
string? AddressLine2,
/// <summary>Postal code</summary>
string PostalCode,
/// <summary>City/town name</summary>
string City,
/// <summary>Two-letter country code (ISO 3166-1 alpha-2)</summary>
string Country
);