1
0

CLAUDE.md für V2.0 angepasst

This commit is contained in:
2026-04-13 08:59:12 +02:00
parent 22ec512cd7
commit be6e3d1971

235
CLAUDE.md
View File

@@ -3,11 +3,15 @@
## Zweck ## Zweck
Dieses Repository implementiert einen lokal gestarteten **PDF-Umbenenner mit KI**. Das Programm liest bereits OCR-verarbeitete, durchsuchbare PDF-Dateien aus einem Quellordner, ermittelt daraus einen normierten Dateinamen und legt **eine Kopie** der Datei im Zielordner ab. Die Quelldatei bleibt unverändert. Dieses Repository implementiert einen lokal gestarteten **PDF-Umbenenner mit KI**. Das Programm liest bereits OCR-verarbeitete, durchsuchbare PDF-Dateien aus einem Quellordner, ermittelt daraus einen normierten Dateinamen und legt **eine Kopie** der Datei im Zielordner ab. Die Quelldatei bleibt unverändert.
Ab V2.0 wird die Anwendung um eine **lokale JavaFX-Desktop-GUI** erweitert. Die GUI ist der neue Standardstart. Der bestehende headless Batch-Betrieb bleibt über `--headless` vollständig erhalten.
## Autoritative Dokumente ## Autoritative Dokumente
@docs/specs/technik-und-architektur.md @docs/specs/technik-und-architektur.md
@docs/specs/fachliche-anforderungen.md @docs/specs/fachliche-anforderungen.md
@docs/specs/meilensteine-v2_0.md
Für die Umsetzung ist zusätzlich immer das aktuell aktive Arbeitspaket unter `docs/workpackages/` maßgeblich. Für die Umsetzung ist zusätzlich immer das aktuell aktive Arbeitspaket unter `docs/workpackages/` maßgeblich.
Dateinamensschema: `M9 - Arbeitspakete.md`, `M10 - Arbeitspakete.md`, … `M13 - Arbeitspakete.md`
Nicht raten, wenn Dokumente fehlen, unklar sind oder sich widersprechen. Nicht raten, wenn Dokumente fehlen, unklar sind oder sich widersprechen.
## Priorisierung der Regeln ## Priorisierung der Regeln
@@ -15,6 +19,7 @@ Die Dokumente haben folgende feste Bedeutung:
- `docs/specs/technik-und-architektur.md` = verbindliche technische Zielarchitektur - `docs/specs/technik-und-architektur.md` = verbindliche technische Zielarchitektur
- `docs/specs/fachliche-anforderungen.md` = verbindliche fachliche Regeln - `docs/specs/fachliche-anforderungen.md` = verbindliche fachliche Regeln
- `docs/specs/meilensteine-v2_0.md` = verbindliche V2.0-Zieldefinition und Meilensteinabgrenzung
- `docs/workpackages/...` = verbindlicher Scope, Reihenfolge und Inhalt des aktuell bearbeiteten Arbeitspakets - `docs/workpackages/...` = verbindlicher Scope, Reihenfolge und Inhalt des aktuell bearbeiteten Arbeitspakets
Bei Konflikten gilt folgende Priorität: Bei Konflikten gilt folgende Priorität:
@@ -25,7 +30,10 @@ Bei Konflikten gilt folgende Priorität:
2. **Fachliche Anforderungen** 2. **Fachliche Anforderungen**
Verbindliche fachliche Regeln und fachliches Zielverhalten. Verbindliche fachliche Regeln und fachliches Zielverhalten.
3. **Arbeitspakete** 3. **Meilensteine V2.0**
Verbindliche Zieldefinition, Abgrenzungen und Leitplanken für den V2.0-Ausbau.
4. **Arbeitspakete**
Definieren den konkret erlaubten Umsetzungsumfang des aktuellen Schritts. Definieren den konkret erlaubten Umsetzungsumfang des aktuellen Schritts.
Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und keine stillen Annahmen treffen. Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und keine stillen Annahmen treffen.
@@ -33,35 +41,46 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
## Unverrückbare Technikvorgaben ## Unverrückbare Technikvorgaben
- Java 21 - Java 21
- Maven Multi-Module - Maven Multi-Module
- ausführbares Standalone-JAR - ausführbares Standalone-JAR (ein gemeinsames JAR für GUI und headless)
- Start über Windows Task Scheduler - **GUI ist der neue Standardstart** (ab V2.0)
- `--headless` startet weiterhin den bestehenden Batch-/Scheduler-Betrieb
- `--config <pfad>` steht für GUI und headless zur Verfügung
- kein Webserver - kein Webserver
- kein Applikationsserver - kein Applikationsserver
- keine Dauerlauf-Anwendung - keine Dauerlauf-Anwendung
- kein interner Scheduler - kein interner Scheduler
- keine EXE, kein Installer
- Log4j2 für Logging - Log4j2 für Logging
- SQLite als lokaler Persistenzspeicher - SQLite als lokaler Persistenzspeicher
- JavaFX wird mit dem JAR ausgeliefert (kein separates JavaFX-Setup)
- GUI offiziell nur für Windows; headless bleibt für Windows Server / Task Scheduler geeignet
- gemappte Laufwerke wie `S:\` oder `H:\` sind ausdrücklich zu unterstützen
- KI-Anbindung über genau **eine** der beiden unterstützten Provider-Familien: - KI-Anbindung über genau **eine** der beiden unterstützten Provider-Familien:
- **OpenAI-kompatible HTTP-Schnittstelle** (Chat-Completions-Stil) - **OpenAI-kompatible HTTP-Schnittstelle** (Chat-Completions-Stil)
- **native Anthropic Messages API** (Claude-Modelle) - **native Anthropic Messages API** (Claude-Modelle)
- Pro Lauf ist genau ein Provider aktiv. Kein Fallback, keine Parallelnutzung. - Pro Lauf ist genau ein Provider aktiv. Kein Fallback, keine Parallelnutzung.
- `.properties` bleibt die einzige Konfigurationswahrheit
- Konkrete Provider-Familie, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung. - Konkrete Provider-Familie, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung.
## Verbindliche Modulstruktur ## Verbindliche Modulstruktur (ab V2.0)
- `pdf-umbenenner-domain` - `pdf-umbenenner-domain`
- `pdf-umbenenner-application` - `pdf-umbenenner-application`
- `pdf-umbenenner-adapter-in-cli` - `pdf-umbenenner-adapter-in-cli`
- `pdf-umbenenner-adapter-in-gui`
- `pdf-umbenenner-adapter-out` - `pdf-umbenenner-adapter-out`
- `pdf-umbenenner-bootstrap` - `pdf-umbenenner-bootstrap`
## Architekturregeln ## Architekturregeln
- Strikte **hexagonale Architektur / Ports and Adapters** - Strikte **hexagonale Architektur / Ports and Adapters**
- Abhängigkeiten zeigen immer **nach innen** - Abhängigkeiten zeigen immer **nach innen**
- Domain kennt **keine** Infrastruktur, keine Datenbank, kein Dateisystem und keine HTTP-Kommunikation - Domain kennt **keine** Infrastruktur, keine Datenbank, kein Dateisystem, keine HTTP-Kommunikation und **kein JavaFX**
- Application orchestriert Use Cases und enthält keine technischen Implementierungsdetails - Application enthält keine technischen Implementierungsdetails und **keine JavaFX-Typen**
- Externe Zugriffe erfolgen ausschließlich über **Ports** - Externe Zugriffe erfolgen ausschließlich über **Ports**
- Konkrete technische Implementierungen sind **Adapter** - Konkrete technische Implementierungen sind **Adapter**
- Adapter dürfen nicht direkt voneinander abhängen - Adapter dürfen nicht direkt voneinander abhängen
- Die GUI ist ein **Inbound-Adapter** (`pdf-umbenenner-adapter-in-gui`) sie wird **nicht** in Bootstrap vermischt
- Bootstrap bleibt verantwortlich für: Startmoduswahl, Konfigurationsauflösung, Objektgraph, kontrollierten Start des passenden Adapters, Exit-Code-Ableitung bei harten Startfehlern
- GUI-Code und JavaFX dürfen im **headless Pfad** nicht unnötig früh initialisiert oder geladen werden
- Keine Vermischung von Dateisystem, PDF-Auslese, SQLite, KI-HTTP, Konfiguration, Logging, Benennungslogik und Retry-Entscheidungen - Keine Vermischung von Dateisystem, PDF-Auslese, SQLite, KI-HTTP, Konfiguration, Logging, Benennungslogik und Retry-Entscheidungen
- Logging ist technische Infrastruktur, kein fachlicher Port - Logging ist technische Infrastruktur, kein fachlicher Port
- Port-Verträge enthalten weder `Path`/`File` noch NIO- oder JDBC-Typen - Port-Verträge enthalten weder `Path`/`File` noch NIO- oder JDBC-Typen
@@ -69,6 +88,35 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
- Es gibt keine gemeinsame „abstrakte KI-Adapter"-Zwischenschicht zwischen Port und konkreten Adaptern - Es gibt keine gemeinsame „abstrakte KI-Adapter"-Zwischenschicht zwischen Port und konkreten Adaptern
- Die Bootstrap-Schicht wählt die **eine** aktive `AiNamingPort`-Implementierung anhand der Konfiguration aus - Die Bootstrap-Schicht wählt die **eine** aktive `AiNamingPort`-Implementierung anhand der Konfiguration aus
## GUI-Leitplanken (verbindlich für alle V2.0-Arbeitspakete)
### Threadingmodell
- Jede potenziell blockierende Operation (Modellabruf, technische Tests, Pfad-/Dateisystemprüfungen, SQLite-Prüfungen, Lesen/Schreiben der `.properties`) läuft auf einem **Hintergrund-Worker-Thread**
- UI-Updates erfolgen ausschließlich über den **JavaFX Application Thread** (`Platform.runLater`)
- Die GUI darf während laufender Hintergrund-Operationen **nicht einfrieren**
### GUI-Teststrategie
- **View-Modelle und Application-nahe GUI-Logik** werden mit JUnit unit-getestet; Fokus auf Zustandsübergängen, Validierungsregeln und Datenflüssen nicht auf Rendering
- **GUI-Smoke-Tests** laufen unter **headless JavaFX (Monocle)** in der Maven-Test-Phase
- Kein TestFX, kein weiteres GUI-Testframework über Monocle hinaus
### GUI-Logging
- Der GUI-Adapter nutzt denselben Log4j2-Stack wie der headless Pfad
- Logformat und Log-Verzeichnis bleiben gegenüber dem headless Betrieb unverändert
- Mindesteinträge für GUI-nahe Ereignisse: Start- und Beendigungsereignisse der GUI, Modellabruf-Versuche (Provider, Erfolg/Misserfolg, **ohne API-Key**), Dateischreibvorgänge inkl. Zielpfad, Ergebnisse der Aktionen `Validieren` und `Technische Tests ausführen`, sowie alle schreibenden Korrekturen
### `--config`-Semantik
- Zeigt `--config <pfad>` im **GUI-Start** auf eine nicht existente Datei: Fehlermeldung, danach verhält sich die GUI so, als wäre `--config` nicht angegeben worden
- Zeigt `--config <pfad>` im **headless Start** auf eine nicht existente Datei: **harter Startfehler**, kein stiller Fallback
## JavaDoc-Standard (verbindlich für alle V2.0-Arbeitspakete)
Für jede **neu hinzugefügte** oder **substanziell geänderte** öffentliche Klasse, öffentliche Methode und jedes neue Java-Package gilt:
- **Klassen-JavaDoc**: Zweck, Verantwortung und Abgrenzung der Klasse
- **Methoden-JavaDoc**: Zweck, Parameter, Rückgabewert und dokumentierte Ausnahmen
- **`package-info.java`**: pro neuem Package, mit Kurzbeschreibung der Paketverantwortung
Ein Arbeitspaket ist erst fertig, wenn die betroffenen öffentlichen Klassen und Methoden dem JavaDoc-Standard entsprechen.
## Globale fachliche Leitplanken ## Globale fachliche Leitplanken
- Zielformat: `YYYY-MM-DD - Titel.pdf` - Zielformat: `YYYY-MM-DD - Titel.pdf`
- Bei Namenskollisionen: `YYYY-MM-DD - Titel(1).pdf`, `YYYY-MM-DD - Titel(2).pdf`, ... - Bei Namenskollisionen: `YYYY-MM-DD - Titel(1).pdf`, `YYYY-MM-DD - Titel(2).pdf`, ...
@@ -85,19 +133,11 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
- Quelldateien werden **nie** überschrieben, verändert, verschoben oder gelöscht - Quelldateien werden **nie** überschrieben, verändert, verschoben oder gelöscht
## Aktiver Implementierungsstand ## Aktiver Implementierungsstand
V1.1 ist vollständig umgesetzt, dokumentiert, getestet und freigegeben.
Die fachliche und technische Basis ist vollständig umgesetzt, dokumentiert, getestet (inkl. PIT-Mutationstests, Smoke-Tests, End-to-End-Tests) und freigegeben. Der aktive Entwicklungsstand ist **V2.0**. Ziel ist der Ausbau um eine lokale JavaFX-Desktop-GUI als neuen Standardstart, ohne die bestehende Architektur, das Standalone-JAR-Betriebsmodell oder den headless Scheduler-Betrieb aufzugeben.
Der aktive Stand ist die Erweiterung **„Zusätzlicher KI-Provider Anthropic Claude über die native Messages API"**. Sie ist eine bewusst minimale Erweiterung des freigegebenen Basisstands. Die fachliche Kernverarbeitung des PDF-Umbenenners bleibt in V2.0 unverändert.
### Ziel der aktiven Erweiterung
- Der bestehende OpenAI-kompatible KI-Weg bleibt unverändert nutzbar.
- Zusätzlich wird die **native Anthropic Messages API** als zweite, gleichwertig unterstützte Provider-Familie integriert.
- Genau **ein** Provider ist pro Lauf aktiv ausschließlich über Konfiguration ausgewählt.
- **Kein** automatischer Fallback, **keine** Parallelnutzung, **keine** Profilverwaltung.
- Der fachliche KI-Vertrag (`NamingProposal` aus Application-/Domain-Sicht) bleibt unverändert.
- Bestehende Properties-Dateien aus dem Vorgängerstand werden beim ersten Start kontrolliert in das neue Schema migriert; vorher wird automatisch eine `.bak`-Sicherung angelegt.
- Architekturgrenzen, Persistenzmodell, Statussemantik, Retry-Semantik, Exit-Code-Verhalten und Logging-Mindestumfang bleiben unverändert; sie werden ausschließlich um den Provider-Identifikator und die Provider-Auswahl ergänzt.
## Statussemantik ## Statussemantik
@@ -118,101 +158,38 @@ Der aktive Stand ist die Erweiterung **„Zusätzlicher KI-Provider Anthropic Cl
3. die Persistenz konsistent fortgeschrieben wurde. 3. die Persistenz konsistent fortgeschrieben wurde.
### Führende Quelle des Benennungsvorschlags (verbindlich) ### Führende Quelle des Benennungsvorschlags (verbindlich)
- Die führende Quelle für Datum, Datumsquelle, validierten Titel und Reasoning ist der **neueste Versuchshistorieneintrag mit Status `PROPOSAL_READY`**. - Die führende Quelle für Datum, Datumsquelle, validierten Titel und Reasoning ist der **neueste Versuchshistorieneintrag mit Status `PROPOSAL_READY`**
- Kein Rekonstruieren aus dem Dokument-Stammsatz. - Kein Rekonstruieren aus dem Dokument-Stammsatz
- Kein neuer KI-Aufruf, wenn bereits ein nutzbarer `PROPOSAL_READY`-Versuch vorliegt. - Kein neuer KI-Aufruf, wenn bereits ein nutzbarer `PROPOSAL_READY`-Versuch vorliegt
- Status `PROPOSAL_READY` ohne lesbaren konsistenten Proposal-Versuch = dokumentbezogener technischer Fehler. - Status `PROPOSAL_READY` ohne lesbaren konsistenten Proposal-Versuch = dokumentbezogener technischer Fehler
- Proposal-Versuch mit fachlich unbrauchbarem Titel oder Datum = inkonsistenter Persistenzzustand = dokumentbezogener technischer Fehler. - Inkonsistente Proposal-Zustände werden **nicht stillschweigend geheilt**, sondern als technische Dokumentfehler behandelt
- Inkonsistente Proposal-Zustände werden **nicht stillschweigend geheilt**, sondern als technische Dokumentfehler behandelt.
## Retry-Semantik ## Retry-Semantik
### Deterministische Inhaltsfehler ### Deterministische Inhaltsfehler
Deterministische Inhaltsfehler sind insbesondere:
- kein brauchbarer Text
- Seitenlimit überschritten
- fachlich unbrauchbarer oder generischer Titel
- vorhandenes, aber unbrauchbares KI-Datum
Regel:
- **erster** historisierter deterministischer Inhaltsfehler → `FAILED_RETRYABLE` - **erster** historisierter deterministischer Inhaltsfehler → `FAILED_RETRYABLE`
- **zweiter** historisierter deterministischer Inhaltsfehler → `FAILED_FINAL` - **zweiter** historisierter deterministischer Inhaltsfehler → `FAILED_FINAL`
### Transiente technische Fehler ### Transiente technische Fehler
- Transiente Fehler laufen über den Transientfehlerzähler im Dokument-Stammsatz. - Transiente Fehler laufen über den Transientfehlerzähler im Dokument-Stammsatz
- Sie bleiben retryable bis der konfigurierte Grenzwert `max.retries.transient` erreicht ist. - Retryable bis der konfigurierte Grenzwert `max.retries.transient` erreicht ist
- Der Fehlversuch, der den Grenzwert **erreicht**, finalisiert den Dokumentstatus zu `FAILED_FINAL`. - Der Fehlversuch, der den Grenzwert **erreicht**, finalisiert den Dokumentstatus zu `FAILED_FINAL`
- `max.retries.transient` = **Integer >= 1**; der Wert `0` ist ungültige Startkonfiguration. - `max.retries.transient` = **Integer >= 1**; der Wert `0` ist ungültige Startkonfiguration
- Die Klassifikation gilt provider-unabhängig: Technische Fehler aus dem aktiven KI-Provider werden in dieselbe transiente Kategorie eingeordnet wie bisher. Der inaktive Provider wird in keiner Fehlersituation als Backup verwendet.
### Technischer Sofort-Wiederholversuch ### Technischer Sofort-Wiederholversuch
- **Genau ein** zusätzlicher technischer Schreibversuch innerhalb desselben Dokumentlaufs. - **Genau ein** zusätzlicher technischer Schreibversuch innerhalb desselben Dokumentlaufs
- **Ausschließlich** für Fehler beim physischen Zielkopierpfad. - **Ausschließlich** für Fehler beim physischen Zielkopierpfad
- Kein erneuter KI-Aufruf, keine erneute Fachableitung. - Kein erneuter KI-Aufruf, keine erneute Fachableitung
- Zählt **nicht** zum laufübergreifenden Transientfehlerzähler. - Zählt **nicht** zum laufübergreifenden Transientfehlerzähler
- Liefert genau ein dokumentbezogenes Ergebnis für Persistenz und Statusfortschreibung.
### Skip-Semantik ## Exit-Codes (verbindlich)
- `SUCCESS` → in späteren Läufen `SKIPPED_ALREADY_PROCESSED` historisieren, keine Zähleränderung. - **`0`**: normale erfolgreiche Beendigung eines headless Laufs sowie für das reguläre Beenden der GUI
- `FAILED_FINAL` → in späteren Läufen `SKIPPED_FINAL_FAILURE` historisieren, keine Zähleränderung. - **`1`**: harte Start-, Bootstrap-, Verdrahtungs-, Konfigurations- oder Initialisierungsfehler, einschließlich ungültiger CLI-Verwendung, nicht existenter `--config`-Datei im headless Start und GUI-Startfehlern vor erfolgreicher Anzeige der Oberfläche
- `FAILED_RETRYABLE`, `READY_FOR_AI`, `PROPOSAL_READY` → verarbeitbar. - Dokumentbezogene Verarbeitungsfehler im headless Lauf ändern dieses Exit-Code-Modell nicht
## Logging-Mindestumfang
Folgende Informationen müssen nachvollziehbar geloggt werden:
- Laufstart mit Lauf-ID
- aktiver KI-Provider für den Lauf
- Laufende
- erkannte Quelldatei
- Überspringen bereits erfolgreicher Dateien
- Überspringen final fehlgeschlagener Dateien
- erzeugter Zielname
- Retry-Entscheidung
- Fehler mit Klassifikation
### Korrelationsregel
- Vor erfolgreicher Fingerprint-Ermittlung: Korrelation über Lauf-ID und Kandidatenbezug.
- Nach erfolgreicher Fingerprint-Ermittlung: dokumentbezogene Logs enthalten den Fingerprint oder eine eindeutig ableitbare Referenz.
- Keine neue Persistenz-Wahrheit oder zusätzliche Tracking-Ebene.
### Sensibilitätsregel für KI-Inhalte
- Vollständige KI-Rohantwort: standardmäßig **nicht** ins Log, bleibt in SQLite.
- Vollständiges KI-`reasoning`: standardmäßig **nicht** ins Log, bleibt in SQLite.
- Freischaltung nur über expliziten booleschen Konfigurationswert.
- Default: sicher / nicht loggen.
- Die Sensibilitätsregel gilt provider-unabhängig.
## Verarbeitungsreihenfolge pro Dokument
1. Fingerprint berechnen
2. Dokument-Stammsatz laden
3. Terminale Skip-Fälle entscheiden (`SUCCESS``SKIPPED_ALREADY_PROCESSED`, `FAILED_FINAL``SKIPPED_FINAL_FAILURE`)
4. Falls nötig: Pfad bis `PROPOSAL_READY` durchlaufen (inkl. KI-Aufruf über den aktiven Provider)
5. Führenden `PROPOSAL_READY`-Versuch laden
6. Finalen Basis-Dateinamen bilden
7. Dubletten-Suffix im Zielordner bestimmen
8. Zielkopie schreiben (temporäre Datei + finaler Move/Rename; bei Fehler: genau ein Sofort-Wiederholversuch)
9. Retry-Entscheidung ableiten
10. Neuen Versuch historisieren, Stammsatz konsistent fortschreiben
## Zielkopie-Semantik
- Kopie zunächst in temporäre Zieldatei im Zielkontext
- Finaler Move/Rename auf den geplanten Zieldateinamen
- Quelldatei bleibt **immer unverändert**
- Bei technischem Schreibfehler: genau ein Sofort-Wiederholversuch (nur Zielkopierpfad)
- Bei Persistenzfehler nach erfolgreicher Zielkopie: kein `SUCCESS` setzen, best-effort Rückbau der Zielkopie, Ergebnis bleibt dokumentbezogener technischer Fehler
## Fehlersemantik
- Technische Fehler → `FAILED_RETRYABLE`, Transientfehlerzähler +1
- Bei Erreichen von `max.retries.transient``FAILED_FINAL`
- Kein Abbruch des Batch-Laufs für andere Dokumente
- Keine neue finale Fehlerkategorie
- Vor-Fingerprint-Fehler werden **nicht** als SQLite-Versuch historisiert
- Provider-spezifische Fehlerausprägungen (HTTP-Fehler, Auth-Fehler, Antwort-Schema-Fehler) werden im jeweiligen Adapter klassifiziert und auf die bestehenden Fehlerkategorien abgebildet. Es entstehen keine neuen Fehlerklassen.
## Persistenz ## Persistenz
Zwei-Ebenen-Modell bleibt unverändert keine dritte Wahrheitsquelle. Zwei-Ebenen-Modell keine dritte Wahrheitsquelle.
**Dokument-Stammsatz** enthält u.a.: **Dokument-Stammsatz** enthält u.a.:
- letzten Zielpfad, letzten Zieldateinamen - letzten Zielpfad, letzten Zieldateinamen
@@ -224,18 +201,16 @@ Zwei-Ebenen-Modell bleibt unverändert keine dritte Wahrheitsquelle.
- Fehlerklasse, Fehlermeldung, Retryable-Flag - Fehlerklasse, Fehlermeldung, Retryable-Flag
- **Provider-Identifikator des aktiven KI-Providers für den Versuch** - **Provider-Identifikator des aktiven KI-Providers für den Versuch**
**Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben. **Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben. Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag.
Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag.
**Rückwärtsverträglichkeit:** Bestehende Datenbestände bleiben lesbar, fortschreibbar und korrekt interpretierbar. Schema-Erweiterungen sind additiv mit definierten Defaultwerten für historische Versuche ohne Provider-Identifikator. **Rückwärtsverträglichkeit:** Bestehende Datenbestände bleiben lesbar, fortschreibbar und korrekt interpretierbar.
## Naming-Regel (verbindlich für alle Arbeitspakete) ## Naming-Regel (verbindlich für alle Arbeitspakete)
In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder Arbeitspaket-Bezeichner erscheinen:
Arbeitspaket-Bezeichner erscheinen:
- Verboten: `M1`, `M2`, …, `M8` - Verboten: `M1`, `M2`, …, `M13`
- Verboten: `AP-001`, `AP-002`, … `AP-00x` - Verboten: `AP-001`, `AP-002`, … `AP-0xx`
- Verboten: Versionsbezeichner wie `V1.0`, `V1.1` in Code/JavaDoc - Verboten: Versionsbezeichner wie `V1.0`, `V1.1`, `V2.0` in Code/JavaDoc
Stattdessen werden **zeitlose technische Bezeichnungen** verwendet. Stattdessen werden **zeitlose technische Bezeichnungen** verwendet.
Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen berührt werden, sind zu ersetzen. Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen berührt werden, sind zu ersetzen.
@@ -248,13 +223,15 @@ Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen ber
- Vor Änderungen zuerst die betroffenen Dateien und Abhängigkeiten verstehen - Vor Änderungen zuerst die betroffenen Dateien und Abhängigkeiten verstehen
- **Keine Annahmen über Dateipfade.** Typen und Klassen werden per Suche nach Typname gefunden, nicht über vermutete Pfade. - **Keine Annahmen über Dateipfade.** Typen und Klassen werden per Suche nach Typname gefunden, nicht über vermutete Pfade.
- Keine Vermutungen: Bei echter Unklarheit oder Dokumentkonflikten knapp nachfragen oder den Konflikt benennen - Keine Vermutungen: Bei echter Unklarheit oder Dokumentkonflikten knapp nachfragen oder den Konflikt benennen
- Keine stillen Änderungen am bestehenden OpenAI-kompatiblen KI-Weg - Keine stillen Änderungen am bestehenden headless Batch-Betrieb
- GUI-Code darf den headless Pfad nicht unnötig früh initialisieren
## Definition of Done pro Arbeitspaket ## Definition of Done pro Arbeitspaket
Ein Arbeitspaket ist erst fertig, wenn: Ein Arbeitspaket ist erst fertig, wenn:
- der Zielumfang des aktuellen Arbeitspakets vollständig umgesetzt ist - der Zielumfang des aktuellen Arbeitspakets vollständig umgesetzt ist
- der Stand konsistent, fehlerfrei und buildbar ist - der Stand konsistent, fehlerfrei und buildbar ist
- Implementierung, Konfiguration, JavaDoc und Tests ergänzt sind, **soweit für den Stand sinnvoll** - Implementierung, Konfiguration, JavaDoc (inkl. `package-info.java` für neue Packages) und Tests ergänzt sind
- der JavaDoc-Standard für alle neu hinzugefügten oder substanziell geänderten öffentlichen Klassen und Methoden eingehalten wurde
- keine Inhalte späterer Arbeitspakete vorweggenommen wurden - keine Inhalte späterer Arbeitspakete vorweggenommen wurden
- der Zwischenstand in sich geschlossen und übergabefähig ist - der Zwischenstand in sich geschlossen und übergabefähig ist
@@ -274,8 +251,8 @@ Ein Arbeitspaket ist erst fertig, wenn:
## Qualitäts- und Prüfreihenfolge ## Qualitäts- und Prüfreihenfolge
- Nur den für das aktuelle Arbeitspaket nötigen Scope ändern - Nur den für das aktuelle Arbeitspaket nötigen Scope ändern
- Nach Änderungen den kleinsten sinnvollen Build-/Test-Umfang ausführen - Nach Änderungen den kleinsten sinnvollen Build-/Test-Umfang ausführen
- Build-Validierung vom Parent-Root: - Build-Validierung vom Parent-Root (Beispiel für vollständigen Reactor-Build ab V2.0):
`.\mvnw.cmd clean verify -pl pdf-umbenenner-domain,pdf-umbenenner-application,pdf-umbenenner-adapter-out,pdf-umbenenner-adapter-in-cli,pdf-umbenenner-bootstrap --also-make` `.\mvnw.cmd clean verify -pl pdf-umbenenner-domain,pdf-umbenenner-application,pdf-umbenenner-adapter-out,pdf-umbenenner-adapter-in-cli,pdf-umbenenner-adapter-in-gui,pdf-umbenenner-bootstrap --also-make`
- Schlägt der Build fehl: Fehler beheben, erneut bauen, erst dann weiter - Schlägt der Build fehl: Fehler beheben, erneut bauen, erst dann weiter
- Vor Abschluss sicherstellen, dass der relevante Maven-Reactor-Stand fehlerfrei ist - Vor Abschluss sicherstellen, dass der relevante Maven-Reactor-Stand fehlerfrei ist
- Fehler nicht kaschieren; Ursachen sauber beheben oder offen benennen - Fehler nicht kaschieren; Ursachen sauber beheben oder offen benennen
@@ -284,8 +261,6 @@ Ein Arbeitspaket ist erst fertig, wenn:
- Ungültige Startkonfiguration verhindert den Verarbeitungslauf und führt zu Exit-Code `1` - Ungültige Startkonfiguration verhindert den Verarbeitungslauf und führt zu Exit-Code `1`
- Eine ungültige oder fehlende Provider-Auswahl ist eine ungültige Startkonfiguration - Eine ungültige oder fehlende Provider-Auswahl ist eine ungültige Startkonfiguration
- Run-Lock verhindert parallele Instanzen; wenn bereits eine Instanz läuft, beendet sich die neue Instanz sofort - Run-Lock verhindert parallele Instanzen; wenn bereits eine Instanz läuft, beendet sich die neue Instanz sofort
- Exit-Code `0`: Lauf technisch ordnungsgemäß ausgeführt, auch wenn einzelne Dateien fachlich oder transient fehlgeschlagen sind
- Exit-Code `1`: harter Start-/Bootstrap-Fehler
- API-Schlüssel: pro Provider eine eigene Umgebungsvariable, Vorrang vor Properties derselben Provider-Familie. Schlüssel verschiedener Provider werden niemals vermischt. - API-Schlüssel: pro Provider eine eigene Umgebungsvariable, Vorrang vor Properties derselben Provider-Familie. Schlüssel verschiedener Provider werden niemals vermischt.
- Dokumentbezogene Fehler führen **nicht** zu Exit-Code `1` - Dokumentbezogene Fehler führen **nicht** zu Exit-Code `1`
@@ -294,7 +269,7 @@ Verbindlich zweckmäßige Parameter:
- `source.folder` Quellordner - `source.folder` Quellordner
- `target.folder` Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich) - `target.folder` Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich)
- `sqlite.file` SQLite-Datenbankdatei - `sqlite.file` SQLite-Datenbankdatei
- `ai.provider.active` aktiver KI-Provider (Pflicht; zulässige Werte sind die Bezeichner der unterstützten Provider-Familien) - `ai.provider.active` aktiver KI-Provider (Pflicht)
- `max.retries.transient` max. historisierte transiente Fehlversuche pro Fingerprint (**Integer >= 1**, `0` ist ungültig) - `max.retries.transient` max. historisierte transiente Fehlversuche pro Fingerprint (**Integer >= 1**, `0` ist ungültig)
- `max.pages` Seitenlimit - `max.pages` Seitenlimit
- `max.text.characters` maximale Zeichenzahl für KI-Eingabe - `max.text.characters` maximale Zeichenzahl für KI-Eingabe
@@ -303,13 +278,7 @@ Verbindlich zweckmäßige Parameter:
- `runtime.lock.file` Lock-Datei (optional) - `runtime.lock.file` Lock-Datei (optional)
- `log.directory` Log-Verzeichnis (optional) - `log.directory` Log-Verzeichnis (optional)
Pro Provider-Familie existiert ein eigener Parameter-Namensraum mit zweckmäßig: Pro Provider-Familie existiert ein eigener Parameter-Namensraum:
- Modellname
- API-Schlüssel (Umgebungsvariable hat Vorrang)
- Timeout
- Basis-URL (optional, wo betrieblich sinnvoll)
Konkretes Schema (zweckmäßig):
```properties ```properties
ai.provider.active=openai-compatible ai.provider.active=openai-compatible
@@ -326,21 +295,22 @@ ai.provider.claude.apiKey=...
``` ```
### Migration historischer Konfiguration ### Migration historischer Konfiguration
Bestehende Properties-Dateien des Vorgängerstands (mit flachen Schlüsseln wie `api.baseUrl`, `api.model`, `api.timeoutSeconds`, `api.key`) werden beim ersten Start erkannt und kontrolliert in das neue Schema überführt. Bestehende Properties-Dateien des Vorgängerstands (flache Schlüssel wie `api.baseUrl`, `api.model`, `api.timeoutSeconds`, `api.key`) werden beim ersten Start erkannt und kontrolliert in das neue Schema überführt.
Verbindlicher Ablauf: Verbindlicher Ablauf:
1. Legacy-Form erkennen 1. Legacy-Form erkennen
2. **`.bak`-Sicherung** der Originaldatei anlegen 2. **`.bak`-Sicherung** der Originaldatei anlegen
3. Inhalt in das neue Schema überführen 3. Inhalt in das neue Schema überführen (Legacy-Werte → Namensraum `openai-compatible`, `ai.provider.active=openai-compatible`)
- Legacy-Werte landen im Namensraum **`openai-compatible`**
- `ai.provider.active` wird auf `openai-compatible` gesetzt
4. Datei in-place schreiben 4. Datei in-place schreiben
5. Datei erneut laden und validieren 5. Datei erneut laden und validieren
6. Erst danach den normalen Lauf fortsetzen 6. Erst danach den normalen Lauf fortsetzen
Alte und neue Struktur sind **kein** dauerhaft gleichrangiges Endformat.
## Nicht-Ziele / Verbote ## Nicht-Ziele / Verbote
- kein manueller Verarbeitungslauf aus der GUI (erst V2.1+)
- kein DB-/Historien-Tab in der GUI (erst V2.x+)
- kein Kosten-Tracking (erst V2.x+)
- kein echter Mini-KI-Testaufruf mit fachlicher Antwortauswertung
- keine EXE, kein Installer
- kein Web-UI - kein Web-UI
- keine REST-API zur Bedienung - keine REST-API zur Bedienung
- keine OCR innerhalb der Java-Anwendung - keine OCR innerhalb der Java-Anwendung
@@ -352,12 +322,11 @@ Alte und neue Struktur sind **kein** dauerhaft gleichrangiges Endformat.
- **keine** automatische Fallback-Umschaltung zwischen KI-Providern - **keine** automatische Fallback-Umschaltung zwischen KI-Providern
- **keine** parallele Nutzung mehrerer KI-Provider in einem Lauf - **keine** parallele Nutzung mehrerer KI-Provider in einem Lauf
- **keine** Profilverwaltung mit mehreren Konfigurationen je Provider-Familie - **keine** Profilverwaltung mit mehreren Konfigurationen je Provider-Familie
- **keine** Provider-Familien jenseits der explizit unterstützten (OpenAI-kompatibel, Anthropic Messages API) - **keine** Provider-Familien jenseits der explizit unterstützten
- keine stillen Änderungen am bestehenden OpenAI-kompatiblen KI-Weg - kein neues Konfigurationsformat
- keine Änderung der fachlichen Kernverarbeitung des PDF-Umbenenners
- keine Änderung der bestehenden Status-, Retry- oder Persistenz-Wahrheit
- keine stillen Änderungen am bestehenden headless Batch-Betrieb
- kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads - kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads
- keine Reporting- oder Statistikfunktionen
- keine neue dritte Persistenz-Wahrheitsquelle für Retry-Entscheidungen
- keine neue Fachfunktionalität jenseits des definierten Zielbilds
- kein großflächiges Refactoring ohne nachweisbaren Defektbezug
- keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug - keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug
- keine Vermischung von API-Schlüsseln verschiedener Provider-Familien - kein großflächiges Refactoring ohne nachweisbaren Defektbezug