# Technik und Architektur – PDF-Umbenenner mit KI ## 1. Ziel und Geltungsbereich Dieses Dokument beschreibt die verbindliche technische Zielarchitektur für den **PDF-Umbenenner**. Die Anwendung ist ein **lokal gestartetes Java-Programm** zur KI-gestützten Umbenennung bereits OCR-verarbeiteter, durchsuchbarer PDF-Dateien. Sie liest PDF-Dateien aus einem konfigurierbaren Quellordner, ermittelt auf Basis des extrahierten Inhalts einen normierten Dateinamen und legt **eine Kopie** der Datei im konfigurierbaren Zielordner ab. Die Quelldatei bleibt unverändert. Dieses Dokument beschreibt ausschließlich: - technische Architektur - technische Regeln und Schnittstellen - Persistenz- und Betriebsmodell - technische Konkretisierung fachlicher Vorgaben Nicht Bestandteil dieses Dokuments sind: - Meilensteine - Projektplanung - manuelle Bedienkonzepte --- ## 2. Verbindliches Zielbild ### 2.1 Betriebsmodell Die Anwendung ist verbindlich: - **Java 21** - **Maven** - **ausführbares Standalone-JAR** - **Start über Windows Task Scheduler** - **kein Webserver** - **kein Applikationsserver** - **keine Dauerlauf-Anwendung** - **kein interner Scheduler** ### 2.2 Verbindlicher Verarbeitungsausgang Bei erfolgreicher Verarbeitung entsteht im Zielordner eine neue Datei im Format: ```text YYYY-MM-DD - Titel.pdf ``` Bei Namenskollisionen wird am Ende des Titels und direkt vor `.pdf` ein laufendes Suffix angehängt: ```text YYYY-MM-DD - Titel(1).pdf YYYY-MM-DD - Titel(2).pdf ``` Dabei gilt: - die **20 Zeichen** beziehen sich nur auf den **Basistitel** - das Dubletten-Suffix zählt **nicht** zu diesen 20 Zeichen - die Quelldatei wird **nie** überschrieben oder verändert --- ## 3. Architekturprinzipien ### 3.1 Strenge hexagonale Architektur Die Anwendung wird strikt nach **Ports and Adapters / Hexagonal Architecture** umgesetzt. Verbindliche Regeln: - Der **Domain-Kern** kennt keine Infrastruktur, keine Datenbank, kein Dateisystem und keine HTTP-Kommunikation. - Die **Application-Schicht** orchestriert Anwendungsfälle und enthält keine technischen Implementierungsdetails. - Jeder externe Zugriff erfolgt ausschließlich über **Ports**. - Konkrete technische Implementierungen sind **Adapter**. - Adapter dürfen nicht direkt voneinander abhängen. - Die Abhängigkeitsrichtung zeigt immer **nach innen**. ### 3.2 Technische Folgen Es darf keine Vermischung geben zwischen: - Dateisystemzugriff - PDF-Auslese - SQLite-Persistenz - KI-HTTP-Kommunikation - Konfigurationsladen - Logging-Konfiguration - Benennungslogik - Retry-Entscheidungen --- ## 4. Maven- und Modulstruktur ### 4.1 Zielstruktur Die Zielstruktur ist ein **Maven-Multi-Module-Projekt** mit mindestens folgenden Modulen: - `pdf-umbenenner-domain` - `pdf-umbenenner-application` - `pdf-umbenenner-adapter-in-cli` - `pdf-umbenenner-adapter-out` - `pdf-umbenenner-bootstrap` Diese Struktur ist für das Projekt zweckmäßig, weil sie einerseits die Hexagonal-Architektur sauber abbildet und andererseits für eine kleine Batch-Anwendung noch überschaubar bleibt. ### 4.2 Modulverantwortung #### Domain Enthält ausschließlich fachliche und fachnah-technische Kernobjekte, zum Beispiel: - `DocumentFingerprint` - `DocumentText` - `NamingProposal` - `ResolvedDate` - `ProcessingStatus` - `RetryDecision` - `FileNamingRules` **Nicht** in die Domain gehören: - Persistenzmodelle - SQLite-Entities - HTTP-DTOs - Log4j2-spezifische Klassen - Dateisystem-Klassen #### Application Enthält Use Cases und Orchestrierung, zum Beispiel: - `RunBatchProcessingUseCase` - `ProcessSingleDocumentUseCase` - `GenerateFileNameUseCase` - `RecordProcessingAttemptUseCase` - `DetermineRetryDecisionUseCase` #### Adapter In Enthält den Batch-/CLI-Einstiegspunkt. Beispiel: - `SchedulerBatchCommand` #### Adapter Out Enthält technische Implementierungen der Outbound-Ports, insbesondere: - Dateisystem - PDFBox - SQLite - OpenAI-kompatibler HTTP-Client - Properties-/Umgebungs-Konfiguration - Run-Lock - Clock #### Bootstrap Verantwortlich für: - Laden und Validieren der Konfiguration - Erzeugen des Objektgraphen - Verdrahtung aller Adapter und Ports - Start des CLI-Adapters - Setzen des Exit-Codes ### 4.3 Maven-Basis Zweckmäßige Maven-Grundlage: - Parent-POM mit `packaging=pom` - `maven-compiler-plugin` mit `release=21` - `maven-surefire-plugin` für Unit-Tests - `maven-enforcer-plugin` für Java-/Maven-Minimalversionen - `maven-shade-plugin` im Bootstrap-Modul zur Erzeugung des ausführbaren JARs --- ## 5. Technologiestack Verbindlich eingesetzt werden: - **Java 21** - **Maven** - **Apache PDFBox** für PDF-Textauslese - **SQLite** als lokaler Persistenzspeicher - **SQLite JDBC-Treiber** - **Log4j2** für Logging - **OpenAI-kompatible HTTP-API** für KI-Zugriff - **Java HTTP Client** oder technisch gleichwertige Standard-HTTP-Komponente - **JSON-Bibliothek** für robuste JSON-Serialisierung und -Validierung Nicht verbindlich festgelegt sind: - konkreter KI-Provider - konkrete KI-Basis-URL - konkreter Modellname Diese drei Punkte sind **reine Konfiguration** und ausdrücklich **keine Architekturentscheidung**. --- ## 6. Ports ### 6.1 Inbound-Port Mindestens ein Inbound-Port ist verbindlich: - `RunBatchProcessingUseCase` Optional kann die Application feiner geschnitten werden, zum Beispiel mit: - `ProcessPendingDocumentsUseCase` - `ProcessSingleDocumentUseCase` ### 6.2 Outbound-Ports Verbindlich zweckmäßige Outbound-Ports: - `SourceDocumentPort` - `PdfTextExtractionPort` - `FingerprintPort` - `ProcessedDocumentRepository` - `AiNamingPort` - `ConfigurationPort` - `RunLockPort` - `ClockPort` ### 6.3 Logging Logging ist **kein fachlicher Port**. Logging ist technische Infrastruktur. --- ## 7. Verarbeitungsmodell ### 7.1 Batch-Ablauf Ein Lauf erfolgt in dieser Reihenfolge: 1. Konfiguration laden 2. Konfiguration validieren 3. Run-Lock erwerben 4. Quellordner lesen 5. PDF-Dateien ermitteln 6. Jede Datei einzeln verarbeiten 7. Run-Lock freigeben 8. Exit-Code setzen ### 7.2 Ablauf pro Datei Die Verarbeitung einer einzelnen Datei erfolgt in dieser Reihenfolge: 1. Fingerprint der Quelldatei berechnen 2. Repository prüfen 3. Erfolgreich verarbeitete Datei überspringen 4. Final fehlgeschlagene Datei überspringen 5. PDF-Text extrahieren 6. Textqualität prüfen 7. Seitenlimit prüfen 8. Text für KI-Aufruf begrenzen und vorbereiten 9. KI aufrufen 10. KI-Antwort validieren 11. Datum auflösen 12. Titel validieren und technisch bereinigen 13. finalen Dateinamen erzeugen 14. Dubletten-Suffix bestimmen 15. Datei in temporäre Zieldatei kopieren 16. temporäre Zieldatei final verschieben/umbenennen 17. Erfolg und Versuchshistorie persistent speichern ### 7.3 Erfolgskriterium Ein Dokument gilt genau dann als erfolgreich verarbeitet, wenn: 1. brauchbarer PDF-Text vorliegt, 2. ein fachlich brauchbarer Titel vorliegt, 3. ein Datum aufgelöst wurde, 4. ein zulässiger Zielname erzeugt wurde, 5. die Zielkopie erfolgreich geschrieben wurde, 6. Status und Versuchshistorie erfolgreich persistiert wurden. --- ## 8. Dateinamensregeln ### 8.1 Zielformat Das verbindliche Zielformat lautet: ```text YYYY-MM-DD - Titel.pdf ``` ### 8.2 Datum Die technische Auflösung folgt fachlich dieser Priorität: 1. Rechnungsdatum 2. Dokumentdatum 3. anderes sinnvolles Dokumentdatum 4. aktuelles Datum als Fallback ### 8.3 Technische Datumsregel Die Anwendung setzt den Fallback auf das **aktuelle Datum** selbst, falls aus dem Dokument **kein belastbares Datum** ableitbar ist. Daraus folgt: - die KI muss **kein unsicheres Datum erfinden** - ein fehlendes belastbares Dokumentdatum ist **kein Fehlerfall** - die Anwendung verwendet in diesem Fall den Wert aus `ClockPort` ### 8.4 Titel Der Titel muss technisch diese Regeln erfüllen: - Deutsch - verständlich - eindeutig genug für den Dokumentkontext - maximal **20 Zeichen** als Basistitel - keine unzulässigen Windows-Dateinamenzeichen - keine generischen Platzhalter wie z. B. `Dokument`, `Datei`, `Scan`, `PDF` - Eigennamen bleiben unverändert - Umlaute und `ß` bleiben erhalten, sofern dateisystemseitig zulässig ### 8.5 Dubletten Bei Namenskollisionen wird das Suffix `(n)` unmittelbar vor `.pdf` angehängt. Beispiele: - `2026-03-31 - Stromabrechnung.pdf` - `2026-03-31 - Stromabrechnung(1).pdf` - `2026-03-31 - Stromabrechnung(2).pdf` ### 8.6 Windows-Kompatibilität Die Anwendung stellt zusätzlich sicher, dass der Zielname für Windows zulässig ist. Unzulässige Zeichen sind technisch zu entfernen oder kontrolliert zu ersetzen. --- ## 9. Fehlerklassifikation und Retry-Regeln ### 9.1 Grundsatz Nur **retryable** Fehler dürfen in späteren Läufen erneut verarbeitet werden. **Finale** Fehler werden in späteren Läufen übersprungen. ### 9.2 Deterministische Inhaltsfehler Deterministische Inhaltsfehler sind insbesondere: - kein brauchbarer PDF-Text - Seitenlimit überschritten - Dokument inhaltlich mehrdeutig - kein brauchbarer Titel - generischer oder unzulässiger Titel - von der KI gelieferter Datumswert ist vorhanden, aber unbrauchbar oder nicht interpretierbar Regel: - genau **1 Retry** in einem späteren Scheduler-Lauf - danach **finaler Fehler** ### 9.3 Transiente technische Fehler Transiente technische Fehler sind insbesondere: - KI nicht erreichbar - HTTP-Timeout - temporäre IO-Fehler - temporäre SQLite-Sperre - ungültiges oder nicht parsebares KI-JSON - sonstige vorübergehende technische Infrastrukturfehler Regel: - Retry in späteren Läufen bis zum konfigurierten Maximalwert ### 9.4 Technischer Sofort-Wiederholversuch Zusätzlich zulässig ist genau **ein technischer Sofort-Wiederholversuch** innerhalb desselben Laufs für den Zielkopiervorgang, wenn das Schreiben der Zieldatei fehlschlägt. Dieser Mechanismus ist **kein fachlicher Retry** und wird getrennt vom laufübergreifenden Retry-Modell behandelt. ### 9.5 Statusmodell Verbindlich zweckmäßige Statuswerte: - `SUCCESS` - `FAILED_RETRYABLE` - `FAILED_FINAL` - `SKIPPED_ALREADY_PROCESSED` - `SKIPPED_FINAL_FAILURE` Ein technischer Zwischenstatus `PROCESSING` ist zusätzlich zulässig und sinnvoll. --- ## 10. Idempotenz und Identifikation ### 10.1 Identifikation Die Identifikation eines Dokuments erfolgt **nicht** über den Dateinamen. Verbindlicher Primärmechanismus: - **SHA-256** der Quelldatei als stabiler Fingerprint ### 10.2 Wirkung Daraus folgt: - bereits erfolgreich verarbeitete Dateien werden in späteren Läufen nicht erneut verarbeitet - final fehlgeschlagene Dateien werden in späteren Läufen übersprungen - geänderter Dateiinhalt erzeugt einen neuen Fingerprint und damit einen neuen fachlichen Vorgang ### 10.3 Determinismus und Reproduzierbarkeit Reproduzierbarkeit bedeutet technisch: - nach einem erfolgreichen Lauf bleibt das gespeicherte Ergebnis stabil - erfolgreiche Dateien werden nicht erneut KI-basiert bewertet - KI-Aufrufe werden, soweit die API es zulässt, mit möglichst geringer Varianz konfiguriert - Prompt-Version und Modellname werden persistiert --- ## 11. KI-Integration ### 11.1 Schnittstelle Die KI wird ausschließlich über eine **OpenAI-kompatible HTTP-Schnittstelle** angebunden. Basis-URL, Modellname und API-Key sind reine Konfiguration. ### 11.2 Prompt Der Prompt wird **nicht** im Code fest verdrahtet. Verbindlich: - externe Prompt-Datei - Prompt-Version oder Prompt-Dateiname wird mitpersistiert - der Prompt darf die KI zur Ausgabe eines deutschen Titels anweisen ### 11.3 Textmenge Es wird nicht zwingend der komplette extrahierte PDF-Text an die KI gesendet. Verbindlich: - die maximale Zeichenzahl ist konfigurierbar - die Begrenzung muss vor dem KI-Aufruf technisch angewendet werden ### 11.4 Antwortformat Die KI muss genau ein parsebares JSON-Objekt liefern. Zweckmäßiges Schema: ```json { "date": "2026-02-11", "title": "Stromabrechnung", "reasoning": "..." } ``` Regeln: - `title` ist verpflichtend - `reasoning` ist verpflichtend - `date` ist optional, wenn kein belastbares Datum ableitbar ist - liefert die KI kein `date`, setzt die Anwendung das aktuelle Datum als Fallback ### 11.5 Antwortvalidierung Die Antwort gilt nur dann als technisch brauchbar, wenn: - JSON parsebar ist - `title` vorhanden ist - `reasoning` vorhanden ist Zusätzlich gilt fachlich: - `title` muss validierbar und brauchbar sein - ein vorhandenes `date` muss im Format `YYYY-MM-DD` interpretierbar sein --- ## 12. PDF-Verarbeitung ### 12.1 Bibliothek Für die PDF-Textauslese wird **Apache PDFBox** verwendet. ### 12.2 Voraussetzung Die Anwendung setzt voraus, dass die PDFs bereits **OCR-verarbeitet und durchsuchbar** sind. ### 12.3 Kein brauchbarer Text Wenn kein brauchbarer Text extrahiert werden kann: - erfolgt **kein** KI-Aufruf - der Fall wird als deterministischer Inhaltsfehler behandelt ### 12.4 Seitenlimit Die maximal verarbeitbare Seitenzahl ist konfigurierbar. Wird das Limit überschritten: - erfolgt **kein** KI-Aufruf - der Fall wird als deterministischer Inhaltsfehler behandelt --- ## 13. SQLite-Persistenzmodell ### 13.1 Ziel SQLite ist der führende lokale Speicher für: - Bearbeitungsstatus - Retry-Informationen - Versuchshistorie - KI-Nachvollziehbarkeit - Ergebnisnachvollziehbarkeit ### 13.2 Persistenzmodell Die Persistenz wird zweckmäßig in **zwei Ebenen** geführt: 1. **Dokument-Stammsatz** pro Fingerprint 2. **Versuchshistorie** mit einem Datensatz pro Verarbeitungsversuch ### 13.3 Dokument-Stammsatz Mindestens zweckmäßig zu speichern: - interne ID - Fingerprint - letzter bekannter Quellpfad - letzter bekannter Quelldateiname - aktueller Gesamtstatus - letzter Zielpfad - letzter Zieldateiname - Anzahl bisheriger Inhaltsfehler - Anzahl bisheriger transienter Fehler - letzter Fehlerzeitpunkt - letzter Erfolgzeitpunkt - Erstellungszeitpunkt - Änderungszeitpunkt ### 13.4 Versuchshistorie Für **jeden Versuch separat** zu speichern: - Versuchs-ID - Fingerprint-Referenz - Lauf-ID - Versuchsnummer - Startzeitpunkt - Endzeitpunkt - Ergebnisstatus - Fehlerklasse - Fehlermeldung - Retryable-Flag - Modellname - Prompt-Identifikator - verarbeitete Seitenzahl - an KI gesendete Zeichenzahl - KI-Rohantwort - KI-Reasoning - aufgelöstes Datum - Datumstyp bzw. Datumsquelle - finaler Titel - finaler Zieldateiname ### 13.5 Sensible Inhalte Die vollständige KI-Rohantwort wird in SQLite gespeichert. Sie soll **standardmäßig nicht vollständig in Logdateien** geschrieben werden. --- ## 14. Konfiguration ### 14.1 Format Die technische Konfiguration erfolgt über `.properties`. ### 14.2 Mindestparameter Verbindlich zweckmäßige Parameter: - `source.folder` - `target.folder` - `sqlite.file` - `api.baseUrl` - `api.model` - `api.timeoutSeconds` - `max.retries.transient` - `max.pages` - `max.text.characters` - `prompt.template.file` Zusätzlich zweckmäßig: - `runtime.lock.file` - `log.directory` - `log.level` - `api.key` ### 14.3 API-Key Der API-Key darf über Umgebungsvariable oder Properties geliefert werden. Verbindlich: - Umgebungsvariable hat Vorrang ### 14.4 Konfigurationsvalidierung Beim Start müssen alle Pflichtparameter validiert werden. Bei ungültiger Startkonfiguration: - beginnt kein Verarbeitungslauf - wird ein Fehler geloggt - wird das Programm mit **Exit-Code ungleich 0** beendet --- ## 15. Logging ### 15.1 Framework Verbindlich ist **Log4j2**. ### 15.2 Mindestumfang Das Logging muss mindestens enthalten: - Laufstart - Laufende - Lauf-ID - erkannte Quelldatei - Überspringen bereits erfolgreicher Dateien - Überspringen final fehlgeschlagener Dateien - erzeugter Zielname - Retry-Entscheidung - Fehler mit Klassifikation ### 15.3 Sensibilitätsregel Standardmäßig gilt: - vollständige KI-Rohantwort **nicht** ins Log - vollständige KI-Rohantwort **in SQLite** - `reasoning` darf geloggt werden, sofern dies betrieblich gewünscht ist - die Ausgabe sensibler Inhalte muss konfigurierbar sein ### 15.4 Speicherort Das Log-Verzeichnis ist konfigurierbar. Ohne explizite Konfiguration ist ein lokales `logs/`-Verzeichnis im Programmkontext zweckmäßig. --- ## 16. Startschutz und Parallelität ### 16.1 Verbindliche Regel Wenn bereits eine laufende Instanz existiert: - beendet sich die neue Instanz sofort ### 16.2 Umsetzung Zweckmäßig ist eine exklusive Lock-Datei über `RunLockPort`. Der Pfad der Lock-Datei soll konfigurierbar sein. ### 16.3 Ziel Der Startschutz verhindert: - konkurrierende SQLite-Zugriffe - kollidierende Zieldateikopien - inkonsistente Retry-Entscheidungen --- ## 17. Exit-Codes Verbindliche Interpretation: - `0`: Lauf wurde technisch ordnungsgemäß ausgeführt, auch wenn einzelne Dateien fachlich oder transient fehlgeschlagen sind - `1`: Lauf konnte wegen hartem Start-/Bootstrap-Fehler nicht ordnungsgemäß beginnen oder fortgesetzt werden Typische `1`-Fälle: - ungültige Konfiguration - Run-Lock nicht erwerbbar - essentielle Ressourcen beim Start nicht verfügbar --- ## 18. Nicht-Ziele Nicht Bestandteil dieser Architektur sind: - Web-UI - REST-API zur Bedienung - DMS-Funktionalität - OCR innerhalb der Java-Anwendung - automatische Löschung von Quelldateien - Verschiebung von Quelldateien statt Kopie - menschlicher Review-Workflow - interne Scheduler-Logik - fachliche Identifikation über Dateinamen --- ## 19. Abschlussbewertung Der technische Zielstand ist mit den hier festgelegten Regeln: - konsistent - widerspruchsfrei - hexagonal sauber geschnitten - für einen minimalen produktiven PDF-Umbenenner zweckmäßig Besonders verbindlich geklärt sind jetzt: - Dateinamensformat mit `YYYY-MM-DD - Titel.pdf` - Dublettenregel mit `(1)`, `(2)`, ... - Trennung zwischen finalen und retrybaren Fehlern - Fallback-Datum durch die Anwendung - Zwei-Ebenen-Persistenz mit Versuchshistorie - Exit-Code-Regel für harte Startfehler - OpenAI-kompatible Schnittstelle ohne fest verdrahteten Provider - Verlagerung technischer Persistenzobjekte aus der Domain heraus