docs: Update API specification based on Marvin/Marlon feedback
CONTROLLER_ENDPOINTS.md changes: - Binary stream output for all operations (NO outputPath, NO base64) - PDF Operations: merge, stamp, annotate → return application/pdf stream - PDF Conversion: to-pdfa, from-pdfa → return application/pdf stream - Attachment Extraction: extract → return application/zip stream - Add Attachment endpoint (Phase 2): embed files in PDF/PDF/A-3 - Swiss QR Code endpoint documented (already implemented) - PdfRenderController REMOVED (moved to .NET client library) AGENTS.md changes: - Current Status: SwissQrCodeController ✅ DONE (2 tests) - Current Status: PdfValidationController ✅ Partial (4 tests) - Phase reorganization: - Phase 1: validate, validate-pdfa, check, extract (SwissQR), extract (attachments), merge - Phase 2: stamp, annotate, add-attachment - Phase 3: to-pdfa, from-pdfa - Removed PdfRenderController from all phases Design decisions (team consensus): - Server endpoints stay granular (validate, check, extract separate) - Combined operations (validateANDextract) → .NET client library - Binary streams avoid filesystem dependencies - No base64 overhead (~33%), client library handles conversions Result: Clean API spec, memory-based operations, client convenience layer
This commit is contained in:
31
AGENTS.md
31
AGENTS.md
@@ -177,7 +177,7 @@ All files for a feature live together. Do NOT create separate Commands/, Handler
|
|||||||
- ✅ All features currently work without authentication
|
- ✅ All features currently work without authentication
|
||||||
|
|
||||||
**When to implement:**
|
**When to implement:**
|
||||||
After completing all Phase 1-3 controllers (PdfValidation, PdfAttachment, PdfOperations, PdfRender, PdfConversion), then add multi-tenancy to ALL endpoints in one refactoring phase.
|
After completing all Phase 1-3 controllers (PdfValidation, PdfAttachment, SwissQrCode, PdfOperations, PdfConversion), then add multi-tenancy to ALL endpoints in one refactoring phase.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -245,30 +245,41 @@ Do NOT add `if (result.IsSuccess)` checks. Throw exceptions for errors. The midd
|
|||||||
1. `PdfValidationController` – 2 endpoints
|
1. `PdfValidationController` – 2 endpoints
|
||||||
- `POST /api/pdf/validation/validate` (Basic PDF validation)
|
- `POST /api/pdf/validation/validate` (Basic PDF validation)
|
||||||
- `POST /api/pdf/validation/validate-pdfa` (PDF/A conformance)
|
- `POST /api/pdf/validation/validate-pdfa` (PDF/A conformance)
|
||||||
2. `PdfAttachmentController` – 2 endpoints
|
2. `PdfAttachmentController` – check endpoint
|
||||||
- `POST /api/pdf/attachments/check` (Attachment detection)
|
- `POST /api/pdf/attachments/check` (Attachment detection)
|
||||||
- `POST /api/pdf/attachments/extract` (Extract attachments)
|
3. `SwissQrCodeController` – extract endpoint
|
||||||
3. `PdfOperationsController` – Merge endpoint
|
- `POST /api/swissqrcode/extract` (Swiss QR Bill extraction)
|
||||||
|
4. `PdfAttachmentController` – extract endpoint
|
||||||
|
- `POST /api/pdf/attachments/extract` (Extract attachments as ZIP)
|
||||||
|
5. `PdfOperationsController` – merge endpoint
|
||||||
- `POST /api/pdf/operations/merge` (Merge multiple PDFs)
|
- `POST /api/pdf/operations/merge` (Merge multiple PDFs)
|
||||||
|
|
||||||
**Phase 2:**
|
**Phase 2:**
|
||||||
4. `PdfOperationsController` – Stamp & Annotate
|
6. `PdfOperationsController` – stamp & annotate
|
||||||
5. `PdfRenderController` – Preview
|
- `POST /api/pdf/operations/stamp` (Add stamps)
|
||||||
|
- `POST /api/pdf/operations/annotate` (Add annotations)
|
||||||
|
7. `PdfAttachmentController` – add attachment
|
||||||
|
- `POST /api/pdf/attachments/add` (Embed attachments in PDF/A-3)
|
||||||
|
|
||||||
**Phase 3:**
|
**Phase 3:**
|
||||||
6. `PdfConversionController` – PDF ↔ PDF/A conversion
|
8. `PdfConversionController` – PDF ↔ PDF/A conversion
|
||||||
|
- `POST /api/pdf/conversion/to-pdfa` (Convert to PDF/A)
|
||||||
|
- `POST /api/pdf/conversion/from-pdfa` (Convert from PDF/A)
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
- `PdfRenderController` – Moved to .NET client library (WinForms/WPF DevExpress controls)
|
||||||
|
|
||||||
### Current Status
|
### Current Status
|
||||||
|
|
||||||
| Controller | Status | Tests |
|
| Controller | Status | Tests |
|
||||||
|-----------|--------|-------|
|
|-----------|--------|-------|
|
||||||
| **PdfValidationController** | ⏳ Pending | 0 |
|
| **PdfValidationController** | ✅ Partial (validate done, validate-pdfa pending) | 4 |
|
||||||
|
| **SwissQrCodeController** | ✅ DONE | 2 |
|
||||||
| **PdfAttachmentController** | ⏳ Pending | 0 |
|
| **PdfAttachmentController** | ⏳ Pending | 0 |
|
||||||
| **PdfOperationsController** | ⏳ Pending | 0 |
|
| **PdfOperationsController** | ⏳ Pending | 0 |
|
||||||
| **PdfRenderController** | ⏳ Pending | 0 |
|
|
||||||
| **PdfConversionController** | ⏳ Pending | 0 |
|
| **PdfConversionController** | ⏳ Pending | 0 |
|
||||||
|
|
||||||
**Legacy code exists** (`DocumentEndpoints.cs` with Minimal API + Base64 JSON), but **must be replaced** with Controllers + multipart/form-data.
|
**Note:** PdfRenderController removed - moved to .NET client library.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -90,34 +90,37 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
|
|
||||||
### Endpoint: Attachment Extraction
|
### Endpoint: Attachment Extraction
|
||||||
**Route:** `POST /api/pdf/attachments/extract`
|
**Route:** `POST /api/pdf/attachments/extract`
|
||||||
**Function:** Extracts all embedded files from the PDF and saves them to the specified path
|
**Function:** Extracts all embedded files from the PDF and returns them as a ZIP archive
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF file (multipart/form-data)
|
||||||
{
|
|
||||||
"file": "PDF (multipart/form-data)",
|
|
||||||
"outputPath": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/zip)
|
||||||
{
|
- Content-Disposition: attachment; filename="attachments.zip"
|
||||||
"success": bool,
|
- ZIP archive containing all extracted files
|
||||||
"extractedFiles": [
|
|
||||||
{
|
|
||||||
"fileName": string,
|
|
||||||
"savedPath": string,
|
|
||||||
"size": long
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** eParser (ZUGFeRD XML extraction)
|
**Usage:** eParser (ZUGFeRD XML extraction)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Endpoint: Add Attachment
|
||||||
|
**Route:** `POST /api/pdf/attachments/add`
|
||||||
|
**Function:** Embeds one or more files as attachments in a PDF (supports PDF/A-3)
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
- PDF file (multipart/form-data)
|
||||||
|
- Attachment files (multipart/form-data, multiple)
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
- Binary stream (application/pdf)
|
||||||
|
- Content-Disposition: attachment; filename="with-attachments.pdf"
|
||||||
|
- PDF with embedded attachments
|
||||||
|
|
||||||
|
**Usage:** eParser (ZUGFeRD XML embedding), PDF/A-3 archiving
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## PdfOperationsController
|
## PdfOperationsController
|
||||||
|
|
||||||
### Endpoint: PDF Merge
|
### Endpoint: PDF Merge
|
||||||
@@ -125,22 +128,13 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
**Function:** Merges multiple PDFs into a single file
|
**Function:** Merges multiple PDFs into a single file
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- Multiple PDF files (multipart/form-data)
|
||||||
{
|
- Field name: "files" (array of IFormFile)
|
||||||
"sourceFiles": string[],
|
|
||||||
"outputPath": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/pdf)
|
||||||
{
|
- Content-Disposition: attachment; filename="merged.pdf"
|
||||||
"success": bool,
|
- Merged PDF document
|
||||||
"outputPath": string,
|
|
||||||
"pageCount": int,
|
|
||||||
"fileSize": long
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** signFLOW (Envelope Generator), ErgebnisberichtCreator, ResultHandler (windream)
|
**Usage:** signFLOW (Envelope Generator), ErgebnisberichtCreator, ResultHandler (windream)
|
||||||
|
|
||||||
@@ -151,26 +145,22 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
**Function:** Adds stamps to PDF pages (APPROVED, CONFIDENTIAL, etc.)
|
**Function:** Adds stamps to PDF pages (APPROVED, CONFIDENTIAL, etc.)
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF file (multipart/form-data)
|
||||||
{
|
- Stamp configuration (JSON):
|
||||||
"file": "PDF (multipart/form-data)",
|
```json
|
||||||
"stamp": {
|
{
|
||||||
"text": string,
|
"text": string,
|
||||||
"position": string,
|
"position": string,
|
||||||
"pages": string,
|
"pages": string,
|
||||||
"color": string,
|
"color": string,
|
||||||
"opacity": float
|
"opacity": float
|
||||||
}
|
}
|
||||||
}
|
```
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/pdf)
|
||||||
{
|
- Content-Disposition: attachment; filename="stamped.pdf"
|
||||||
"success": bool,
|
- PDF with applied stamps
|
||||||
"outputPath": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** ErgebnisberichtCreator
|
**Usage:** ErgebnisberichtCreator
|
||||||
|
|
||||||
@@ -181,63 +171,75 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
**Function:** Adds comments, highlights, and markings to the PDF
|
**Function:** Adds comments, highlights, and markings to the PDF
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF file (multipart/form-data)
|
||||||
{
|
- Annotations (JSON):
|
||||||
"file": "PDF (multipart/form-data)",
|
```json
|
||||||
"annotations": [
|
{
|
||||||
{
|
"annotations": [
|
||||||
"type": string,
|
{
|
||||||
"page": int,
|
"type": string,
|
||||||
"position": object,
|
"page": int,
|
||||||
"text": string
|
"position": object,
|
||||||
}
|
"text": string
|
||||||
]
|
}
|
||||||
}
|
]
|
||||||
```
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/pdf)
|
||||||
{
|
- Content-Disposition: attachment; filename="annotated.pdf"
|
||||||
"success": bool,
|
- PDF with applied annotations
|
||||||
"outputPath": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** signFLOW (Envelope Generator)
|
**Usage:** signFLOW (Envelope Generator)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## PdfRenderController
|
## SwissQrCodeController
|
||||||
|
|
||||||
### Endpoint: PDF Preview
|
### Endpoint: Swiss QR Code Extraction
|
||||||
**Route:** `POST /api/pdf/render/preview`
|
**Route:** `POST /api/swissqrcode/extract`
|
||||||
**Function:** Renders PDF pages as PNG/JPEG for preview
|
**Function:** Extracts and parses Swiss QR Bill (Swiss QR Code) from PDF
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF file (multipart/form-data)
|
||||||
{
|
|
||||||
"file": "PDF (multipart/form-data)",
|
|
||||||
"page": int,
|
|
||||||
"format": string,
|
|
||||||
"dpi": int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"images": [
|
"qrType": "SwissQrBill",
|
||||||
{
|
"version": "0200",
|
||||||
"page": int,
|
"creditorIban": "CH4431999123000889012",
|
||||||
"base64": string,
|
"creditorName": "Example AG",
|
||||||
"width": int,
|
"creditorAddress": {
|
||||||
"height": int
|
"addressType": "Structured",
|
||||||
}
|
"street": "Musterstrasse",
|
||||||
]
|
"houseNumber": "1",
|
||||||
|
"postalCode": "8000",
|
||||||
|
"city": "Zürich",
|
||||||
|
"country": "CH"
|
||||||
|
},
|
||||||
|
"amount": 1234.56,
|
||||||
|
"currency": "CHF",
|
||||||
|
"debtorName": "Max Mustermann",
|
||||||
|
"debtorAddress": { ... },
|
||||||
|
"referenceType": "QRR",
|
||||||
|
"reference": "210000000003139471430009017",
|
||||||
|
"unstructuredMessage": "Invoice #12345",
|
||||||
|
"billInformation": "//S1/10/12345",
|
||||||
|
"alternativeProcedures": ["UV1", "UV2"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Usage:** taskFLOW, fileFLOW, easyFLOW, orgFLOW - PDF preview
|
**Usage:** eParser (Swiss QR Bill processing), signFLOW (payment reference extraction)
|
||||||
|
|
||||||
|
**Note:** Supports only Structured Address (S-Type) as per Swiss QR Bill Standard 2.0. Combined Address (K-Type) deprecated November 21, 2025.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PdfRenderController
|
||||||
|
|
||||||
|
**Status:** REMOVED - PDF preview functionality will be implemented in .NET client library using DevExpress WinForms/WPF controls. Server-side rendering is unnecessary CPU/memory overhead.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -248,21 +250,13 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
**Function:** Converts a standard PDF to PDF/A
|
**Function:** Converts a standard PDF to PDF/A
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF file (multipart/form-data)
|
||||||
{
|
- PDF/A level (query parameter): "PDF/A-1b", "PDF/A-2b", "PDF/A-3b"
|
||||||
"file": "PDF (multipart/form-data)",
|
|
||||||
"pdfaLevel": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/pdf)
|
||||||
{
|
- Content-Disposition: attachment; filename="converted-pdfa.pdf"
|
||||||
"success": bool,
|
- PDF/A compliant document
|
||||||
"outputPath": string,
|
|
||||||
"pdfaVersion": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** taskFLOW (optional conversion)
|
**Usage:** taskFLOW (optional conversion)
|
||||||
|
|
||||||
@@ -273,19 +267,12 @@ This specification defines the controller structure and REST API endpoints for t
|
|||||||
**Function:** Converts PDF/A to a standard PDF
|
**Function:** Converts PDF/A to a standard PDF
|
||||||
|
|
||||||
**Input:**
|
**Input:**
|
||||||
```json
|
- PDF/A file (multipart/form-data)
|
||||||
{
|
|
||||||
"file": "PDF (multipart/form-data)"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output:**
|
**Output:**
|
||||||
```json
|
- Binary stream (application/pdf)
|
||||||
{
|
- Content-Disposition: attachment; filename="converted-pdf.pdf"
|
||||||
"success": bool,
|
- Standard PDF document
|
||||||
"outputPath": string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage:** taskFLOW (optional conversion)
|
**Usage:** taskFLOW (optional conversion)
|
||||||
|
|
||||||
@@ -312,9 +299,21 @@ if (result.IsValid) { ... }
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Response Format
|
### Response Format
|
||||||
- Default: JSON
|
- Default: JSON (for metadata endpoints like validation, check)
|
||||||
|
- Binary streams: application/pdf, application/zip (for operations, conversion, extraction)
|
||||||
|
- Content-Disposition header: attachment; filename="<output-filename>"
|
||||||
- Errors: HTTP Status Codes (400, 404, 500) + JSON error object
|
- Errors: HTTP Status Codes (400, 404, 500) + JSON error object
|
||||||
- Success: HTTP 200 + JSON response
|
- Success: HTTP 200 + JSON/Binary response
|
||||||
|
|
||||||
|
**Binary Stream Endpoints:**
|
||||||
|
- PDF Operations: merge, stamp, annotate
|
||||||
|
- PDF Conversion: to-pdfa, from-pdfa
|
||||||
|
- Attachment Operations: extract (ZIP), add (PDF)
|
||||||
|
|
||||||
|
**JSON Response Endpoints:**
|
||||||
|
- PDF Validation: validate, validate-pdfa
|
||||||
|
- Attachment Check: check
|
||||||
|
- Swiss QR Code: extract
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
- API Key (Header: `X-API-Key`)
|
- API Key (Header: `X-API-Key`)
|
||||||
@@ -330,16 +329,21 @@ if (result.IsValid) { ... }
|
|||||||
## Prioritization
|
## Prioritization
|
||||||
|
|
||||||
### Phase 1 (Priority)
|
### Phase 1 (Priority)
|
||||||
1. PdfValidationController - both endpoints
|
1. PdfValidationController - both endpoints (validate, validate-pdfa)
|
||||||
2. PdfAttachmentController - both endpoints
|
2. PdfAttachmentController - check endpoint
|
||||||
3. PdfOperationsController - Merge endpoint
|
3. SwissQrCodeController - extract endpoint (already implemented)
|
||||||
|
4. PdfAttachmentController - extract endpoint
|
||||||
|
5. PdfOperationsController - merge endpoint
|
||||||
|
|
||||||
### Phase 2
|
### Phase 2
|
||||||
4. PdfOperationsController - Stamp & Annotate
|
6. PdfOperationsController - stamp & annotate endpoints
|
||||||
5. PdfRenderController - Preview
|
7. PdfAttachmentController - add attachment endpoint
|
||||||
|
|
||||||
### Phase 3
|
### Phase 3
|
||||||
6. PdfConversionController - both endpoints
|
8. PdfConversionController - both endpoints (to-pdfa, from-pdfa)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- PdfRenderController - moved to .NET client library (WinForms/WPF DevExpress controls)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user