Compare commits
4 Commits
64be11f7ad
...
1b39ec502b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b39ec502b | ||
|
|
b1d48418cf | ||
|
|
10cfb0c838 | ||
|
|
d50e30f7ac |
406
DocumentOperator.API/PROJECT_STATUS.md
Normal file
406
DocumentOperator.API/PROJECT_STATUS.md
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
# DocumentOperator - Projekt Status & Zeitplan
|
||||||
|
|
||||||
|
> **Letzte Aktualisierung:** 17.01.2025
|
||||||
|
> **Aktueller Status:** Phase 3 - Infrastructure Layer (in Bearbeitung)
|
||||||
|
> **Gesamtfortschritt:** ~28% (2.75 von 11 Phasen abgeschlossen)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Projekt-Übersicht
|
||||||
|
|
||||||
|
**DocumentOperator** ist ein zentralisierter REST API Service für PDF-Dokumenten-Operationen in einer Multi-Tenant DMS-Umgebung.
|
||||||
|
|
||||||
|
### Kern-Features
|
||||||
|
- ? PDF Validierung (Metadaten-Extraktion)
|
||||||
|
- ? Attachment-Extraktion
|
||||||
|
- ? PDF-Konkatenation (asynchron bei großen Dateien)
|
||||||
|
- ? Stempel/Wasserzeichen (tenant-spezifisch)
|
||||||
|
- ? Zertifikat-Einbettung
|
||||||
|
|
||||||
|
### Technologie-Stack
|
||||||
|
- **.NET 8** (ASP.NET Core Minimal APIs)
|
||||||
|
- **Clean Architecture** (pragmatisch, nicht dogmatisch)
|
||||||
|
- **DevExpress PDF Core** (Universal License verfügbar)
|
||||||
|
- **MediatR** (CQRS Pattern)
|
||||||
|
- **EF Core + SQLite** (Tenant-Management)
|
||||||
|
- **Lokale Temp-Ordner** (File Storage mit IFileStorage Abstraction)
|
||||||
|
- **In-Memory Queue** (Async Processing)
|
||||||
|
- **Polly** (Resilience: Retry, Circuit Breaker)
|
||||||
|
- **Redis** (Caching, Rate-Limiting)
|
||||||
|
- **Serilog** (Structured Logging)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Phasen-Übersicht
|
||||||
|
|
||||||
|
| Phase | Name | Status | Fortschritt | Zeitaufwand |
|
||||||
|
|-------|------|--------|-------------|-------------|
|
||||||
|
| **1** | Foundation | ? Abgeschlossen | 100% | ~2 Tage |
|
||||||
|
| **2** | Domain Layer | ? Abgeschlossen | 100% | ~1 Tag |
|
||||||
|
| **3** | Infrastructure Layer | ?? In Bearbeitung | 75% | ~3-4 Tage |
|
||||||
|
| **4** | Application Layer | ? Ausstehend | 0% | ~2-3 Tage |
|
||||||
|
| **5** | API Layer | ? Ausstehend | 0% | ~2 Tage |
|
||||||
|
| **5.5** | Health Checks & Resilience | ? Ausstehend | 0% | ~1 Tag |
|
||||||
|
| **6** | Weitere Features (synchron) | ? Ausstehend | 0% | ~3-4 Tage |
|
||||||
|
| **6.5** | Async Processing (In-Memory Queue) | ? Ausstehend | 0% | ~2 Tage |
|
||||||
|
| **7** | Swagger & API Docs | ? Ausstehend | 0% | ~1 Tag |
|
||||||
|
| **8** | Multi-Tenancy (DB-based) | ? Ausstehend | 0% | ~3-4 Tage |
|
||||||
|
| **9** | File Storage (Lokale Temp-Ordner) | ? Ausstehend | 0% | ~1 Tag |
|
||||||
|
| **10** | Logging & Monitoring | ? Ausstehend | 0% | ~2 Tage |
|
||||||
|
| **11** | Production Deployment | ? Ausstehend | 0% | ~2-3 Tage |
|
||||||
|
|
||||||
|
**Gesamtaufwand (Schätzung):** ~24-30 Arbeitstage (5-6 Wochen bei 1 Entwickler)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Bereits erledigt (Phasen 1-2.5)
|
||||||
|
|
||||||
|
### Phase 1: Foundation ?
|
||||||
|
- [x] Solution-Struktur erstellt (4 Projekte: API, Application, Infrastructure, Domain)
|
||||||
|
- [x] Clean Architecture Dependencies korrekt (Dependency Rule eingehalten)
|
||||||
|
- [x] NuGet Packages installiert (MediatR, FluentValidation, DevExpress, xUnit, Moq, FluentAssertions)
|
||||||
|
- [x] Folder-Struktur nach Vertical Slice Architecture
|
||||||
|
- [x] Serilog Setup (Structured Logging)
|
||||||
|
- [x] appsettings.json Konfiguration
|
||||||
|
|
||||||
|
### Phase 2: Domain Layer ?
|
||||||
|
- [x] Domain Exceptions (4 Stück: DomainException, DomainValidationException, NotFoundException, PdfProcessingException)
|
||||||
|
- [x] Enums (DocumentOperationType, ProcessingStatus)
|
||||||
|
- [x] Value Objects (Base64String, TenantId, PdfMetadata) - selbst-validierend, immutable
|
||||||
|
|
||||||
|
### Phase 3: Infrastructure Layer (75% abgeschlossen) ??
|
||||||
|
- [x] IPdfProcessor Interface (Application/Common/Interfaces/)
|
||||||
|
- [x] Test-Struktur erstellt (Unit/Infrastructure/Services/PdfProcessing/)
|
||||||
|
- [x] Test-PDF Datei (valid.pdf als Embedded Resource)
|
||||||
|
- [x] DevExpressPdfProcessorTests.cs (TDD Red Phase - 6 Tests geschrieben)
|
||||||
|
- [x] **ABGESCHLOSSEN:** DevExpressPdfProcessor.cs implementiert (TDD Green Phase) - Package: DevExpress.Document.Processor 26.1.3
|
||||||
|
- [x] **ABGESCHLOSSEN:** Alle 6 Tests laufen erfolgreich (17.01.2025)
|
||||||
|
- [ ] **Ausstehend:** DependencyInjection.cs (Infrastructure/DependencyInjection.cs)
|
||||||
|
- [ ] **Ausstehend:** Polly Resilience Integration (Retry, Circuit Breaker, Timeout)
|
||||||
|
- [ ] **Ausstehend:** IFileStorage Interface + LocalFileStorage (Dev)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Aktuell in Bearbeitung (Phase 3)
|
||||||
|
|
||||||
|
### Step 3.2: DevExpressPdfProcessor implementieren (TDD) - ? ABGESCHLOSSEN
|
||||||
|
**Was wurde gemacht:**
|
||||||
|
- ? Tests geschrieben (Red Phase - 17.01.2025)
|
||||||
|
- ValidateAsync_ValidPdf_ReturnsMetadata
|
||||||
|
- ValidateAsync_InvalidPdf_ThrowsPdfProcessingException
|
||||||
|
- ValidateAsync_CorruptedPdf_ThrowsPdfProcessingException
|
||||||
|
- ValidateAsync_EmptyByteArray_ThrowsDomainValidationException
|
||||||
|
- ValidateAsync_NullByteArray_ThrowsDomainValidationException
|
||||||
|
- ValidateAsync_PdfWithAttachments_ReturnsCorrectAttachmentCount
|
||||||
|
- ? DevExpressPdfProcessor.cs implementiert (Green Phase - 17.01.2025)
|
||||||
|
- DevExpress PDF API Integration mit `PdfDocumentProcessor`
|
||||||
|
- Package: `DevExpress.Document.Processor` 26.1.3 (korrekt installiert)
|
||||||
|
- Exception Handling (PdfProcessingException, DomainValidationException)
|
||||||
|
- Metadaten extrahieren (Seitenzahl, Dateigröße, PDF-Version)
|
||||||
|
- Attachments als TODO für Phase 6 markiert (API nicht direkt verfügbar)
|
||||||
|
- ? Alle 6 Tests bestanden (17.01.2025)
|
||||||
|
|
||||||
|
**Erkenntnisse:**
|
||||||
|
- `DevExpress.Document.Processor` ist das korrekte Package (nicht `DevExpress.Pdf.Core`)
|
||||||
|
- `PdfDocumentProcessor` liegt in `DevExpress.Pdf` Namespace
|
||||||
|
- Attachments-Handling benötigt erweiterte API (Phase 6)
|
||||||
|
|
||||||
|
**Zeitaufwand:** ~2 Tage (abgeschlossen)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Nächste Schritte (Phase 4-5)
|
||||||
|
|
||||||
|
### Phase 4: Application Layer (~2-3 Tage)
|
||||||
|
**Priorität:** Hoch
|
||||||
|
**Abhängigkeiten:** Phase 3 muss abgeschlossen sein
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] MediatR Setup (DependencyInjection.cs, ValidationBehavior.cs, LoggingBehavior.cs)
|
||||||
|
- [ ] ValidatePdf Feature (Query, Handler, Validator)
|
||||||
|
- [ ] DTOs (ValidatePdfRequest, ValidatePdfResponse)
|
||||||
|
- [ ] Unit Tests für Handler
|
||||||
|
|
||||||
|
**Deliverable:** Erste komplette Feature-Implementierung (ValidatePdf)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 5: API Layer (~2 Tage)
|
||||||
|
**Priorität:** Hoch
|
||||||
|
**Abhängigkeiten:** Phase 4 muss abgeschlossen sein
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] Exception Handling Middleware (zentrale Exception ? HTTP Status Code Mapping)
|
||||||
|
- [ ] Minimal API Endpoint (POST /api/v1/documents/validate)
|
||||||
|
- [ ] Swagger Configuration (API-Key Header Support)
|
||||||
|
- [ ] Integration Test (End-to-End)
|
||||||
|
|
||||||
|
**Deliverable:** Funktionierender REST API Endpoint (testbar via Swagger)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Kritische Phasen (Production-Ready)
|
||||||
|
|
||||||
|
### Phase 5.5: Health Checks & Resilience (~1 Tag)
|
||||||
|
**Priorität:** Mittel (aber wichtig für Production!)
|
||||||
|
**Warum früh?** Load Balancer / Kubernetes brauchen Health Checks
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] DevExpressPdfHealthCheck (Smoke Test)
|
||||||
|
- [ ] /health Endpoint (Liveness/Readiness Probes)
|
||||||
|
- [ ] Polly Resilience (Retry, Circuit Breaker, Timeout für DevExpress Calls)
|
||||||
|
|
||||||
|
**Deliverable:** Production-ready Health Checks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 6.5: Async Processing (~2 Tage)
|
||||||
|
**Priorität:** Mittel
|
||||||
|
**Warum wichtig?** PDF-Konkatenation von 50 PDFs = 10+ Sekunden (HTTP Timeout!)
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] In-Memory Queue Setup (IJobQueue Interface)
|
||||||
|
- [ ] Background Worker (JobProcessorService - IHostedService)
|
||||||
|
- [ ] Async Endpoints (POST ? JobId, GET /jobs/{id} ? Status)
|
||||||
|
- [ ] Job Status Tracking (In-Memory Dictionary mit ConcurrentDictionary)
|
||||||
|
|
||||||
|
**Deliverable:** Queue-basiertes Async Processing (In-Memory, einfache Implementierung)
|
||||||
|
|
||||||
|
**Hinweis:** In-Memory Queue = nicht persistent (Server-Neustart löscht Jobs). Für Production mit Load Balancer später auf Redis Queue upgraden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 8: Multi-Tenancy (DB-based) (~3-4 Tage)
|
||||||
|
**Priorität:** Hoch (für Multi-Tenant DMS!)
|
||||||
|
**Warum DB-based?** Skalierbar, API-Key Rotation, Audit-Log
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] EF Core + SQLite Setup (Tenant-Datenbank)
|
||||||
|
- [ ] Tenant/TenantSettings Entities
|
||||||
|
- [ ] TenantRepository (ITenantRepository)
|
||||||
|
- [ ] TenantResolutionMiddleware (API-Key ? Tenant, Redis Cache)
|
||||||
|
- [ ] Tenant Admin API (CRUD für API-Keys)
|
||||||
|
- [ ] API-Key Hashing (BCrypt)
|
||||||
|
|
||||||
|
**Deliverable:** Multi-Tenant fähige API mit DB-basiertem Tenant-Management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 9: File Storage (Lokale Temp-Ordner) (~1 Tag)
|
||||||
|
**Priorität:** Mittel
|
||||||
|
**Warum wichtig?** Temporäre Dateien für verarbeitete PDFs (Download-Links)
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- [ ] IFileStorage Interface
|
||||||
|
- [ ] LocalFileStorage Implementation (appsettings: TempFolder-Pfad)
|
||||||
|
- [ ] TempFileCleanupService (IHostedService - täglich um 3 Uhr)
|
||||||
|
- [ ] Optionale Retention Policy (z.B. 24 Stunden)
|
||||||
|
|
||||||
|
**Deliverable:** Lokales File Storage mit automatischem Cleanup
|
||||||
|
|
||||||
|
**Hinweis:** Single-Server Setup (einfach). Für Multi-Server später auf Shared Network Drive (UNC-Pfad) upgraden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Risiken & Abhängigkeiten
|
||||||
|
|
||||||
|
### Technische Risiken
|
||||||
|
1. **DevExpress PDF API Stabilität**
|
||||||
|
- **Risiko:** Unbekannte Edge Cases (korrupte PDFs, spezielles PDF-Format)
|
||||||
|
- **Mitigation:** Polly Resilience (Retry, Circuit Breaker), umfangreiche Tests
|
||||||
|
- **Impact:** Mittel
|
||||||
|
|
||||||
|
2. **In-Memory Queue (nicht persistent)**
|
||||||
|
- **Risiko:** Server-Neustart löscht alle laufenden Jobs
|
||||||
|
- **Mitigation:** Single-Server Setup empfohlen, später Redis Queue für Production
|
||||||
|
- **Impact:** Niedrig (für MVP akzeptabel)
|
||||||
|
|
||||||
|
3. **Multi-Tenancy Komplexität**
|
||||||
|
- **Risiko:** Tenant-Isolation muss 100% korrekt sein (Security!)
|
||||||
|
- **Mitigation:** TDD, umfangreiche Integration Tests, Code Reviews
|
||||||
|
- **Impact:** Hoch (aber planbar)
|
||||||
|
|
||||||
|
### Externe Abhängigkeiten
|
||||||
|
- ? **DevExpress Universal License:** Verfügbar
|
||||||
|
- ? **Redis Server:** Optional für Phase 8 (Tenant-Caching), Phase 11 (Rate-Limiting)
|
||||||
|
- Alternative: In-Memory Cache für Single-Server Setup
|
||||||
|
- ? **Shared Network Drive:** Nur bei Multi-Server Setup (für File Storage)
|
||||||
|
- Alternative: Lokale Temp-Ordner für Single-Server
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Zeitplan & Milestones
|
||||||
|
|
||||||
|
### Milestone 1: MVP (Minimum Viable Product) ??
|
||||||
|
**Ziel:** Funktionierender API Endpoint (ValidatePdf)
|
||||||
|
**Phasen:** 1-5 abgeschlossen
|
||||||
|
**Zeitaufwand:** ~10-12 Arbeitstage
|
||||||
|
**ETA:** Ende KW 4 / Anfang KW 5 (bei 1 Entwickler)
|
||||||
|
|
||||||
|
**Deliverables:**
|
||||||
|
- ? REST API Endpoint: POST /api/v1/documents/validate
|
||||||
|
- ? Swagger UI (testbar)
|
||||||
|
- ? Exception Handling
|
||||||
|
- ? Unit Tests + Integration Tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Milestone 2: Production-Ready (Core Features) ??
|
||||||
|
**Ziel:** Production-ready API mit Health Checks, Resilience, Multi-Tenancy
|
||||||
|
**Phasen:** 1-5.5, 6 (nur ValidatePdf + ExtractAttachments), 7, 8 abgeschlossen
|
||||||
|
**Zeitaufwand:** ~20-25 Arbeitstage
|
||||||
|
**ETA:** Ende KW 7 / Anfang KW 8
|
||||||
|
|
||||||
|
**Deliverables:**
|
||||||
|
- ? Alle CRUD-Operationen (ValidatePdf, ExtractAttachments)
|
||||||
|
- ? Multi-Tenancy (DB-based, API-Key Management)
|
||||||
|
- ? Health Checks (/health Endpoint)
|
||||||
|
- ? Resilience (Polly)
|
||||||
|
- ? Swagger Documentation
|
||||||
|
- ? Production-ready Logging (Correlation IDs)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Milestone 3: Full Feature Set ??
|
||||||
|
**Ziel:** Alle Features + Async Processing + File Storage
|
||||||
|
**Phasen:** Alle 11 Phasen abgeschlossen
|
||||||
|
**Zeitaufwand:** ~24-30 Arbeitstage
|
||||||
|
**ETA:** Ende KW 8 / Anfang KW 9
|
||||||
|
|
||||||
|
**Deliverables:**
|
||||||
|
- ? Alle PDF-Operationen (ValidatePdf, ExtractAttachments, ConcatenatePdfs, ApplyStamp, EmbedCertificate)
|
||||||
|
- ? Async Processing (In-Memory Queue für große Operationen)
|
||||||
|
- ? Lokale Temp-Ordner (File Storage mit automatischem Cleanup)
|
||||||
|
- ? Logging & Monitoring (Seq, File Logging)
|
||||||
|
- ? IIS Deployment-ready
|
||||||
|
- ? Rate-Limiting (Redis-based)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Empfehlung für Projekt-Planung
|
||||||
|
|
||||||
|
### Option 1: Agile Iterationen (Empfohlen ?)
|
||||||
|
**Strategie:** 3 Milestones iterativ ausrollen
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- ? Frühes Feedback (MVP nach 2 Wochen testbar)
|
||||||
|
- ? Risiken früh erkannt (DevExpress Integration in Milestone 1)
|
||||||
|
- ? Flexibel (Anforderungen können sich ändern)
|
||||||
|
|
||||||
|
**Zeitplan:**
|
||||||
|
- **Sprint 1 (2 Wochen):** Milestone 1 (MVP) - Phase 1-5
|
||||||
|
- **Sprint 2 (3 Wochen):** Milestone 2 (Production-Ready) - Phase 5.5, 6, 7, 8
|
||||||
|
- **Sprint 3 (1-2 Wochen):** Milestone 3 (Full Feature Set) - Phase 6.5, 9, 10, 11
|
||||||
|
|
||||||
|
**Gesamtdauer:** ~6 Wochen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Option 2: Wasserfall (Nicht empfohlen ??)
|
||||||
|
**Strategie:** Alle Phasen komplett abarbeiten, dann erst testen
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- ? Spätes Feedback (erst nach 6 Wochen testbar)
|
||||||
|
- ? Risiken spät erkannt
|
||||||
|
- ? Keine Flexibilität
|
||||||
|
|
||||||
|
**Gesamtdauer:** ~6-7 Wochen (gleich, aber höheres Risiko)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Ressourcen-Bedarf
|
||||||
|
|
||||||
|
### Entwickler
|
||||||
|
- **Aktuell:** 1 Entwickler (außerhalb der Kernarbeitszeit)
|
||||||
|
- **Empfehlung:** 1 Entwickler ausreichend (bei agilen Sprints)
|
||||||
|
- **Alternative:** 2 Entwickler = Halbierung der Zeit (~3 Wochen statt 6)
|
||||||
|
|
||||||
|
### Infrastruktur (Production)
|
||||||
|
- **Lokaler File Server** (für Temp-Ordner) - ODER Shared Network Drive bei Multi-Server
|
||||||
|
- **Redis Server** (für Tenant-Caching, Rate-Limiting)
|
||||||
|
- **SQL Server** (optional, aktuell SQLite) - erst bei > 10.000 Requests/Sekunde
|
||||||
|
|
||||||
|
### Kosten-Schätzung
|
||||||
|
- **Redis Cache (Basic):** ~15 EUR/Monat (optional: In-Memory Cache für Single-Server)
|
||||||
|
- **Seq (Self-Hosted):** Kostenlos (oder Seq Cloud: ~20 EUR/Monat)
|
||||||
|
- **File Storage:** Kostenlos (lokale Festplatte)
|
||||||
|
|
||||||
|
**Gesamt:** ~0-35 EUR/Monat (abhängig von Redis + Seq Cloud)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ? Nächste Schritte (diese Woche)
|
||||||
|
|
||||||
|
### Priorität 1: Phase 3 abschließen
|
||||||
|
- [ ] DevExpressPdfProcessor.cs implementieren (TDD Green Phase)
|
||||||
|
- [ ] Alle Tests grün machen
|
||||||
|
- [ ] Code Review
|
||||||
|
|
||||||
|
**Zeitaufwand:** 1-2 Tage
|
||||||
|
**ETA:** Dienstag/Mittwoch
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Priorität 2: Phase 4 starten (Application Layer)
|
||||||
|
- [ ] MediatR Setup
|
||||||
|
- [ ] ValidatePdf Feature (Query, Handler, Validator)
|
||||||
|
|
||||||
|
**Zeitaufwand:** 2-3 Tage
|
||||||
|
**ETA:** Ende der Woche (Freitag)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Priorität 3: Milestone 1 erreichen (MVP)
|
||||||
|
- [ ] Phase 5 (API Layer)
|
||||||
|
- [ ] Erster testbarer Endpoint via Swagger
|
||||||
|
|
||||||
|
**Zeitaufwand:** 2 Tage
|
||||||
|
**ETA:** Anfang nächste Woche (Montag/Dienstag)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Fragen / Entscheidungen erforderlich
|
||||||
|
|
||||||
|
1. **Redis Server:**
|
||||||
|
Ist Redis-Instanz verfügbar? (Benötigt für Phase 8 - Tenant-Caching, Phase 11 - Rate-Limiting)
|
||||||
|
**Alternative:** In-Memory Cache für Dev, Redis erst für Production
|
||||||
|
|
||||||
|
2. **Deployment-Ziel:**
|
||||||
|
IIS? Docker/Kubernetes?
|
||||||
|
**Impact:** Beeinflusst Phase 11 (Production Deployment)
|
||||||
|
**Empfehlung:** IIS (Windows Server) - einfachste Lösung für .NET 8 APIs
|
||||||
|
|
||||||
|
3. **Priorität Async Processing (Phase 6.5):**
|
||||||
|
Ist In-Memory Queue-basiertes Async Processing Pflicht oder Nice-to-have?
|
||||||
|
**Impact:** Kann Zeit sparen (~2 Tage), wenn nicht benötigt
|
||||||
|
**Hinweis:** In-Memory Queue = nicht persistent (Server-Neustart löscht Jobs)
|
||||||
|
|
||||||
|
4. **Multi-Server Setup:**
|
||||||
|
Wird Load Balancer mit mehreren API-Instanzen benötigt?
|
||||||
|
**Impact:** Multi-Server = Shared Network Drive statt lokale Temp-Ordner notwendig
|
||||||
|
**Empfehlung:** Single-Server Setup vorerst (einfacher)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ?? Fazit & Empfehlung
|
||||||
|
|
||||||
|
**Projekt-Status:** ? Auf gutem Weg (25% abgeschlossen)
|
||||||
|
**Architektur:** ? Solide (Clean Architecture, TDD, Vertical Slices)
|
||||||
|
**Technologie-Stack:** ? Modern (.NET 8, Minimal APIs, Polly, EF Core) - **OHNE Azure-Abhängigkeiten**
|
||||||
|
**Risiken:** ?? Gering (mit Polly Resilience abgefedert)
|
||||||
|
|
||||||
|
**Empfehlung:**
|
||||||
|
1. ? **Phase 3 abschließen** (diese Woche)
|
||||||
|
2. ? **Milestone 1 (MVP) erreichen** (nächste Woche)
|
||||||
|
3. ? **Agile Iterationen** nutzen (3 Sprints à 2-3 Wochen)
|
||||||
|
4. ? **Frühes Feedback** einholen (nach Milestone 1)
|
||||||
|
|
||||||
|
**ETA für Production-Ready (Milestone 2):** Ende KW 7 / Anfang KW 8 (bei 1 Entwickler)
|
||||||
|
|
||||||
|
**Änderung (22.06.2026):** Azure Services (Blob Storage, Storage Queue) vollständig entfernt - stattdessen lokale Temp-Ordner + In-Memory Queue (einfacher, keine Cloud-Abhängigkeiten). Alle Azure-Referenzen in der Dokumentation bereinigt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Erstellt von:** DocumentOperator Entwicklungsteam
|
||||||
|
**Datum:** 22.06.2026
|
||||||
|
**Version:** 1.3 (Azure-Referenzen vollständig entfernt)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DevExpress.Pdf.Core" Version="25.2.8" />
|
<PackageReference Include="DevExpress.Document.Processor" Version="26.1.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
<Folder Include="DependencyInjection\" />
|
<Folder Include="DependencyInjection\" />
|
||||||
<Folder Include="Services\FileStorage\" />
|
<Folder Include="Services\FileStorage\" />
|
||||||
<Folder Include="Services\DocumentValidation\" />
|
<Folder Include="Services\DocumentValidation\" />
|
||||||
<Folder Include="Services\PdfProcessing\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using DevExpress.Pdf;
|
||||||
|
using DevExpress.Pdf;
|
||||||
|
using DocumentOperator.Application.Common.Interfaces;
|
||||||
|
using DocumentOperator.Domain.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace DocumentOperator.Infrastructure.Services.PdfProcessing;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PDF processor implementation using DevExpress.Pdf library.
|
||||||
|
/// Handles PDF validation and metadata extraction.
|
||||||
|
/// </summary>
|
||||||
|
public class DevExpressPdfProcessor : IPdfProcessor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Validates a PDF document and returns metadata.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pdfBytes">PDF content as byte array</param>
|
||||||
|
/// <returns>PDF metadata (page count, file size, version, etc.)</returns>
|
||||||
|
/// <exception cref="PdfProcessingException">Thrown when PDF is invalid or null</exception>
|
||||||
|
public async Task<DocumentOperator.Domain.Models.ValueObjects.PdfMetadata> ValidateAsync(byte[] pdfBytes)
|
||||||
|
{
|
||||||
|
// 1. Input Validation (Defensive Programming)
|
||||||
|
if (pdfBytes == null)
|
||||||
|
{
|
||||||
|
throw new PdfProcessingException("PDF bytes cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdfBytes.Length == 0)
|
||||||
|
{
|
||||||
|
throw new PdfProcessingException("PDF bytes cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 2. Load PDF with DevExpress Document API (PdfDocumentProcessor)
|
||||||
|
using var processor = new PdfDocumentProcessor();
|
||||||
|
processor.LoadDocument(new MemoryStream(pdfBytes));
|
||||||
|
|
||||||
|
// 3. Extract metadata
|
||||||
|
var document = processor.Document;
|
||||||
|
|
||||||
|
int pageCount = document.Pages.Count;
|
||||||
|
string pdfVersion = document.Version.ToString(); // z.B. "1.4", "1.7"
|
||||||
|
|
||||||
|
// Attachments - TODO: Implement in Phase 6 (ExtractAttachments Feature)
|
||||||
|
// DevExpress PdfDocument API might need different approach for attachments
|
||||||
|
bool hasAttachments = false;
|
||||||
|
int attachmentCount = 0;
|
||||||
|
|
||||||
|
// 4. Create and return PdfMetadata Value Object (fully qualified name!)
|
||||||
|
return new DocumentOperator.Domain.Models.ValueObjects.PdfMetadata(
|
||||||
|
pageCount: pageCount,
|
||||||
|
fileSizeBytes: pdfBytes.Length,
|
||||||
|
pdfVersion: pdfVersion,
|
||||||
|
hasAttachments: hasAttachments,
|
||||||
|
attachmentCount: attachmentCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is not PdfProcessingException)
|
||||||
|
{
|
||||||
|
// Wrap DevExpress exceptions in our domain exception
|
||||||
|
throw new PdfProcessingException(
|
||||||
|
$"Failed to validate PDF: {ex.Message}",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -120,7 +120,7 @@ public class DevExpressPdfProcessorTests
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await act.Should().ThrowAsync<PdfProcessingException>()
|
await act.Should().ThrowAsync<PdfProcessingException>()
|
||||||
.WithMessage("*invalid*", "corrupted PDF should throw exception");
|
.WithMessage("*valid pdf*", "corrupted PDF should throw exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user