# Architektur-Übersicht: Domain & Application Dieses Dokument beschreibt die fachliche und anwendungsnahe Schicht des PDF-Umbenenners: das Modul `pdf-umbenenner-domain` und das Modul `pdf-umbenenner-application`. Es richtet sich an Entwickler, die in diesen beiden Modulen arbeiten, und soll als alleiniger Architekturkontext ausreichen – ergänzt durch die `CLAUDE.md` im Projektroot. Nicht enthalten sind Adapter-Implementierungen (Dateisystem, PDFBox, SQLite, HTTP-Clients); diese sind in `adapter-overview.md` beschrieben. GUI-spezifische Ports und deren Einbettung in den Konfigurationseditor sind in `gui-overview.md` dokumentiert. --- ## 1. Modulzweck ### `pdf-umbenenner-domain` Enthält ausschließlich fachliche Kerntypen (Records, Enums, Sealed Interfaces) ohne jegliche Infrastrukturabhängigkeiten. Alle Typen modellieren den Problembereich und sind von anderen Modulen referenzierbar, ohne transitive Abhängigkeiten einzuschleppen. ### `pdf-umbenenner-application` Definiert Use-Case-Orchestrierung sowie alle Inbound- und Outbound-Ports der hexagonalen Architektur. Enthält anwendungsnahe Dienste (KI-Antwort-Parsing, Pre-Check-Auswertung, Retry-Entscheidung) und Konfigurationsmodelle, aber keinerlei Infrastrukturcode (kein JDBC, kein PDFBox, kein HTTP-Client, kein JavaFX). --- ## 2. Paketstruktur ### `pdf-umbenenner-domain` | Paket | Verantwortung | |-------|---------------| | `de.gecheckt.pdf.umbenenner.domain` | Wurzelpaket; enthält nur `package-info.java` | | `de.gecheckt.pdf.umbenenner.domain.model` | Alle fachlichen Kerntypen: Records, Sealed Interfaces und Enums, die die Verarbeitungsdomäne beschreiben | ### `pdf-umbenenner-application` | Paket | Verantwortung | |-------|---------------| | `de.gecheckt.pdf.umbenenner.application` | Wurzelpaket des Application-Moduls | | `de.gecheckt.pdf.umbenenner.application.port.in` | Inbound-Ports (Use-Case-Interfaces) – Einstiegspunkte für den Aufrufer | | `de.gecheckt.pdf.umbenenner.application.port.out` | Outbound-Ports – Verträge gegenüber Infrastruktur-Adaptern (Persistenz, Dateisystem, KI, Uhr, Logging) | | `de.gecheckt.pdf.umbenenner.application.port.out.modelcatalog` | Spezialisierter Outbound-Port für den Abruf verfügbarer KI-Modelle; ausschließlich im GUI-Pfad genutzt (siehe `gui-overview.md`) | | `de.gecheckt.pdf.umbenenner.application.service` | Anwendungsnahe, zustandslose Dienste: KI-Antwort-Parsing, Pre-Check-Auswertung, Verarbeitungs-Pipeline, Retry-Entscheidung | | `de.gecheckt.pdf.umbenenner.application.config` | Konfigurationsmodelle der Anwendungsschicht (`RuntimeConfiguration`, Provider-Konfiguration) | | `de.gecheckt.pdf.umbenenner.application.config.startup` | Vollständiges Startup-Konfigurationsmodell (`StartConfiguration`) | | `de.gecheckt.pdf.umbenenner.application.config.provider` | Modelle für KI-Provider-Konfiguration (Provider-Familie, Einzelkonfiguration, Multi-Provider) | | `de.gecheckt.pdf.umbenenner.application.validation.editor` | Validierungslogik für den GUI-Konfigurationseditor (Findings, Report, API-Key-Auflösung); siehe `gui-overview.md` | | `de.gecheckt.pdf.umbenenner.application.validation.technicaltest` | Technischer Selbsttest: Pfad-Checks, Korrekturpläne, Checkpoints; Details in `gui-overview.md` | | `de.gecheckt.pdf.umbenenner.application.usecase` | Paket-Marker für Use-Case-Implementierungen | --- ## 3. Schlüsselklassen ### Domain-Modul **`de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentCandidate`** Record für einen PDF-Kandidaten aus dem Quellordner. Enthält keinen `Path`, sondern einen opaken `SourceDocumentLocator`, damit die Domain frei von NIO-Typen bleibt. **`de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint`** Record mit einem SHA-256-Hex-String (64 Zeichen) als stabiler Dokumentidentität; Grundlage für Idempotenz und Persistenz-Lookup. **`de.gecheckt.pdf.umbenenner.domain.model.DocumentProcessingOutcome`** Sealed Interface mit sechs Implementierungen, die alle möglichen Ausgänge der Dokumentverarbeitung exhaustiv abbilden: | Implementierung | Bedeutung | |-----------------|-----------| | `PreCheckPassed` | Vorprüfung bestanden, KI-Pfad freigegeben | | `PreCheckFailed` | Deterministischer Inhaltsfehler vor KI-Aufruf | | `TechnicalDocumentError` | Technischer Fehler ohne erneuten KI-Aufruf | | `NamingProposalReady` | KI-Antwort gültig, Vorschlag liegt vor | | `AiTechnicalFailure` | Transienter technischer Fehler beim KI-Aufruf | | `AiFunctionalFailure` | Deterministischer fachlicher Fehler der KI-Antwort | **`de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus`** Enum mit acht Zuständen. Dokumentiert Zustandsübergänge und Retry-Schwellen; fachliches Herzstück der Persistenz-Semantik. | Status | Bedeutung | |--------|-----------| | `READY_FOR_AI` | Verarbeitbar, KI-Pfad noch nicht durchlaufen | | `FAILED_RETRYABLE` | Verarbeitbar, transient fehlgeschlagen | | `PROPOSAL_READY` | Eingangszustand für Dateinamensbildung und Zielkopie | | `SUCCESS` | Terminaler Enderfolg – nur nach Zielkopie und konsistenter Persistenz | | `FAILED_FINAL` | Terminal, wird nicht erneut fachlich verarbeitet | | `SKIPPED_ALREADY_PROCESSED` | Historisierter Skip für `SUCCESS`-Dokumente | | `SKIPPED_FINAL_FAILURE` | Historisierter Skip für `FAILED_FINAL`-Dokumente | **`de.gecheckt.pdf.umbenenner.domain.model.NamingProposal`** Record mit aufgelöstem Datum, `DateSource`, validiertem Titel und KI-Begründung. Führende Quelle für die Zieldateinamensbildung. **`de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext`** Klasse mit Run-ID, Zeitstempel und optionalem Fingerabdruck-Filter; steuert den Umfang eines Batch-Laufs. --- ### Application-Modul **`de.gecheckt.pdf.umbenenner.application.config.RuntimeConfiguration`** Schmales Laufzeit-Record (`maxPages`, `maxRetriesTransient`, `aiContentSensitivity`). Wird von den Use Cases verwendet, enthält keine Pfade. **`de.gecheckt.pdf.umbenenner.application.config.startup.StartConfiguration`** Vollständige typisierte Startup-Konfiguration; einziger Ort in der Anwendungsschicht, an dem `java.nio.file.Path` vorkommt. Wird vom `ConfigurationPort` geliefert und von Bootstrap ausgewertet. **`de.gecheckt.pdf.umbenenner.application.service.DocumentProcessingService`** Statische Hilfsklasse: überführt ein Extraktionsergebnis über den Pre-Check in ein `DocumentProcessingOutcome`. Kompakte Pipeline-Klasse; guter Einstieg zum Verständnis der Verarbeitungslogik. **`de.gecheckt.pdf.umbenenner.application.service.AiResponseParser`** Statischer Parser für KI-Antworten in `ParsedAiResponse`. Erzwingt reines JSON-Objekt; Validierungslogik liegt vollständig in der Anwendungsschicht. **`de.gecheckt.pdf.umbenenner.application.port.out.ProcessingAttempt`** Record für einen Versuchshistorie-Eintrag; enthält u. a. Provider-Identifikator, Modellname, Prompt-Identifikator, aufgelöstes Datum und finalen Zieldateinamen. **`de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecord`** Record für den Dokument-Stammsatz; enthält Gesamtstatus, Fehler- und Transientzähler sowie letzten Zielpfad. --- ## 4. Inbound Ports ### `BatchRunProcessingUseCase` ``` de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProcessingUseCase ``` Zentraler Use-Case-Einstiegspunkt für den gesamten Batch-Betrieb. Beschreibt den Anwendungszweck in einer einzigen Methode: ```java BatchRunOutcome execute(BatchRunContext context); ``` Mögliche Ergebnisse: | Ergebnis | Bedeutung | |----------|-----------| | `SUCCESS` | Lauf technisch ordnungsgemäß abgeschlossen | | `LOCK_UNAVAILABLE` | Run-Lock konnte nicht erworben werden | | `FAILURE` | Harter technischer Fehler beim Laufstart | --- ## 5. Outbound Ports Alle Outbound-Ports liegen in `de.gecheckt.pdf.umbenenner.application.port.out` (bzw. dessen Unterpaket `modelcatalog`). Implementierungen befinden sich ausschließlich in `pdf-umbenenner-adapter-out`; Details dort sind in `adapter-overview.md` beschrieben. | Interface | Zweck | Hauptmethode(n) | |-----------|-------|-----------------| | `SourceDocumentCandidatesPort` | Scannt Quellordner, liefert Kandidaten in deterministischer Reihenfolge | `List loadCandidates()` | | `FingerprintPort` | Berechnet SHA-256-Fingerabdruck eines Kandidaten | `FingerprintResult computeFingerprint(SourceDocumentCandidate)` | | `PdfTextExtractionPort` | Extrahiert Text und Seitenanzahl aus einer PDF | `PdfExtractionResult extractTextAndPageCount(...)` | | `AiInvocationPort` | Ruft den aktiven KI-Dienst auf; provider-neutral | `AiInvocationResult invoke(AiRequestRepresentation)` | | `PromptPort` | Lädt das Prompt-Template aus der konfigurierten Quelle | `PromptLoadingResult loadPrompt()` | | `TargetFileCopyPort` | Kopiert Quelldokument unter aufgelöstem Namen in den Zielordner (Temp + Rename) | `TargetFileCopyResult copyToTarget(...)` | | `TargetFileRenamePort` | Atomare Umbenennung einer bereits kopierten Zieldatei (manuelle Korrektur) | `TargetFileRenameResult rename(...)` | | `RunLockPort` | Exklusiver Lauf-Lock gegen parallele Instanzen | `acquire()` / `release()` | | `PersistenceSchemaInitializationPort` | Idempotente Schema-Initialisierung der SQLite-Datenbank | `initializeSchema()` | | `ClockPort` | Abstraktion des Systemtakts | `Instant now()` | | `ConfigurationPort` | Lädt die typisierte Startup-Konfiguration | `StartConfiguration loadConfiguration()` | | `ProcessingLogger` | Logging-Delegation; sensibles KI-Content-Logging über Flag gesteuert | `info/debug/warn/error/debugSensitiveAiContent(...)` | | `AiModelCatalogPort` | Abruf verfügbarer Modelle vom Provider (nur GUI-Pfad, siehe `gui-overview.md`) | `ModelCatalogResult fetchAvailableModels(...)` | | `PathCheckPort` | Lesende Pfad-Prüfung für den technischen Selbsttest | `isDirectoryReadable`, `isDirectoryWritableOrCreatable`, `isFileReadable`, `isSqlitePathUsable` | | `ResourceCreationPort` | Schreibende Korrektur-Aktionen (Ordner anlegen, Prompt-Datei erzeugen, SQLite-Pfad vorbereiten) | `createDirectory`, `createPromptFile`, `prepareSqlitePath` | | `ApiKeyResolutionPort` | Ermittelt API-Key-Herkunft pro Provider-Familie für die GUI-Validierung | `EffectiveApiKeyDescriptor resolve(...)` | > **Hinweis zu GUI-spezifischen Ports:** `AiModelCatalogPort`, `PathCheckPort`, `ResourceCreationPort` und `ApiKeyResolutionPort` werden ausschließlich im GUI-Pfad genutzt. Ihre Implementierungen und der Aufrufkontext sind in `gui-overview.md` beschrieben. --- ## 6. Einstiegspunkte für neue Entwickler Die folgende Lesereihenfolge gibt den kürzesten Weg zum Gesamtverständnis: 1. **`de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProcessingUseCase`** – beschreibt den gesamten Anwendungszweck in einer Methode. 2. **`de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus`** – fachliches Herzstück; dokumentiert Zustandsübergänge und Retry-Schwellen. 3. **`de.gecheckt.pdf.umbenenner.domain.model`** (gesamtes Paket) – gemeinsame Sprache aller Schichten; vollständig in wenigen Minuten lesbar. 4. **`de.gecheckt.pdf.umbenenner.application.service.DocumentProcessingService`** – kompakte Pipeline-Klasse; zeigt, wie Pre-Check und Ergebnis-Typen zusammenspielen. 5. **`de.gecheckt.pdf.umbenenner.application.port.out`** (gesamtes Paket) – vollständige Außengrenzen der Architektur; jeder Infrastrukturzugriff ist hier als Port definiert.