Commit Graph

154 Commits

Author SHA1 Message Date
75bea9ef29 Refactor DTOs and tests; add framework-specific handling
Refactored the codebase to use shared DTOs from `DocumentService.Application.Common.DTOs`, removing inline DTO definitions in client interfaces and tests. Introduced conditional compilation to handle framework-specific differences in DTOs and handlers.

Updated test cases to align with the new DTO structures, including `SwissQrCodeExtractionResult`, `PdfValidationResult`, and `ZugferdExtractionResult`. Adjusted test data to match updated DTO properties.

Cleaned up solution and project files, ensuring proper references and organization. Removed unused files and fixed project references in `DocumentService.Tests.csproj`. Improved maintainability and consistency across the codebase.
2026-08-31 00:54:38 +02:00
108e522316 Add multi-targeting and refactor project structure
Enabled multi-targeting in `DocumentService.Application` to support `net462`, `net480`, and `net8.0`. Updated dependencies with framework-specific versions and added conditional configurations for compatibility.

Refactored `DocumentService.Client` by removing redundant enums and unused code. Adjusted namespaces and project references to streamline the codebase and improve maintainability.

These changes modernize the project, enhance compatibility, and align with modular design principles.
2026-08-31 00:53:34 +02:00
95d67567f0 Support multiple frameworks and set C# language version
Updated the project to target multiple frameworks (`net462`,
`net480`, and `net8.0`) by replacing `<TargetFramework>` with
`<TargetFrameworks>`. Added `<LangVersion>` property set to
`latest` to enable the use of the latest C# language features.
Adjusted `<Nullable>` property formatting for consistency.
2026-08-30 22:20:12 +02:00
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
050cb55bf9 test: strengthen PdfValidationClient tests (IsEncrypted + full field assertions)
- Add IsEncrypted=true deserialization test (EncryptedPdf_DeserializesIsEncryptedTrue)
- Add HasAttachments/AttachmentCount assertions on Bytes overload
- Add 400/500 error tests for both byte[] overloads of ValidatePdfAAsync
- Strengthen ValidatePdfAAsync assertions (Errors count, Warnings count)
- Extract BuildError() helper to reduce boilerplate
- Total: 8 -> 11 tests
2026-08-28 11:46:37 +02:00
7559028164 test: add FluentValidation unit tests for all command/query validators
ValidatorTests.cs covers 21 scenarios across 4 validators:

MergePdfsCommandValidator (3):
- TwoOrMoreStreams passes, SingleStream fails, NullStreams fails

AddAnnotationValidator (7):
- Valid circle passes, FreeText without content fails,
  TextMarkup without style fails, invalid/valid color hex,
  zero page number fails, invalid rectangle (X2<X1) fails

AddStampValidator (6):
- Valid text stamp passes, missing Text/ImageBytes/PredefinedType each fail,
  opacity > 1.0 fails, invalid color hex fails

ConvertToPdfACommandValidator (4):
- All valid levels pass, invalid level fails, empty level fails, null stream fails
2026-08-28 11:46:28 +02:00
fbaefe1fd2 test: add Application handler tests for all missing features
New test files (4 tests each — 2 success + 2 failure):
- MergePdfsCommandHandlerTests: TwoStreams, WithPageRanges, BadRequest, GenericException
- AddAnnotationHandlerTests: TextMarkup, FreeText, BadRequest (page OOB), GenericException
- AddStampHandlerTests: TextStamp, PredefinedStamp, BadRequest (opacity), GenericException
- ExtractPdfAttachmentsHandlerTests: ReturnsZip, NotFoundException, BadRequest, GenericException
- ConvertPdfAHandlerTests (ConvertTo + ConvertFrom):
  ConvertTo: ValidLevel, NotImplemented, BadRequest
  ConvertFrom: ValidPdfA, BadRequest, GenericException
2026-08-28 11:46:18 +02:00
9040aed1da test: rewrite existing Application handler tests (no mapper mock, full assertions)
ValidatePdfHandlerTests:
- Remove IMapper mock (handler no longer uses mapper)
- Add: EncryptedPdf_ReturnsIsEncryptedTrue
- Add: PdfWithAttachments_ReturnsAttachmentData
- Add: ProcessorThrowsGenericException_PropagatesException

ValidatePdfAQueryHandlerTests:
- Remove IMapper mock
- Strengthen assertions (Errors count, Warnings content)
- Add: ProcessorThrowsGenericException_PropagatesException

CheckPdfAttachmentsQueryHandlerTests:
- Remove duplicate Handle_WithBase64Pdf test (identical to WithPdfBytes)
- Add: ProcessorThrowsBadRequest_PropagatesException
- Add: ProcessorThrowsGenericException_PropagatesException
- Strengthen: assert individual attachment fields (FileName, MimeType, Size)
2026-08-28 11:46:09 +02:00
9a9d775fec test: strengthen DevExpressPdfProcessor tests (IsEncrypted + DetectEncryption)
- Rename ValidateAsync_ValidPdf_ReturnsPdfMetadata to ReturnsPdfValidationResult
  and add FileSizeMB assertion
- Add Encryption Detection region with 4 tests:
  - NormalPdf_IsEncryptedFalse (real PDF via ValidateAsync)
  - ValidatePdfAAsync_NormalPdf_EncryptedFalse (real PDF via ValidatePdfAAsync)
  - DetectEncryption_TrailerWithEncryptEntry_ReturnsTrue (reflection, byte scan)
  - DetectEncryption_NoEncryptEntry_ReturnsFalse (reflection, byte scan)
  - DetectEncryptionKeyword_NotStandaloneToken_ReturnsFalse (token boundary check)
- Add IsEncrypted.Should().BeFalse() assertion to attachment count test
2026-08-28 11:45:59 +02:00
2630860e7e test: add encryptedPdf.pdf test fixture with /Encrypt in trailer
Minimal hand-crafted PDF containing a Standard encryption dictionary
referenced from the trailer (/Encrypt 4 0 R). Used by DetectEncryption
unit tests to verify byte-level encryption detection.

Registered as EmbeddedResource in DocumentService.Tests.csproj.
2026-08-28 11:45:50 +02:00
7b9318e75c fix: replace ASCII-based DetectEncryption with byte-level trailer scan
Old implementation used Encoding.ASCII.GetString() which:
- Corrupts binary PDF bytes 0x80-0xFF -> '?' (false negatives)
- Matches '/Encrypt' anywhere in document content (false positives)
- Matches '/Encrypted', '/EncryptionKey' etc. (token boundary not checked)

New implementation uses ReadOnlySpan<byte> with three strategies:
1. Search last 2KB (trailer region) - fast path, covers standard PDFs
2. Search first 2KB (linearized PDFs have duplicate trailer at start)
3. Full-file fallback for PDF 1.5+ compressed xref streams, with token
   boundary check (next byte must be space/newline/tab/'<'/'/'/'[')
   to avoid matching '/Encrypted' or '/EncryptionKey'

Also: DevExpressPdfProcessor.ValidateAsync now returns PdfValidationResult
directly (no more PdfMetadata wrapper), includes IsEncrypted field.
2026-08-28 11:45:43 +02:00
ef78fb5cdd refactor: remove PdfMetadata/PdfAMetadata, use result DTOs directly
PdfMetadata and PdfAMetadata were redundant intermediate classes that
mirrored PdfValidationResult and PdfAValidationResult exactly.

Changes:
- Delete PdfMetadata.cs and PdfAMetadata.cs
- IPdfProcessor.ValidateAsync now returns PdfValidationResult directly
- IPdfProcessor.ValidatePdfAAsync now returns PdfAValidationResult directly
- ValidatePdfQueryHandler: remove IMapper dependency, return result directly
- ValidatePdfAQueryHandler: remove IMapper dependency, return result directly
- MappingProfile: remove the two now-obsolete CreateMap calls
- PdfValidationResult: add IsEncrypted parameter (was missing)
2026-08-28 11:45:33 +02:00
9cb964379f chore: Add DocumentService.Client project reference to Tests 2026-08-11 10:30:24 +02:00
4363b5e961 test: Update integration tests to use moved request DTOs 2026-08-11 10:30:15 +02:00
0059a70055 test: Add unit tests for DocumentService.Client 2026-08-11 10:30:05 +02:00
d08e40d551 chore: Add DocumentService.Client project reference to API 2026-08-11 10:29:55 +02:00
757f56b9f8 refactor: Move request DTOs to DocumentService.Client.Models namespace 2026-08-11 10:29:44 +02:00
8c72502913 chore: Add DocumentService.Client project configuration 2026-08-11 10:29:34 +02:00
058cb9327d feat: Add specialized client implementations for PDF operations 2026-08-11 10:29:24 +02:00
14250f0b4b feat: Add DocumentService.Client base infrastructure 2026-08-11 10:29:14 +02:00
b3a07f1348 Add interfaces and DTOs for PDF operations support
Introduced multiple interfaces and DTOs to support a wide range of
PDF-related operations, including attachment handling, conversion,
validation, annotation, stamping, and metadata extraction.

Key changes:
- Added `DocumentServiceClientOptions` for HTTP client config.
- Introduced `IPdfAttachmentClient` for attachment operations.
- Added `IPdfConversionClient` for PDF/A conversion (marked obsolete).
- Added `IPdfOperationsClient` for merge, annotate, and stamp ops.
- Introduced `IPdfValidationClient` for PDF and PDF/A validation.
- Added `ISwissQrCodeClient` for Swiss QR Code extraction.
- Added `IZugferdClient` for ZUGFeRD detection and extraction.
- Created request DTOs for Base64-encoded operations.
- Added enums for annotation, stamp, and validation configurations.

These changes provide a flexible and extensible foundation for
interacting with PDF documents, supporting both multipart and
Base64-encoded inputs, and ensuring type safety with enums and records.
2026-07-30 16:59:54 +02:00
d477eb5a28 Add DocumentService.Client project to solution
Introduced a new `DocumentService.Client` project targeting `net462`, `net480`, and `net8.0`. The project includes metadata for NuGet packaging, such as `PackageId`, `Authors`, and `Company`, and references `Microsoft.Extensions.DependencyInjection` and `Microsoft.Extensions.Logging`.

Updated `DocumentService.sln` to include the new project, its build configurations, and solution folder associations.

Added `icon.png` as the NuGet package icon and included it in the project file.
2026-07-30 14:15:31 +02:00
3da6ca8323 Remove DocumentOperator.sln and associated projects
The `DocumentOperator.sln` file was completely removed, along with all associated projects (`DocumentService.API`, `DocumentService.Application`, `DocumentService.Infrastructure`, `DocumentService.Domain`, `DocumentService.Tests`) and solution folders (`Solution Items`, `fake-pfd`, `core`, `presentation`, `infrastructure`, `src`, `tests`).

Markdown files (`AGENTS.md`, `CONTROLLER_ENDPOINTS.md`, `REQUIRED_FEATURES.md`) and PDF files (`form.pdf`, `multi-page.pdf`, `one-page.pdf`, `with-image.pdf`) were also deleted.

Solution configurations, platform settings, project nesting, and the `SolutionGuid` were removed, indicating the solution is no longer part of the codebase. This change may be part of a restructuring, migration, or deprecation effort.
2026-07-30 14:04:55 +02:00
0e88b349d7 Rebrand project: DocumentOperator to DocumentService
This commit implements a complete rebranding of the project:
- Updated all namespaces from `DocumentOperator` to `DocumentService`.
- Renamed file paths, embedded resources, and test data references.
- Updated configuration keys, logging paths, and Redis instance names.
- Revised documentation to reflect the new project name.
- Modified project and solution files to align with the new structure.
- Updated class names, DTOs, commands, queries, and handlers.
- Adjusted middleware, controllers, and API endpoints.
- Updated Swagger metadata and API titles to `DocumentService API`.
- Refactored test namespaces, resource paths, and embedded resources.
- Updated build and deployment configurations for the new name.
- Replaced all references to `DocumentOperator` in comments and literals.

These changes ensure consistency across the codebase and documentation.
2026-07-30 14:02:56 +02:00
b6bb894257 Refactor: Rename DocumentOperator to DocumentService
Renamed and restructured project references across the solution
to replace `DocumentOperator` projects with `DocumentService`
projects. Updated all `.csproj` files to reflect the new project
names and references.

Modified the solution file (`DocumentOperator.sln`) to remove
`DocumentOperator` projects and add corresponding `DocumentService`
projects, including `DocumentService.API`, `DocumentService.Application`,
`DocumentService.Infrastructure`, `DocumentService.Domain`, and
`DocumentService.Tests`.

This change aligns the project structure with the new naming
convention or organizational standards.
2026-07-30 14:01:29 +02:00
9cff7ee459 Add new projects and update solution structure
Added the following projects to `DocumentOperator.sln`:
- `core`, `presentation`, `infrastructure`, `src`, `tests`
Updated `GlobalSection(NestedProjects)` to define hierarchical
relationships between projects for better organization. Nested
projects include `core`, `presentation`, and `infrastructure`
under `src`, among others.
2026-07-30 13:46:06 +02:00
a6694bfce7 Add PDF attachment and PDF/A conversion features
Introduced endpoints for embedding attachments in PDFs and converting
between standard PDFs and PDF/A formats. Added `PdfAttachmentController`
and `PdfConversionController` with multipart/form-data and Base64-based
support. Implemented commands, handlers, and validators for these
operations.

Extended `IPdfProcessor` with methods for adding attachments and
PDF/A conversion. Partially implemented functionality in
`DevExpressPdfProcessor`, including `ConvertFromPdfAAsync`.

Added `attachment.xml` and `withoutAttachment.pdf` as resources for
testing. Marked endpoints as `[Obsolete]` to indicate incomplete
implementation. Improved validation and error handling for commands.
2026-07-30 13:43:55 +02:00
a242458d2f Add support for XML file output in ZUGFeRD extraction
Enhanced `ExtractZugferdFromFile` and `ExtractZugferdFromBase64`
methods to support output as an XML file (`application/xml`)
or JSON (default). Introduced `asFile` and `format` query
parameters to control the output format. Updated XML
documentation and `ProducesResponseType` attributes to reflect
these changes. Default values for `CancellationToken` were
set to `default` for improved usability.
2026-07-30 10:47:48 +02:00
94123cd1be Add ZUGFeRD detection and extraction functionality
Introduced `ZugferdController` to handle ZUGFeRD-related operations, including detection and extraction of ZUGFeRD XML from PDFs via file upload or Base64-encoded payloads. Integrated `MediatR` for query/command handling.

Added `ZugferdSettings` for configurable file names and patterns, and updated `appsettings.json` and `Program.cs` to support this configuration.

Implemented `HasZugferdQuery` and `ExtractZugferdCommand` with their respective handlers and validators. Added DTOs (`ZugferdCheckResult`, `ZugferdExtractionResult`) for operation results.

Included `ZUGFeRD-Example.pdf` for testing and integrated `Serilog.Ui.Core.Extensions` for logging.
2026-07-30 10:16:43 +02:00
080c2ac2a0 refactor(api): Pass IConfiguration to AddApplication
- Update AddApplication call with builder.Configuration parameter
- Required for license key reading from appsettings.json
2026-07-21 16:52:32 +02:00
97122d0bbd feat(license): Configure MediatR + AutoMapper with LuckyPennySoft license
- Read LuckyPennySoftLicenseKey from appsettings.json
- Set MediatR config.LicenseKey
- Set AutoMapper cfg.LicenseKey
- AddApplication now requires IConfiguration parameter
2026-07-21 16:52:27 +02:00
e9d1586266 chore(deps): Add Microsoft.Extensions.Configuration packages
- Microsoft.Extensions.Configuration.Abstractions 10.0.10
- Microsoft.Extensions.Configuration.Binder 10.0.10
- Required for reading appsettings.json in Application layer
2026-07-21 16:52:21 +02:00
2804993ea6 feat(api): Enable conditional Swagger/Scalar in production
Program.cs changes:
- Add Scalar.AspNetCore using
- Register SwaggerSettings with Options Pattern
- Pass IConfiguration to AddSwaggerDocumentation()
- Conditional middleware: Development OR EnableInProduction=true
- Add Swagger UI with custom endpoint configuration
- Add Scalar UI at /scalar/v1 (DeepSpace theme, C# HttpClient target)

Access URLs:
- Swagger UI: https://localhost:7186/swagger
- Scalar UI: https://localhost:7186/scalar/v1
- Serilog UI: https://localhost:7186/serilog-ui

Production behavior: Swagger+Scalar enabled by default (configurable)
2026-07-21 15:01:56 +02:00
06a9dc7385 chore(deps): Add Scalar.AspNetCore 1.2.58 package
- Modern Swagger UI alternative with better UX
- DeepSpace theme
- C# HttpClient code generation support
2026-07-21 15:01:46 +02:00
4b5c763f24 refactor(swagger): Read SwaggerConfiguration from appsettings
- Update AddSwaggerDocumentation to accept IConfiguration parameter
- Read SwaggerSettings from configuration (Title/Version/Description)
- Replace hardcoded values with dynamic settings
- Add Microsoft.Extensions.Options using for IOptions support
2026-07-21 15:01:38 +02:00
559c726118 feat(swagger): Configure Swagger settings in appsettings.json
- Add SwaggerSettings section with EnableInProduction: true
- Title: DocumentOperator API
- Version: v1
- Description: PDF document processing service using DevExpress
- Production Swagger enabled by default
2026-07-21 15:01:29 +02:00
1106a86ec3 feat(swagger): Add SwaggerSettings configuration class
- Add SwaggerSettings with EnableInProduction flag (default: true)
- Title, Version, Description configurable via appsettings.json
- Enables production Swagger access for debugging/testing
2026-07-21 15:01:22 +02:00
89436406ce Add PDF Stamp Operation feature with endpoints and tests
Implemented the "PDF Stamp Operation" feature, allowing users to add text, image, or predefined stamps to PDF documents.

- Added `FEATURE_7_PLAN.md` with detailed implementation plan.
- Introduced enums (`StampType`, `PredefinedStampType`, `StampPlacement`) in the domain layer.
- Added `AddStampAsync` method to `IPdfProcessor` interface.
- Implemented `AddStampAsync` in `DevExpressPdfProcessor` using DevExpress API.
- Created unit tests for `AddStampAsync` covering various scenarios.
- Added `AddStampCommand` in the application layer with validation rules.
- Created two new endpoints in `PdfOperationsController` for multipart and Base64 inputs.
- Added DTOs for handling endpoint requests.
- Wrote integration tests for endpoints to ensure correctness.
- Updated `AGENTS.md` and added DevExpress API references.
- Documented challenges, considerations, and estimated effort.

This commit completes the "PDF Stamp Operation" feature with full test coverage and documentation.
2026-07-21 14:45:30 +02:00
c96cbbc8d3 ee
Add IIS publish profile for Web Deploy packaging

Added `IISProfile.pubxml` to configure publishing via Web Deploy.
Set the publish method to `Package` and specified build settings
(`Release`, `Any CPU`). Configured the output package location,
enabled single-file packaging, and set the IIS app path to
`DocumentOperator.API`. Target framework updated to .NET 8.0.
2026-07-21 14:44:21 +02:00
9b85e55cd4 docs: Update AGENTS.md for Feature 7 completion + Serilog.UI
Updates:
- Mark stamp endpoint as DONE in Current Status table
- Add Serilog.UI packages to Key Libraries table
- Update test count (Feature 7 instead of Feature 6)
- Add Serilog UI URL to Build/Run section
- Document log viewer access at /serilog-ui
2026-07-21 14:39:40 +02:00
536413bafe feat(logging): Configure Serilog SQLite sink + UI
appsettings.json:
- Add Application:LogDirectory configuration
- Add Serilog WriteTo.SQLite sink (logs.db in LogDirectory)
- Logs table with UTC timestamps

Program.cs:
- Add Serilog.UI usings
- Configure Serilog.UI with SQLite provider
- Mount UI at /serilog-ui endpoint

Web-based log viewer accessible at: https://localhost:7186/serilog-ui
2026-07-21 14:39:32 +02:00
b37ccc8538 chore: Add Serilog.UI packages + versioning metadata
Packages:
- Serilog.Sinks.SQLite 7.0.0 (SQLite log persistence)
- Serilog.UI 3.2.0 (Web-based log viewer)
- Serilog.UI.SqliteProvider 1.1.0 (SQLite provider for Serilog.UI)

Versioning metadata:
- Version: 1.0.0
- Authors/Company: Digital Data GmbH
- Copyright: 2026
- Description: PDF document processing service using DevExpress
2026-07-21 14:39:24 +02:00
d0606f3605 feat(stamp): Add Application layer (AddStampCommand with handler/validator)
- Vertical slice: Command + Handler + Validator in single file
- Validation rules enforce StampType-specific required fields
- Text stamps: Text + FontName + FontSize required
- Image stamps: ImageBytes required
- Predefined stamps: PredefinedType required
- Supports Origin, Rotation, Opacity, Placement, Size parameters
2026-07-21 14:39:03 +02:00
c037ad8446 feat(stamp): Add IPdfProcessor.AddStampAsync interface
- Add AddStampAsync method signature to IPdfProcessor interface
- Parameters: pdfBytes, stampType, pages, position, text/image/predefined params
- Supports Origin (TopLeft/BottomLeft), Rotation, Opacity, Placement
2026-07-21 14:38:29 +02:00
e2bec710e0 feat(stamp): Add Domain value objects for stamp operations
- Add StampType enum (Text, Image, Predefined)
- Add PredefinedStampType enum (CONFIDENTIAL, APPROVED, DRAFT, etc.)
- Add StampPlacement enum (Foreground, Background)
- All enums in DocumentOperator.Domain namespace
2026-07-21 14:38:22 +02:00
61b11fc216 feat(annotation): Add Origin/Width/Height to API endpoints
- Update AddAnnotationFromFile/AddAnnotationFromBase64 endpoints
- Add Origin parameter to multipart/JSON request DTOs
- Add Width/Height as alternative to X2/Y2 in requests
- Calculate X2/Y2 from Width/Height if provided
- XML documentation updated with new parameters
2026-07-21 14:38:14 +02:00
c4ec0c2b48 feat(annotation): Implement coordinate system conversion in DevExpressPdfProcessor
- Add Y-axis conversion for TopLeft origin (bottomLeftY = pageHeight - topLeftY)
- Origin parameter support in AddAnnotationAsync
- Preserves existing BottomLeft behavior as default
2026-07-21 14:38:08 +02:00
eed9d46e19 feat(annotation): Add Origin/Width/Height parameters to AddAnnotationCommand
- Add Origin parameter (default: BottomLeft)
- Add Width/Height as alternatives to X2/Y2
- Validation: Either (X2+Y2) OR (Width+Height) required, not both
- FluentValidation rules enforce mutual exclusivity
2026-07-21 14:38:01 +02:00
c1bb3abeef feat(annotation): Add AnnotationOrigin value object
- Add AnnotationOrigin enum (BottomLeft/TopLeft)
- BottomLeft = PDF native coordinate system (default)
- TopLeft = UI-friendly coordinate system (requires Y-axis conversion)
- Shared with stamp operations for consistency
2026-07-21 14:37:54 +02:00
d72d41ec2d test(integration): Add 10 integration tests for annotation endpoints + update docs
Integration tests:
- 5 happy path tests (TextMarkup, FreeText, StickyNote, Circle, Square) with multipart + Base64 mix
- 5 validation error tests (invalid Base64, page number, missing content/style, invalid color)
- All existing 7 merge tests retained (now 17 total in PdfOperationsControllerTests)

Documentation updates (AGENTS.md):
- Update test count: 82 -> 101 passed, 7 skipped
- Update PdfOperationsController status: 1/N -> 2/3 endpoints (merge + annotate DONE, stamp TODO)
- Add test breakdown by feature (6 features listed)
- Update 'Run tests' section with Feature 6 mention

Test results: 101 PASSED, 7 SKIPPED, 0 FAILED
2026-07-21 12:28:59 +02:00