- AP-001: Betriebs- und Startdokumentation für GUI und headless konsolidiert (betrieb.md, README.md) - AP-002: Endbenutzer-Bedienanleitung gui-bedienanleitung.md angelegt (deskriptiv, 13 Kapitel, deutsch, Windows-Hinweise) - AP-003: Konfigurationsbeispiele docs/examples/application.properties und docs/examples/prompt.txt konsolidiert, konsistent mit Standardvorlage - AP-004: Regressionstests für headless Abwärtskompatibilität (JAR-Smoke-IT mit --config-Varianten und JavaFX-Freiheit) - AP-005: GUI-Smoke-Tests für V2.0-Kernumfang vervollständigt (Startup-Notice-Sichtbarkeit im Header) - AP-006: Build- und Packaging-Dokumentation im Abschnitt "Build und Packaging" in betrieb.md, README-Artefaktnamen korrigiert - AP-007: Integrierte Gesamtprüfung durchgeführt, V2.0-Abschnitt in befundliste.md — keine Release-Blocker, zwei nicht blockierende Restpunkte (R1 ByteBuddy-Warning, R2 fehlender visueller GUI-Render-Test) - AP-008: entfiel (keine Release-Blocker zu beheben) - AP-009: Finale Gesamtprüfung, Freigabedokument docs/freigabe-v2_0.md mit Git-HEAD, Build-/Test-Ergebnissen, Freigabeaussage. Ein während der Stichprobe entdeckter Doku-Defekt (R3: API-Key-Legacy-Variable) wurde unmittelbar in gui-bedienanleitung.md korrigiert. V2.0 ist freigabefähig. 1.403 Tests grün, 0 Failures, 0 Errors. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
19 KiB
Betriebsdokumentation – PDF Umbenenner
Zweck
Der PDF Umbenenner liest bereits OCR-verarbeitete, durchsuchbare PDF-Dateien aus einem konfigurierten Quellordner, ermittelt per KI-Aufruf einen normierten deutschen Dateinamen und legt eine Kopie im konfigurierten Zielordner ab. Die Quelldatei bleibt unverändert.
Startmodi und Betriebsmodell (V2.0)
Ab V2.0 enthält die Anwendung zwei Startmodi in einem gemeinsamen ausführbaren JAR:
| Startmodus | Beschreibung |
|---|---|
| GUI-Start (Standard) | Öffnet die JavaFX-Desktop-GUI. Wird verwendet, wenn kein --headless angegeben ist. |
| headless Betrieb | Klassischer Batch-/Scheduler-Betrieb ohne grafische Oberfläche. Wird über --headless aktiviert. |
CLI-Optionen
| Option | Beschreibung |
|---|---|
| (keine Argumente) | GUI-Standardstart |
--headless |
Aktiviert den headless Batch-Betrieb (wie vor V2.0) |
--config <pfad> |
Zeigt explizit auf eine .properties-Konfigurationsdatei (für GUI und headless) |
--config und --headless können kombiniert werden:
java -jar pdf-umbenenner-bootstrap-*.jar --headless --config C:\Pfad\zur\config.properties
Verhalten bei fehlender oder ungültiger --config-Datei
| Startmodus | Datei nicht vorhanden | Datei vorhanden, aber ungültig |
|---|---|---|
| headless | Harter Startfehler, Exit-Code 1, kein Fallback |
Harter Startfehler, Exit-Code 1 |
| GUI | Fehlermeldung in der GUI, danach Verhalten wie ohne --config (Willkommenstext) |
Fehlermeldung in der GUI, Konfiguration nicht geladen |
Im headless Betrieb ist ein nicht vorhandener --config-Pfad ein harter Startfehler. Ein stiller
Fallback auf das Default-Verhalten ist in diesem Fall ausdrücklich unzulässig.
Verhalten bei GUI-Startfehlern
Tritt vor der erfolgreichen Anzeige der grafischen Oberfläche ein nicht behebbarer Fehler auf
(z. B. fehlende JavaFX-Laufzeit, Bootstrap-Fehler), beendet sich die Anwendung mit Exit-Code 1.
Plattform und Laufwerksbuchstaben
Die GUI wird offiziell nur unter Windows unterstützt. Der headless Betrieb bleibt für den Windows Server-Betrieb geeignet.
Gemappte Netzlaufwerke wie S:\ oder H:\ werden ausdrücklich unterstützt. Eine Ablehnung
solcher Pfade allein wegen eines dahinterliegenden UNC-Pfads ist unzulässig.
Umfang der V2.0-GUI
Die GUI in V2.0 dient ausschließlich als:
- Konfigurationseditor für die
.properties-Datei - Validierungsoberfläche (automatische und explizite Prüfung des Konfigurationsstands)
- Technische Testoberfläche (Erreichbarkeit des Providers, Pfade, SQLite-Datei, Prompt-Datei)
Die GUI enthält in V2.0 keinen manuellen Verarbeitungslauf. Das Starten eines Batch-Laufs aus der GUI ist erst ab V2.1+ vorgesehen. Der headless Betrieb über den Windows Task Scheduler bleibt der einzige Weg, PDF-Dateien automatisiert zu verarbeiten.
Voraussetzungen
- Java 21 (JRE oder JDK)
- Zugang zu einem KI-Dienst (API-Schlüssel erforderlich; unterstützte Provider: OpenAI-kompatibel, Anthropic Claude)
- Quellordner mit OCR-verarbeiteten PDF-Dateien
- Schreibzugriff auf Zielordner und Datenbankverzeichnis
Start des ausführbaren JAR
Das ausführbare JAR wird durch den Maven-Build im Verzeichnis
pdf-umbenenner-bootstrap/target/ erzeugt:
java -jar pdf-umbenenner-bootstrap/target/pdf-umbenenner-bootstrap-0.0.1-SNAPSHOT.jar
Ohne weitere Argumente öffnet sich die GUI (Standardstart ab V2.0).
Für den headless Betrieb (Batch-/Scheduler-Start):
java -jar pdf-umbenenner-bootstrap/target/pdf-umbenenner-bootstrap-0.0.1-SNAPSHOT.jar --headless
Die Anwendung liest die Konfiguration standardmäßig aus config/application.properties relativ zum
Arbeitsverzeichnis, in dem der Befehl ausgeführt wird.
Start über Windows Task Scheduler
Empfohlene Startsequenz für den headless Betrieb über den Windows Task Scheduler:
- Aktion: Programm/Skript starten
- Programm:
java - Argumente:
-jar C:\Pfad\zur\Installation\pdf-umbenenner-bootstrap\target\pdf-umbenenner-bootstrap-0.0.1-SNAPSHOT.jar --headless - Starten in:
C:\Pfad\zur\Installation(muss das Verzeichnis mitconfig\application.propertiesundconfig\prompts\enthalten)
Hinweis: Das „Starten in"-Verzeichnis ist das Arbeitsverzeichnis der Anwendung. Die Konfigurationsdatei
config/application.propertiessowie das Prompt-Verzeichnisconfig/prompts/müssen relativ zu diesem Verzeichnis erreichbar sein. Der JAR-Pfad in den Argumenten muss absolut oder relativ zum Starten-in-Verzeichnis korrekt angegeben sein.
Alternativ kann über --config ein expliziter Konfigurationspfad angegeben werden:
java -jar ... --headless --config S:\Betrieb\meine-config.properties
Wichtig: Zeigt
--configauf eine nicht vorhandene Datei, bricht die Anwendung mit Exit-Code1ab. Es findet kein stiller Fallback aufconfig/application.propertiesstatt.
Konfiguration
Die Konfiguration wird aus config/application.properties geladen.
Ein vollständiges Konfigurationsbeispiel mit allen unterstützten Parametern, realistischen Windows-Pfaden und erklärenden Kommentaren liegt unter:
Vorlagen für lokale und Test-Konfigurationen befinden sich in:
config/application-local.example.propertiesconfig/application-test.example.properties
Pflichtparameter (allgemein)
| Parameter | Beschreibung |
|---|---|
source.folder |
Quellordner mit OCR-PDFs (muss vorhanden und lesbar sein) |
target.folder |
Zielordner für umbenannte Kopien (wird angelegt, wenn nicht vorhanden) |
sqlite.file |
SQLite-Datenbankdatei (übergeordnetes Verzeichnis muss existieren) |
ai.provider.active |
Aktiver KI-Provider: openai-compatible oder claude |
max.retries.transient |
Maximale transiente Fehlversuche pro Dokument (ganzzahlig, >= 1) |
max.pages |
Maximale Seitenzahl pro Dokument (ganzzahlig, > 0) |
max.text.characters |
Maximale Zeichenanzahl des Dokumenttexts für KI-Anfragen (ganzzahlig, > 0) |
prompt.template.file |
Pfad zur externen Prompt-Datei (muss vorhanden sein) |
Provider-Parameter
Nur der aktive Provider muss vollständig konfiguriert sein. Der inaktive Provider wird nicht validiert.
OpenAI-kompatibler Provider (ai.provider.active=openai-compatible):
| Parameter | Beschreibung |
|---|---|
ai.provider.openai-compatible.baseUrl |
Basis-URL des KI-Dienstes (z. B. https://api.openai.com/v1) |
ai.provider.openai-compatible.model |
Modellname (z. B. gpt-4o-mini) |
ai.provider.openai-compatible.timeoutSeconds |
HTTP-Timeout in Sekunden (ganzzahlig, > 0) |
ai.provider.openai-compatible.apiKey |
API-Schlüssel (Umgebungsvariable OPENAI_COMPATIBLE_API_KEY hat Vorrang) |
Anthropic Claude-Provider (ai.provider.active=claude):
| Parameter | Beschreibung |
|---|---|
ai.provider.claude.baseUrl |
Basis-URL (optional; Standard: https://api.anthropic.com) |
ai.provider.claude.model |
Modellname (z. B. claude-3-5-sonnet-20241022) |
ai.provider.claude.timeoutSeconds |
HTTP-Timeout in Sekunden (ganzzahlig, > 0) |
ai.provider.claude.apiKey |
API-Schlüssel (Umgebungsvariable ANTHROPIC_API_KEY hat Vorrang) |
Optionale Parameter
| Parameter | Beschreibung | Standard |
|---|---|---|
runtime.lock.file |
Lock-Datei für Startschutz | pdf-umbenenner.lock im Arbeitsverzeichnis |
log.directory |
Log-Verzeichnis | ./logs/ |
log.level |
Log-Level (DEBUG, INFO, WARN, ERROR) |
INFO |
log.ai.sensitive |
KI-Rohantwort und Reasoning ins Log schreiben (true/false) |
false |
API-Schlüssel
Pro Provider-Familie existiert eine eigene Umgebungsvariable, die Vorrang vor dem Properties-Wert hat:
| Provider | Umgebungsvariable |
|---|---|
openai-compatible |
OPENAI_COMPATIBLE_API_KEY |
claude |
ANTHROPIC_API_KEY |
Schlüssel verschiedener Provider-Familien werden niemals vermischt.
Migration älterer Konfigurationsdateien
Ältere Konfigurationsdateien, die noch die flachen Schlüssel api.baseUrl, api.model,
api.timeoutSeconds und api.key verwenden, werden beim ersten Start automatisch
in das aktuelle Schema überführt.
Was passiert
- Die Anwendung erkennt die veraltete Form anhand der flachen
api.*-Schlüssel. - Vor jeder Änderung wird eine Sicherungskopie der Originaldatei angelegt:
- Standardfall:
config/application.properties.bak - Falls
.bakbereits existiert:config/application.properties.bak.1,.bak.2, … - Bestehende Sicherungen werden niemals überschrieben.
- Standardfall:
- Die Datei wird in-place in das neue Schema überführt:
api.baseUrl→ai.provider.openai-compatible.baseUrlapi.model→ai.provider.openai-compatible.modelapi.timeoutSeconds→ai.provider.openai-compatible.timeoutSecondsapi.key→ai.provider.openai-compatible.apiKeyai.provider.active=openai-compatiblewird ergänzt.- Alle übrigen Schlüssel bleiben unverändert.
- Die migrierte Datei wird über eine temporäre Datei (
*.tmp) und atomischen Move/Rename geschrieben. Das Original wird niemals teilbeschrieben. - Die migrierte Datei wird sofort neu eingelesen und validiert.
Bei Migrationsfehler
Schlägt die Validierung der migrierten Datei fehl, bricht die Anwendung mit Exit-Code 1 ab.
Die Sicherungskopie (.bak) bleibt in diesem Fall erhalten und enthält die unveränderte
Originaldatei. Die Konfiguration muss dann manuell korrigiert werden.
Betreiber-Hinweis
Die Umgebungsvariable PDF_UMBENENNER_API_KEY des Vorgängerstands wird nicht automatisch
umbenannt. Falls dieser Wert bislang verwendet wurde, muss er auf OPENAI_COMPATIBLE_API_KEY
umgestellt werden.
Prompt-Konfiguration
Der Prompt wird aus der in prompt.template.file konfigurierten externen Textdatei geladen.
Der Dateiname der Prompt-Datei dient als Prompt-Identifikator in der Versuchshistorie
(SQLite) und ermöglicht so die Nachvollziehbarkeit, welche Prompt-Version für welchen
Verarbeitungsversuch verwendet wurde.
Eine angepasste Vorlage befindet sich in config/prompts/template.txt und kann direkt
verwendet oder an den jeweiligen KI-Dienst angepasst werden.
Fehlt die konfigurierte Prompt-Datei, erzeugt die GUI beim Ausführen der technischen Tests
automatisch eine deutsche Standardvorlage am konfigurierten Pfad. Ein Beispiel dieser
Standardvorlage liegt unter docs/examples/prompt.txt.
Die Anwendung ergänzt den Prompt automatisch um:
- einen Dokumenttext-Abschnitt
- eine explizite JSON-Antwortspezifikation mit den Feldern
title,reasoningunddate
Zielformat
Jede erfolgreich verarbeitete PDF-Datei wird im Zielordner unter folgendem Namen abgelegt:
YYYY-MM-DD - Titel.pdf
Bei Namenskollisionen wird ein laufendes Suffix angehängt:
YYYY-MM-DD - Titel(1).pdf
YYYY-MM-DD - Titel(2).pdf
Das Suffix zählt nicht zu den 20 Zeichen des Basistitels.
Retry- und Skip-Verhalten
Dokumentstatus
Die folgende Tabelle beschreibt die persistenten Statuszustände der Dokument-Stammsätze in der SQLite-Datenbank. Diese Zustände sind nach Abschluss eines Verarbeitungsversuchs dauerhaft gespeichert.
| Status | Bedeutung |
|---|---|
READY_FOR_AI |
Verarbeitbar, KI-Pfad noch nicht durchlaufen |
PROPOSAL_READY |
KI-Benennungsvorschlag liegt vor, Zielkopie noch nicht geschrieben |
SUCCESS |
Erfolgreich verarbeitet und kopiert (terminaler Endzustand) |
FAILED_RETRYABLE |
Fehlgeschlagen, erneuter Versuch in späterem Lauf möglich |
FAILED_FINAL |
Terminal fehlgeschlagen, wird nicht erneut verarbeitet |
SKIPPED_ALREADY_PROCESSED |
Übersprungen – Dokument bereits erfolgreich verarbeitet |
SKIPPED_FINAL_FAILURE |
Übersprungen – Dokument terminal fehlgeschlagen |
Zusätzlich kennt das System den transienten Zustand PROCESSING, der während der aktiven
Verarbeitung eines Dokuments im Stammsatz gesetzt werden kann. Er wird nach Abschluss des
Verarbeitungsversuchs stets durch einen der obigen Zustände ersetzt und ist kein gültiger
Endstatus in der Datenbank.
Retry-Regeln
Deterministische Inhaltsfehler (z. B. kein extrahierbarer Text, Seitenlimit überschritten, unbrauchbarer KI-Titel):
- Erster Fehler →
FAILED_RETRYABLE(ein Wiederholversuch in späterem Lauf erlaubt) - Zweiter Fehler →
FAILED_FINAL(kein weiterer Versuch)
Transiente technische Fehler (z. B. KI nicht erreichbar, HTTP-Timeout):
- Wiederholbar bis zum Grenzwert
max.retries.transient - Bei Erreichen des Grenzwerts →
FAILED_FINAL
Technischer Sofort-Wiederholversuch:
Bei einem Schreibfehler der Zielkopie wird innerhalb desselben Laufs exakt ein Sofort-Wiederholversuch unternommen. Dieser zählt nicht zum laufübergreifenden Fehlerzähler.
Logging
Logs werden in das konfigurierte log.directory geschrieben (Standard: ./logs/).
Log-Rotation erfolgt täglich und bei Erreichen von 10 MB je Datei.
Sensible KI-Inhalte
Standardmäßig werden die vollständige KI-Rohantwort und das KI-Reasoning nicht ins Log geschrieben, sondern ausschließlich in der SQLite-Datenbank gespeichert.
Die Ausgabe kann für Diagnosezwecke mit log.ai.sensitive=true freigeschaltet werden.
Erlaubte Werte: true oder false. Jeder andere Wert ist ungültig und verhindert den Start.
Exit-Codes
| Code | Bedeutung |
|---|---|
0 |
Lauf technisch ordnungsgemäß ausgeführt (auch bei dokumentbezogenen Teilfehlern) |
1 |
Harter Start- oder Bootstrap-Fehler (ungültige Konfiguration, Lock nicht erwerbbar, Schema-Initialisierungsfehler) |
Dokumentbezogene Fehler einzelner PDF-Dateien führen nicht zu Exit-Code 1.
Startschutz (Parallelinstanzschutz)
Die Anwendung verwendet eine exklusive Lock-Datei, um parallele Instanzen zu verhindern.
Wenn bereits eine Instanz läuft, beendet sich die neue Instanz sofort mit Exit-Code 1.
Der Pfad der Lock-Datei ist über runtime.lock.file konfigurierbar.
Ohne Konfiguration wird pdf-umbenenner.lock im Arbeitsverzeichnis verwendet.
SQLite-Datenbank
Die SQLite-Datei enthält:
- Dokument-Stammsätze: Gesamtstatus, Fehlerzähler, letzter Zieldateiname, Zeitstempel
- Versuchshistorie: Jeder Verarbeitungsversuch mit Modell, Prompt-Identifikator, KI-Rohantwort, Reasoning, Datum, Titel und Fehlerstatus
Die Datenbank ist die führende Wahrheitsquelle für Bearbeitungsstatus und Nachvollziehbarkeit. Sie muss nicht manuell verwaltet werden – das Schema wird beim Start automatisch initialisiert.
Build und Packaging
Gemeinsames ausführbares JAR
Die gesamte Anwendung wird als ein einziges ausführbares JAR ausgeliefert, das GUI-Start und headless Batch-Betrieb vereint. Eine separate JavaFX-Installation ist nicht erforderlich.
Das JAR wird vom Maven-Shade-Plugin im Modul pdf-umbenenner-bootstrap erzeugt.
Nach einem erfolgreichen Build liegt es unter:
pdf-umbenenner-bootstrap/target/pdf-umbenenner-bootstrap-0.0.1-SNAPSHOT.jar
Dieses JAR enthält alle Abhängigkeiten inklusive der JavaFX-Plattformbibliotheken
für Windows (Classifier win). Die nativen JavaFX-DLLs werden beim GUI-Start
von JavaFX selbst in ein temporäres Verzeichnis extrahiert.
Integrierte JavaFX-Laufzeit
JavaFX ist als Maven-Dependency im Modul pdf-umbenenner-adapter-in-gui mit
Windows-Classifier deklariert (javafx-base:win, javafx-graphics:win,
javafx-controls:win). Das Shade-JAR schließt diese Bibliotheken ein, sodass
der GUI-Start ohne separate JavaFX-Installation auf dem Zielsystem funktioniert.
Nur das Modul pdf-umbenenner-adapter-in-gui hängt direkt von JavaFX ab.
Die Module domain, application, adapter-in-cli und adapter-out sind
vollständig JavaFX-frei.
Headless-Start ohne JavaFX-Initialisierung
Beim headless Start (--headless) wird JavaFX nicht initialisiert. Der
GuiAdapter wird nur dann instanziiert und gestartet, wenn der Startmodus GUI ist.
JavaFX-Klassen sind zwar im Shade-JAR enthalten, werden im headless Pfad jedoch
nicht geladen. Headless läuft damit auch auf Windows Server-Systemen ohne
JavaFX-fähige Grafiklaufzeit.
Keine EXE, kein Installer
In V2.0 wird ausschließlich das JAR als Distributionsartefakt ausgeliefert. EXE-Wrapper und Installer sind bewusst nicht Bestandteil von V2.0.
Build-Kommandos
Vollständiger Reactor-Build (alle Module, Tests, Packaging):
.\mvnw.cmd clean verify
Auf Unix-Systemen (headless CI):
./mvnw clean verify
Nur das ausführbare JAR erzeugen (überspringt Tests):
.\mvnw.cmd clean package -pl pdf-umbenenner-bootstrap --also-make -DskipTests
Selektiver Reactor-Build (ohne Coverage-Modul, z. B. während der Entwicklung):
.\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
Technische Hinweise zum Shade-JAR
- Signaturdateien (
*.SF,*.DSA,*.RSA) signierter JARs (u. a. JavaFX) werden beim Shading entfernt, da sie im zusammengeführten JAR ungültig wären. - JPMS-Moduldeskriptoren (
module-info.class) werden entfernt, da JavaFX als modulares Framework mit dem nicht-modularen Fat-JAR-Modell kollidieren würde. META-INF/services-Einträge aus allen Abhängigkeiten werden durch denServicesResourceTransformerzusammengeführt statt überschrieben.- Der Main-Class-Eintrag im Manifest verweist auf
de.gecheckt.pdf.umbenenner.bootstrap.PdfUmbenennerApplication. Diese Klasse erweitert bewusst nichtjavafx.application.Application, um den JavaFX-Modul-System-Launcher-Check zu umgehen, der Fat-JAR-Ausführung blockieren würde. Der GUI-Pfad ruftApplication.launch(...)explizit auf.
Weitere Dokumentation
Die Bedienung der GUI ist in gui-bedienanleitung.md beschrieben.
Systemgrenzen
- Nur OCR-verarbeitete, durchsuchbare PDF-Dateien werden verarbeitet
- Keine eingebaute OCR-Funktion
- Kein Web-UI, keine REST-API
- Die GUI (V2.0) dient der Konfiguration, Validierung und technischen Diagnose – kein manueller Verarbeitungslauf aus der GUI
- Kein interner Scheduler – der Batch-Betrieb wird extern angestoßen (z. B. Windows Task Scheduler,
--headless) - Quelldateien werden nie überschrieben, verschoben oder gelöscht
- Die Identifikation erfolgt über SHA-256-Fingerprint des Dateiinhalts, nicht über Dateinamen
- Die GUI wird offiziell nur unter Windows unterstützt; der headless Betrieb ist für Windows Server geeignet