1
0

M1-Fix: Exit-Code für ungültige Konfiguration auf 1 geändert

This commit is contained in:
2026-03-31 16:00:37 +02:00
parent ea83f8fa8c
commit 91b7a918c7
6 changed files with 1722 additions and 0 deletions

View File

@@ -0,0 +1,225 @@
# Fachliche Anforderungen PDF-Umbenenner
## 1. Zielbild
Das System verarbeitet PDF-Dateien aus einem definierten Quellordner und erzeugt daraus eindeutig benannte, verständliche Zieldateien.
Ziel ist eine automatisierte, nachvollziehbare, robuste und wiederholbare Benennung von Dokumenten für den produktiven Einsatz.
---
## 2. Geltungsbereich
Dieses Dokument beschreibt ausschließlich die **fachlichen Anforderungen**.
Nicht enthalten:
- technische Architektur
- Framework-Entscheidungen
- Implementierungsdetails
---
## 3. Hauptprozess
1. Eine PDF-Datei im Quellordner wird als **Verarbeitungskandidat** erkannt.
2. Die Datei wird verarbeitet.
3. Falls erfolgreich:
- Ein neuer Dateiname wird erzeugt.
- Die Datei wird im Zielordner abgelegt.
4. Falls fehlgeschlagen:
- Der Fehler wird dokumentiert.
- Ein Retry erfolgt abhängig von der Fehlerart.
---
## 4. Benennungsregeln
### 4.1 Format
Der Dateiname folgt strikt diesem Muster:
`YYYY-MM-DD - Titel.pdf`
---
### 4.2 Datum
Priorität:
1. Rechnungsdatum
2. Dokumentdatum
3. anderes sinnvolles Dokumentdatum
4. aktuelles Datum (Fallback)
#### Definition „anderes sinnvolles Dokumentdatum“
Reihenfolge:
1. Ausstellungsdatum
2. Bescheiddatum
3. Schreibdatum
4. Ende eines Leistungszeitraums
Fallback auf aktuelles Datum ist erlaubt, wenn kein belastbares Datum eindeutig ableitbar ist.
---
### 4.3 Titel
- maximal **20 Zeichen (Basistitel)**
- verständlich und eindeutig
- keine Sonderzeichen außer Leerzeichen
---
### 4.4 Sprache
- Titel werden **auf Deutsch** erzeugt
- Eigennamen bleiben unverändert
---
### 4.5 Dublettenregel
Bei Namenskonflikten:
- `(1)`, `(2)`, … wird angehängt
Regel:
- 20 Zeichen gelten nur für den Basistitel
- Suffix wird zusätzlich ergänzt
---
## 5. Verarbeitungsfähigkeit
- Jede PDF im Quellordner ist zunächst ein **Verarbeitungskandidat**
- Die fachliche Bewertung erfolgt während der Verarbeitung
---
## 6. Fehlerbehandlung
### 6.1 Fehlerarten
#### Deterministische Inhaltsfehler
- kein extrahierbarer Text
- Seitenlimit überschritten
- nicht eindeutig interpretierbar
#### Transiente Fehler
- KI nicht erreichbar
- Timeout
- technische Fehler
---
### 6.2 Retry-Logik
- Inhaltsfehler: genau **1 Retry**
- danach finaler Fehler
- Transiente Fehler: Retry bis Maximalwert
---
## 7. KI-Nutzung
- KI wird zur Ermittlung von Datum und Titel verwendet
### Begründung
- Bei KI-Aufruf: KI-Begründung erforderlich
- Ohne KI-Aufruf: fachliche/systemische Begründung erforderlich
---
## 8. Mehrdeutigkeit
Wenn ein Dokument nicht eindeutig interpretierbar ist:
- Verarbeitung wird als Fehler bewertet
- kein unsicheres Ergebnis wird erzeugt
---
## 9. Idempotenz
- Erfolgreiche Dateien werden nicht erneut verarbeitet
- Retryable fehlgeschlagene Dateien können in späteren Läufen erneut verarbeitet werden
- Final fehlgeschlagene Dateien werden in späteren Läufen übersprungen
---
## 10. Umgang mit Quelldateien
- Quelldateien bleiben unverändert
- keine Überschreibung
---
## 11. Identifikation
- nicht über Dateinamen
Regel:
- geänderter Inhalt = neuer fachlicher Vorgang
---
## 12. Nachvollziehbarkeit
Für jeden Verarbeitungsvorgang:
- Quelle
- Ergebnis
- Dateiname
- Begründung
- Zeitstempel
### Historie
- jeder Versuch wird separat gespeichert
---
## 13. Akzeptanzkriterien
Ein Ergebnis ist korrekt, wenn:
- Format stimmt
- Datum korrekt ist
- Titel max. 20 Zeichen hat
- Dubletten korrekt behandelt wurden
- Begründung vorhanden ist
- Ergebnis reproduzierbar ist
---
## 14. Nicht-Ziele
- keine manuelle Nachbearbeitung
- keine Benutzerinteraktion
- keine Inhaltsänderung von Dokumenten
---
## 15. Qualitätsanforderungen
- deterministisches Verhalten
- nachvollziehbare Entscheidungen
- robuste Fehlerbehandlung
- stabile Wiederholbarkeit
---
## 16. Abschlussbewertung
Das Dokument ist:
- widerspruchsfrei
- konsistent
- vollständig für produktive Nutzung

334
docs/specs/meilensteine.md Normal file
View File

@@ -0,0 +1,334 @@
# Meilensteine KI-gestützte Umbenennung OCR-verarbeiteter PDFs
## Grundsätze für alle Meilensteine
- Jeder Meilenstein liefert einen **in sich geschlossenen, lauffähigen Entwicklungsstand**.
- Jeder Meilenstein umfasst **Implementierung, Konfiguration, JavaDoc und Tests**, soweit für den jeweiligen Stand sinnvoll.
- Die Lösung wird von Beginn an in **strenger hexagonaler Architektur** umgesetzt.
- Jeder Meilenstein baut auf dem vorherigen Stand auf, ohne Architekturbrüche oder provisorische Seiteneffekte zu erzeugen.
- Die Meilensteine bilden zusammen vollständig die fachlichen Anforderungen sowie das technische Zielbild ab.
- Fachliche Entscheidungen werden nicht in technische Adapter verschoben, technische Infrastruktur nicht in die Domain.
---
## M1 Vollständiges Maven-Projekt und technisches Grundgerüst
### Ziel
Erstellung eines vollständig lauffähigen Multi-Modul-Maven-Projekts als stabile Basis der Gesamtentwicklung.
### Inhalt
- vollständige Maven-Projektstruktur in strenger Hexagonal-Architektur erstellen:
- `domain`
- `application`
- `adapter-in`
- `adapter-out`
- `bootstrap`
- Parent-POM mit `packaging=pom` anlegen
- Modul-POMs vollständig konfigurieren
- alle benötigten Dependencies fest einbinden, insbesondere für:
- Log4j2
- Apache PDFBox
- SQLite JDBC
- OpenAI-kompatiblen HTTP-Zugriff
- JSON-Verarbeitung
- Test-Frameworks
- benötigte Maven-Plugins vollständig konfigurieren, insbesondere für:
- Compiler
- Surefire
- Enforcer
- Shade im Bootstrap-Modul
- Logging-Konfiguration mit Log4j2 anlegen
- lauffähigen Bootstrap-Einstiegspunkt bereitstellen
- `.properties`-Konfiguration grundlegend laden
- Grundvalidierung der Startkonfiguration vorsehen
- Build-, Start- und Testfähigkeit herstellen
### Lauffähiger Stand
- das Projekt baut vollständig mit Maven
- das ausführbare JAR startet erfolgreich
- Logging funktioniert
- Konfiguration wird geladen oder sauber validiert
- das Programm beendet sich kontrolliert ohne fachliche Verarbeitung
### Tests
- Build-/Smoke-Test für Programmstart
- Tests für Konfigurationsladen und Grundvalidierung
- Tests für Logging-/Bootstrap-Grundverhalten, soweit sinnvoll
---
## M2 Hexagonaler Kern, Batch-Startfall und Startschutz
### Ziel
Der fachliche Kern, der Batch-Einstieg und der technische Startschutz sind sauber modelliert, jedoch noch ohne vollständige Dokumentverarbeitung.
### Inhalt
- Domain-Objekte und Statusmodell anlegen
- zentrale Ports definieren
- zentralen Inbound-Use-Case für den Batch-Lauf implementieren
- CLI-/Batch-Adapter implementieren
- Bootstrap-Verdrahtung vervollständigen
- Run-Lock-Port und erste Lock-Implementierung einführen
- Lauf-ID-Konzept einführen
- Exit-Code-Grundverhalten vorbereiten:
- `0` für technisch ordnungsgemäß ausgeführten Lauf
- `1` für harte Start-/Bootstrap-Fehler
- JavaDoc für Architekturgrenzen, Ports und zentrale Typen ergänzen
### Lauffähiger Stand
- das Programm startet als Batch-Prozess
- Lauf-Sperre wird gesetzt und freigegeben
- eine zweite Instanz beendet sich kontrolliert sofort
- der Use-Case wird über den Inbound-Adapter erreicht
- Architekturgrenzen sind technisch sichtbar und eingehalten
- noch keine echte PDF-Verarbeitung, aber kontrollierter Batch-Ablauf vorhanden
### Tests
- Unit-Tests für Domain-Objekte und Statusmodell
- Tests für Lock-Verhalten
- Tests für Bootstrap- und Use-Case-Verdrahtung
- Tests für Exit-Code-Verhalten bei Startschutz- und Bootstrap-Fehlern, soweit in diesem Stand sinnvoll
---
## M3 Dateisystemzugriff, Kandidatenermittlung und PDF-Textauslese
### Ziel
Der Batch-Prozess kann PDFs im Quellordner finden, fachlich als Verarbeitungskandidaten behandeln sowie Text und Seitenzahl extrahieren.
### Inhalt
- Dateisystem-Adapter für Quellordnerzugriff implementieren
- PDF-Dateifilter gemäß fachlicher Regeln umsetzen
- PDFBox-Adapter zur Textauslese implementieren
- Seitenzahlermittlung integrieren
- Prüfung auf „brauchbaren Text“ umsetzen
- konfigurierbares Seitenlimit einführen
- erste Dateiobjekte und Metadatenfluss im Use-Case herstellen
- sicherstellen, dass bei fehlendem brauchbarem Text oder überschrittenem Seitenlimit **kein KI-Aufruf** erfolgt
- JavaDoc für Adapter, Fehlerfälle und Kandidatenbegriff ergänzen
### Lauffähiger Stand
- das Programm scannt den Quellordner
- passende PDFs werden erkannt
- Text und Seitenzahl werden extrahiert
- Dateien ohne brauchbaren Text oder oberhalb des Seitenlimits werden erkannt und protokolliert
- diese Fälle werden als deterministische Inhaltsfehler behandelt
- noch keine KI-Anbindung und noch keine Ergebnisdatei
### Tests
- Unit-Tests für PDF-Filterlogik
- Tests für Textauslese und Seitenzahlerkennung
- Tests für Fehlerfälle „kein brauchbarer Text“ und „Seitenlimit überschritten“
- Tests dafür, dass in diesen Fehlerfällen kein KI-Aufruf stattfindet
---
## M4 Fingerprint, SQLite-Persistenz und Idempotenz
### Ziel
Die Anwendung kann verarbeitete Dateien stabil wiedererkennen, Bearbeitungszustände dauerhaft speichern und jeden Verarbeitungsversuch nachvollziehbar historisieren.
### Inhalt
- Fingerprint-Port und SHA-256-basierte Implementierung einführen
- SQLite-Schema vollständig implementieren
- Persistenzmodell explizit in **zwei Ebenen** umsetzen:
- Dokument-Stammsatz pro Fingerprint
- Versuchshistorie mit einem Datensatz pro Verarbeitungsversuch
- Statusmodell persistent nutzbar machen
- Retry-Zähler und Fehlstatus speichern
- Regeln für „bereits erfolgreich verarbeitet“ und „final fehlgeschlagen“ umsetzen
- Versuchshistorie explizit mit mindestens folgenden technischen Metadaten anlegen:
- Lauf-ID
- Versuchsnummer
- Start- und Endzeitpunkt
- Ergebnisstatus
- Fehlerklasse
- Fehlermeldung bzw. fachliche/systemische Begründung
- Retryable-Flag
- JavaDoc für Persistenzmodell, Statusübergänge und Idempotenz ergänzen
### Lauffähiger Stand
- das Programm erkennt identische Quelldateien über Fingerprint wieder
- erfolgreich verarbeitete Dateien werden in späteren Läufen übersprungen
- final fehlgeschlagene Dateien werden in späteren Läufen übersprungen
- Bearbeitungsstände werden in SQLite gespeichert
- jeder Verarbeitungsversuch wird separat historisiert
- der Batch-Lauf ist idempotent gegenüber Wiederholungen
- noch keine KI-Anbindung und noch keine Zielkopie
### Tests
- Unit-Tests für Fingerprint-Erzeugung
- Repository-Tests gegen SQLite
- Tests für Statusübergänge, Retry-Zähler und Skip-Logik
- Tests für Versuchshistorie pro Lauf und pro Versuch
---
## M5 KI-Integration, Prompt-Bezug und validierter Benennungsvorschlag
### Ziel
Die Anwendung kann aus extrahiertem PDF-Text per KI einen validierten Benennungsvorschlag erzeugen und alle KI-bezogenen Nachvollziehbarkeitsdaten persistent festhalten.
### Inhalt
- externe Prompt-Datei laden und versionierbar anbinden
- OpenAI-kompatiblen HTTP-Adapter implementieren
- Basis-URL, Modellname, Timeout und API-Zugriff vollständig konfigurierbar machen
- Priorität Umgebungsvariable vor Properties für API-Key umsetzen
- Begrenzung des an die KI gesendeten Inhalts umsetzen
- parsebares JSON-Ergebnis mit `date`, `title`, `reasoning` verarbeiten
- Validierung umsetzen:
- `title` ist verpflichtend
- `reasoning` ist verpflichtend
- `date` ist optional
- fachliche Validierung für Datum und Titel umsetzen
- falls die KI **kein** belastbares Datum liefert, den Fallback **durch die Anwendung** über die technische Uhr/Clock vorsehen
- unbrauchbare KI-Antworten als Fehlerfälle behandeln
- Versuchshistorie um KI-Nachvollziehbarkeit explizit erweitern, insbesondere um:
- Modellname
- Prompt-Identifikator oder Prompt-Dateiname
- verarbeitete Seitenzahl
- an KI gesendete Zeichenzahl
- KI-Rohantwort
- KI-Reasoning
- aufgelöstes Datum
- Datumsquelle
- JavaDoc für KI-Port, Antwortvalidierung und Datumsauflösung ergänzen
### Lauffähiger Stand
- das Programm kann für verarbeitbare PDFs einen gültigen Benennungsvorschlag erzeugen
- gültige und ungültige KI-Antworten werden korrekt unterschieden
- bei fehlendem belastbarem KI-Datum wird das Datum durch die Anwendung als Fallback aufgelöst
- KI-Nachvollziehbarkeit ist persistent gespeichert
- noch keine physische Zielkopie, aber der vollständige Benennungsvorschlag ist verfügbar und gespeichert
### Tests
- Unit-Tests für Response-Validierung
- Tests für Prompt-Laden und Konfigurationsauflösung
- Tests für Fehlerfälle wie Timeout, ungültiges JSON und unbrauchbaren Titel
- Tests für Datums-Fallback durch die Anwendung
- Mock-/Adapter-Tests für den KI-Port
---
## M6 Dateinamensbildung, Dublettenbehandlung und Zielkopie
### Ziel
Der vollständige Erfolgspfad wird umgesetzt: Aus KI-Ergebnis und technischer Datumsauflösung wird ein zulässiger Zielname erzeugt und eine Kopie im Zielordner abgelegt.
### Inhalt
- technische Dateinamensbildung implementieren
- verbindliches Zielformat umsetzen: `YYYY-MM-DD - Titel.pdf`
- Windows-Zeichenbereinigung ergänzen
- Titellängenregel für den **Basistitel** umsetzen
- feste deutsche Titelregeln technisch absichern
- fachliche Titelregel „keine Sonderzeichen außer Leerzeichen“ technisch absichern
- Dubletten-Suffix `(1)`, `(2)` usw. implementieren
- Zielordnerprüfung und Zielpfadbildung vervollständigen
- Kopierlogik in den Zielordner implementieren
- temporäre Zieldatei mit finalem Rename bzw. atomisches Schreiben umsetzen, soweit möglich
- Erfolgsstatus erst nach erfolgreichem Schreiben **und** erfolgreicher Persistenz setzen
- finalen Zieldateinamen und Zielpfad persistent speichern
- JavaDoc für Dateinamensregeln, Dubletten und Zielerzeugung ergänzen
### Lauffähiger Stand
- das Programm verarbeitet PDFs Ende-zu-Ende erfolgreich
- bei Erfolg entsteht eine korrekt benannte Kopie im Zielordner
- die Quelldatei bleibt unverändert erhalten
- Dubletten werden korrekt ab `(1)` behandelt
- Erfolgsstatus, Zieldateiname und Zielpfad werden konsistent gespeichert
### Tests
- Unit-Tests für Dateinamensbildung und Dubletten-Suffixe
- Tests für technische Zeichenbereinigung
- Tests für Basistitel-Längenregel und Zielformat
- integrationsnahe Tests für Zielkopie und Erfolgsstatus
---
## M7 Fehlerbehandlung, Retry-Logik, Logging und betriebliche Robustheit
### Ziel
Die Lösung wird robust gegen typische Fehlerfälle und verhält sich in wiederholten Task-Scheduler-Läufen stabil, nachvollziehbar und konsistent.
### Inhalt
- fachliche Retry-Logik über spätere Läufe vollständig umsetzen
- deterministische Inhaltsfehler mit genau **1 Retry** in späterem Lauf umsetzen
- transiente technische Fehler mit Retry bis zum konfigurierten Maximalwert umsetzen
- finalen Fehlerstatus nach Ausschöpfen der jeweiligen Retry-Regeln umsetzen
- Sofort-Wiederholversuch nur für Schreibfehler der Zielkopie implementieren
- Skip-Logik für bereits erfolgreich verarbeitete und final fehlgeschlagene Dateien vervollständigen
- Logging auf den final geforderten Mindestumfang bringen, insbesondere mit:
- Laufstart
- Laufende
- Lauf-ID
- erkannte Quelldatei
- Überspringen bereits erfolgreicher Dateien
- Überspringen final fehlgeschlagener Dateien
- erzeugter Zielname
- Retry-Entscheidung
- Fehler mit Klassifikation
- Sensibilitätsregel für Logs umsetzen:
- vollständige KI-Rohantwort standardmäßig **nicht** ins Log
- vollständige KI-Rohantwort **in SQLite**
- Ausgabe sensibler Inhalte konfigurierbar
- Exit-Code-Verhalten finalisieren:
- `0` auch bei Teilfehlern einzelner Dateien, solange der Lauf technisch ordnungsgemäß ausgeführt wurde
- `1` nur bei harten Start-/Bootstrap-Fehlern
- Konfigurationsvalidierung vervollständigen
- Fehlernachvollziehbarkeit in Logs und SQLite konsistent machen
- JavaDoc zu Fehlersemantik, Retry-Regeln, Exit-Codes und Logging ergänzen
### Lauffähiger Stand
- die Anwendung verhält sich in Erfolg, Teilfehlern und Endfehlern stabil
- wiederholte Scheduler-Läufe führen zu keinem inkonsistenten Verhalten
- Fehler einzelner Dateien blockieren nicht den Gesamtlauf
- Retry-Zähler, Endstatus und Überspringen funktionieren konsistent
- Exit-Code und Logging entsprechen dem definierten Betriebsmodell
### Tests
- Tests für Retry-Abläufe über mehrere Läufe
- Tests für finale Fehlerzustände
- Tests für Skip-Logik bei bereits verarbeiteten Dateien
- Tests für Sofort-Wiederholversuch bei Zielkopierfehlern
- Tests für Logging-Sensibilitätsregel, soweit automatisierbar
- Tests für Konfigurationsfehler und finales Exit-Code-Verhalten
---
## M8 Abschlussmeilenstein: Qualitätssicherung, Feinschliff und vollständige Entwicklungsfreigabe
### Ziel
Die Entwicklung wird vollständig abgeschlossen und der Gesamtstand auf Produktionsreife innerhalb des definierten Projektumfangs gebracht.
### Inhalt
- Review aller Architekturgrenzen und Sicherstellung der strengen Hexagonal-Architektur
- Abgleich aller Meilenstein-Ergebnisse mit Fachlichkeit sowie Technik/Architektur
- letzte technische und fachliche Restlücken schließen
- JavaDoc vervollständigen
- Testabdeckung gezielt vervollständigen
- Konfigurationsbeispiel und Startdokumentation konsolidieren
- Logging- und Fehlermeldungen sprachlich und inhaltlich schärfen
- letzte Inkonsistenzen in Statusmodell, Persistenz und Adapterverhalten bereinigen
- End-to-End-Gesamtprüfung des vollständigen Soll-Ablaufs durchführen
### Lauffähiger Stand
- die Lösung ist innerhalb des definierten Umfangs vollständig implementiert
- alle Kernanforderungen aus Fachlichkeit sowie Technik/Architektur sind umgesetzt
- der Stand ist stabil, testbar, dokumentiert und für den geplanten Betrieb bereit
### Tests
- vollständige End-to-End-Tests, soweit im Projekt sinnvoll automatisierbar
- Regressionstests für Kernregeln
- Konsistenztests für Persistenz, Dateinamensbildung, Retry-Logik und Skip-Verhalten
- abschließende Smoke-Tests für Build, Start und Batch-Lauf
---
## Abschlussbewertung
Die Meilensteine sind mit diesem Stand:
- vollständig auf das fachliche Zielbild ausgerichtet
- mit dem technischen Architekturziel konsistent
- widerspruchsfrei und logisch aufeinander aufbauend
- für eine schrittweise produktive Umsetzung geeignet

View File

@@ -0,0 +1,638 @@
# 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