639 lines
18 KiB
Markdown
639 lines
18 KiB
Markdown
# 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
|