51d6168697
- addModules-Liste per jdeps aktualisiert: java.prefs und jdk.unsupported.desktop
neu hinzugefuegt; java.desktop, java.logging und java.xml manuell beibehalten
(reflektiv genutzt, von jdeps --ignore-missing-deps nicht erkannt)
- jdeps-Ausgabe in pdf-umbenenner-packaging/jdeps-output.txt dokumentiert
- winUpgradeUuid gesetzt (EA8D0149-1401-4D3D-A98D-A2B98DAE5495); darf nie geaendert werden
- BAT-Dateien korrigiert: referenzieren nun %~dp0PDF-KI-Renamer.exe (kein Unterverzeichnis),
passend zur appContent-Einbettung ins Installationsverzeichnis
- BAT-Dateien via appContent in den MSI-Installer eingebettet
- winShortcut=true und winShortcutPrompt=false bestaetigt (waren bereits korrekt)
- app.version=${revision} bestaetigt (war bereits korrekt nach #67)
- betrieb.md: MSI-Release-Checkliste und Pfad-Empfehlung fuer sqlite.file ergaenzt
- README-icon.md: Ist-Stand dokumentiert (icon.ico ca. 127 KB, kein Platzhalter)
- Offener Punkt fuer Marcus: Laufzeit-Verifikation ohne JDK nach manuellem MSI-Build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
683 lines
30 KiB
Markdown
683 lines
30 KiB
Markdown
# 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.
|
||
|
||
### Startverhalten der GUI
|
||
|
||
Die GUI startet **maximiert** (Vollbild). Beim Start wird die zuletzt geladene
|
||
Konfigurationsdatei automatisch geladen. Der Pfad wird in den Windows-Benutzereinstellungen
|
||
gespeichert (`java.util.prefs.Preferences`). Existiert die Datei beim nächsten Start nicht
|
||
mehr, startet die GUI ohne Fehlermeldung mit dem Willkommenstext.
|
||
|
||
### Umfang der GUI
|
||
|
||
Die GUI enthält drei Tabs:
|
||
|
||
- **Tab „Konfiguration"** – Editor, Validierungs- und technische Testoberfläche für
|
||
die `.properties`-Datei (Erreichbarkeit des Providers, Pfade, SQLite-Datei,
|
||
Prompt-Datei).
|
||
- **Tab „Verarbeitungslauf"** – Start eines Batch-Laufs aus der GUI mit
|
||
Live-Fortschritt, Ergebnisliste und KI-Begründung je Dokument. Pro Zeile ist eine
|
||
**integrierte PDF-Vorschau** der Quelldatei sowie ein **editierbarer Dateiname-Bereich**
|
||
verfügbar. Der Lauf verwendet den zuletzt gespeicherten Stand der `.properties`-Datei;
|
||
ungespeicherte Änderungen im Editor fließen nicht in den Lauf ein. Ein **Soft-Stop**
|
||
über den Abbrechen-Knopf beendet den Lauf nach Abschluss der gerade bearbeiteten Datei.
|
||
Während eines laufenden Batches ist Tab 1 gesperrt; ein Hinweis weist darauf hin.
|
||
- **Tab „Prompt"** – Lädt, bearbeitet und speichert die konfigurierte Prompt-Datei direkt
|
||
aus der Oberfläche. Bearbeitungen erzeugen einen Dirty-State (Asterisk im Tab-Titel).
|
||
Speichern erfolgt **atomar** (Temp-Datei im selben Verzeichnis + `ATOMIC_MOVE`).
|
||
Ein „Auf Standard zurücksetzen"-Button befüllt die TextArea mit der Standard-Vorlage,
|
||
ohne zu speichern. Fehlt die Prompt-Datei am konfigurierten Pfad, wird ein
|
||
„Standard-Prompt erstellen"-Button angezeigt. Der Tab wird beim ersten Öffnen automatisch
|
||
geladen. Tab-Wechsel mit ungespeicherten Änderungen löst einen Bestätigungsdialog aus.
|
||
|
||
Der headless Betrieb über den Windows Task Scheduler bleibt unverändert bestehen und
|
||
kann weiterhin für automatisierte Läufe genutzt werden. Pro Anwendungsinstanz ist genau
|
||
ein Verarbeitungslauf gleichzeitig zulässig; ein gleichzeitiger externer headless Lauf
|
||
wird jedoch nicht technisch erkannt oder blockiert.
|
||
|
||
---
|
||
|
||
## Voraussetzungen
|
||
|
||
- 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
|
||
|
||
### Java-Laufzeitumgebung
|
||
|
||
- Bei Verwendung des **Shade-JAR** direkt: **Java 21 JRE** auf dem Zielsystem erforderlich.
|
||
- Bei Verwendung des **Windows-Installers (V3.0)**: **keine** separate Java-Installation notwendig –
|
||
die JRE 21 ist in der installierten Anwendung eingebettet.
|
||
|
||
---
|
||
|
||
## 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.
|
||
|
||
### Konsolen-Encoding unter Windows
|
||
|
||
Die Anwendung schreibt alle Log-Ausgaben in UTF-8. Windows-Konsolen (PowerShell, CMD) verwenden
|
||
standardmäßig den OEM-Codepage (z. B. CP850), was zu unlesbaren Sonderzeichen führt.
|
||
|
||
**Lösung:** Konsole vor dem Start auf UTF-8 umschalten:
|
||
|
||
```
|
||
chcp 65001
|
||
java -jar pdf-umbenenner-bootstrap-*.jar --headless
|
||
```
|
||
|
||
Alternativ kann die UTF-8-Ausgabe auch als JVM-Argument angegeben werden (Java 17+):
|
||
|
||
```
|
||
java -Dstdout.encoding=UTF-8 -jar pdf-umbenenner-bootstrap-*.jar --headless
|
||
```
|
||
|
||
> **Hinweis:** Die mitgelieferten Batch-Dateien (`PDF-KI-Renamer.bat`, `PDF-KI-Renamer-GUI.bat`)
|
||
> rufen `chcp 65001` automatisch auf. Der Windows Task Scheduler schreibt Log-Ausgaben in eine
|
||
> Protokolldatei, die stets UTF-8-kodiert ist – dort entsteht kein Anzeigeproblem.
|
||
|
||
### Start über Windows Task Scheduler
|
||
|
||
Empfohlene Startsequenz für den headless Betrieb über den Windows Task Scheduler:
|
||
|
||
1. Aktion: Programm/Skript starten
|
||
2. Programm: `java`
|
||
3. Argumente: `-jar C:\Pfad\zur\Installation\pdf-umbenenner-bootstrap\target\pdf-umbenenner-bootstrap-0.0.1-SNAPSHOT.jar --headless`
|
||
4. Starten in: `C:\Pfad\zur\Installation` (muss das Verzeichnis mit `config\application.properties` und `config\prompts\` enthalten)
|
||
|
||
> **Hinweis:** Das „Starten in"-Verzeichnis ist das Arbeitsverzeichnis der Anwendung.
|
||
> Die Konfigurationsdatei `config/application.properties` sowie das Prompt-Verzeichnis
|
||
> `config/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 `--config` auf eine nicht vorhandene Datei, bricht die Anwendung mit Exit-Code `1` ab.
|
||
> Es findet kein stiller Fallback auf `config/application.properties` statt.
|
||
|
||
---
|
||
|
||
## 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:
|
||
|
||
- [`docs/examples/application.properties`](examples/application.properties)
|
||
|
||
Vorlagen für lokale und Test-Konfigurationen befinden sich in:
|
||
|
||
- `config/application-local.example.properties`
|
||
- `config/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) |
|
||
| `max.title.length` | Maximale Länge des Basistitels in Zeichen (ganzzahlig, 10..120, Default 60). Werte unter 10 oder über 120 verhindern den Start. Werte 10–39 und 100–120 erzeugen eine Startwarnung. |
|
||
| `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
|
||
|
||
1. Die Anwendung erkennt die veraltete Form anhand der flachen `api.*`-Schlüssel.
|
||
2. **Vor jeder Änderung** wird eine Sicherungskopie der Originaldatei angelegt:
|
||
- Standardfall: `config/application.properties.bak`
|
||
- Falls `.bak` bereits existiert: `config/application.properties.bak.1`, `.bak.2`, …
|
||
- Bestehende Sicherungen werden **niemals überschrieben**.
|
||
3. Die Datei wird in-place in das neue Schema überführt:
|
||
- `api.baseUrl` → `ai.provider.openai-compatible.baseUrl`
|
||
- `api.model` → `ai.provider.openai-compatible.model`
|
||
- `api.timeoutSeconds` → `ai.provider.openai-compatible.timeoutSeconds`
|
||
- `api.key` → `ai.provider.openai-compatible.apiKey`
|
||
- `ai.provider.active=openai-compatible` wird ergänzt.
|
||
- Alle übrigen Schlüssel bleiben unverändert.
|
||
4. Die migrierte Datei wird über eine temporäre Datei (`*.tmp`) und atomischen
|
||
Move/Rename geschrieben. Das Original wird niemals teilbeschrieben.
|
||
5. 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`](examples/prompt.txt).
|
||
|
||
Die Anwendung ergänzt den Prompt automatisch um:
|
||
- einen Dokumenttext-Abschnitt
|
||
- eine explizite JSON-Antwortspezifikation mit den Feldern `title`, `reasoning` und `date`
|
||
|
||
### Prompt-Pfad-Auflösung je Betriebsart
|
||
|
||
Der Wert von `prompt.template.file` wird **relativ zum Arbeitsverzeichnis** aufgelöst,
|
||
wenn kein absoluter Pfad angegeben ist. Das Arbeitsverzeichnis hängt von der Betriebsart ab:
|
||
|
||
| Betriebsart | Arbeitsverzeichnis | Empfohlener Wert |
|
||
|---|---|---|
|
||
| **IDE** | Projekt-Wurzelverzeichnis (in der Regel das Parent-POM-Verzeichnis) | `config/prompts/template.txt` |
|
||
| **Shade-JAR direkt** | Verzeichnis, aus dem `java -jar ...` aufgerufen wird | `config/prompts/template.txt` |
|
||
| **Windows Task Scheduler** | „Starten in"-Feld der Task-Konfiguration | absoluter Pfad empfohlen, z. B. `C:\Betrieb\config\prompts\template.txt` |
|
||
| **Windows-Installer (MSI)** | Installationsverzeichnis | absoluter Pfad empfohlen |
|
||
|
||
> **Empfehlung für den Windows-Produktivbetrieb:** Verwenden Sie einen **absoluten Pfad**
|
||
> für `prompt.template.file`. Damit ist die Prompt-Datei unabhängig vom Arbeitsverzeichnis
|
||
> immer eindeutig auffindbar – insbesondere beim Start über den Windows Task Scheduler,
|
||
> wo das Arbeitsverzeichnis je nach Konfiguration variieren kann.
|
||
|
||
### Bearbeitung über den GUI-Prompt-Tab
|
||
|
||
Im GUI-Tab „Prompt" kann die Prompt-Datei ohne externen Editor gelesen, bearbeitet und
|
||
gespeichert werden. Das Speichern erfolgt atomar; ein Rollback schlägt nur fehl, wenn
|
||
das Dateisystem kein atomisches Verschieben im selben Verzeichnis unterstützt (in diesem
|
||
Fall wird kein stiller Fallback durchgeführt).
|
||
|
||
Der Tab zeigt stets die Datei an, die beim GUI-Start als `prompt.template.file` konfiguriert
|
||
war. Wird während der GUI-Session eine andere `.properties`-Datei geöffnet (Tab „Konfiguration"),
|
||
aktualisiert sich der Prompt-Tab nicht automatisch – in diesem Fall sollte die GUI neu gestartet
|
||
oder der Prompt-Tab durch erneutes Auswählen manuell neu geladen werden.
|
||
|
||
---
|
||
|
||
## 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 zur konfigurierten maximalen Titellänge 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.
|
||
|
||
### Windows-Installer (V3.0)
|
||
|
||
Ab V3.0 steht neben dem Shade-JAR ein vollwertiger **MSI-Installer** für Windows 10/11 (x64)
|
||
und Windows Server 2022 (x64) bereit. Der Installer enthält eine eingebettete JRE 21 und
|
||
benötigt keine separate Java-Installation auf dem Zielsystem. Das Shade-JAR bleibt das
|
||
primäre Distributionsartefakt; der MSI ist eine zusätzliche Option für Systeme ohne
|
||
Java-Installation und für den Standard-Installationspfad nach `C:\Program Files\`.
|
||
|
||
> **Hinweis zur CI-Umgebung:** Der MSI-Build ist Windows-only (`jpackage` + WiX Toolset 3.x).
|
||
> Jenkins läuft im Linux-Container auf dem Synology NAS und kann kein MSI erzeugen.
|
||
> Der MSI-Build wird bewusst manuell auf der Windows-Entwicklungsmaschine ausgeführt.
|
||
|
||
**Voraussetzungen für den Installer-Build (nur auf der Entwicklungsmaschine):**
|
||
- Windows x64
|
||
- JDK 21 im PATH
|
||
- [WiX Toolset 3.x](https://wixtoolset.org/) im PATH
|
||
|
||
**MSI bauen:**
|
||
|
||
```powershell
|
||
.\mvnw.cmd clean package -P release -pl pdf-umbenenner-packaging --also-make -DskipTests
|
||
```
|
||
|
||
Der normale Build (`mvn clean verify`) ist vom Profil `release` vollständig unberührt
|
||
und benötigt **kein** WiX Toolset.
|
||
|
||
Das Ergebnis liegt unter:
|
||
|
||
```
|
||
pdf-umbenenner-packaging/target/dist/
|
||
PDF-KI-Renamer-2.5.0.msi ← Windows-Installer
|
||
PDF-KI-Renamer.bat ← Headless-Start (zusätzlich kopiert)
|
||
PDF-KI-Renamer-GUI.bat ← GUI-Start (zusätzlich kopiert)
|
||
```
|
||
|
||
**Installationsverzeichnis:**
|
||
|
||
Der Installer legt die Anwendung nach `C:\Program Files\PDF KI Renamer\` ab.
|
||
Beide Batch-Dateien landen ebenfalls dort. Der Installer erstellt:
|
||
- einen Startmenü-Eintrag in der Gruppe `PDF KI Renamer` (startet die GUI)
|
||
- einen Desktop-Shortcut (startet die GUI)
|
||
|
||
Die Deinstallation erfolgt über „Programme und Features" in der Windows-Systemsteuerung.
|
||
Vom Installer angelegte Dateien werden entfernt; Nutzerdaten unter `C:\ProgramData\PDF KI Renamer\`
|
||
(Konfiguration, Logs, SQLite-Datenbank) bleiben erhalten.
|
||
|
||
**Konfigurationsverzeichnis (`ProgramData`):**
|
||
|
||
Das empfohlene Konfigurationsverzeichnis für den produktiven Betrieb ist:
|
||
|
||
```
|
||
C:\ProgramData\PDF KI Renamer\config\
|
||
```
|
||
|
||
Die Anwendung löst dieses Verzeichnis **nicht** automatisch auf. Der Pfad zur
|
||
Konfigurationsdatei muss weiterhin explizit über `--config` angegeben werden
|
||
(siehe „CLI-Optionen"). Der Installer legt eine Beispiel-Konfiguration namens
|
||
`application.example.properties` neben den installierten Artefakten im
|
||
Installationsverzeichnis ab. **Der Betreiber muss diese Beispieldatei manuell nach**
|
||
`C:\ProgramData\PDF KI Renamer\config\` **kopieren und anpassen.**
|
||
|
||
**Beispielaufruf headless mit installierter Anwendung:**
|
||
|
||
```powershell
|
||
"C:\Program Files\PDF KI Renamer\PDF-KI-Renamer.bat" --config "C:\ProgramData\PDF KI Renamer\config\application.properties"
|
||
```
|
||
|
||
**Hinweis:** Der MSI ist nicht signiert. Beim Installieren erscheint eine
|
||
Windows-SmartScreen-Warnung, die durch „Weitere Informationen → Trotzdem ausführen"
|
||
bestätigt werden muss. Code-Signing ist für spätere Ausbaustufen vorgesehen.
|
||
|
||
**Empfehlung für Prompt- und Konfigurationspfade im MSI-Betrieb:**
|
||
|
||
Für den MSI-Betrieb (Startmenü, Task Scheduler) wird **empfohlen**,
|
||
`prompt.template.file` und `sqlite.file` als **absolute Pfade** zu konfigurieren
|
||
oder auf `%APPDATA%`- bzw. `%ProgramData%`-Verzeichnisse zu zeigen.
|
||
Relative Pfade beziehen sich auf das Arbeitsverzeichnis, das je nach Startart variiert
|
||
(siehe Abschnitt „Prompt-Konfiguration").
|
||
|
||
### MSI-Release-Checkliste
|
||
|
||
Die folgende Checkliste ist vor jeder MSI-Auslieferung manuell abzuarbeiten.
|
||
|
||
- [ ] Neuinstallation auf sauberer Windows-Umgebung ohne vorinstalliertes Java
|
||
- [ ] Installation in Installationspfad **mit Leerzeichen** (z. B. `C:\Program Files\PDF KI Renamer\`)
|
||
- [ ] Upgrade von installiertem Vorgänger-MSI (kein manuelles Deinstallieren)
|
||
- [ ] GUI-Start über Startmenü-Eintrag
|
||
- [ ] Headless-Start über `PDF-KI-Renamer.bat` im Windows Task Scheduler
|
||
- [ ] Desktop-Shortcut vorhanden oder Einschränkung hier dokumentiert
|
||
- [ ] App-Version `3.0.x` im Windows-Installer sichtbar („Programme und Features")
|
||
- [ ] Deinstallation sauber – Konfiguration unter `C:\ProgramData\PDF KI Renamer\` bleibt erhalten
|
||
- [ ] SmartScreen-Warnung erscheint und wird durch „Weitere Informationen → Trotzdem ausführen" bestätigt
|
||
- [ ] BAT-Dateien funktionieren bei Installationspfad mit Leerzeichen
|
||
- [ ] Anwendungsstart **ohne Entwicklungs-JDK** erfolgreich: GUI-Start, PDF laden und rendern, Verarbeitungslauf starten, Verlaufs-Tab öffnen (Verifikation der `addModules`-Liste)
|
||
|
||
> **Hinweis zur JDK-freien Laufzeit-Verifikation:** Nur ein erfolgreicher Test
|
||
> auf einem System ohne installiertes JDK bestätigt die Vollständigkeit der
|
||
> `addModules`-Liste in `pdf-umbenenner-packaging/pom.xml`. Die aktuelle Liste
|
||
> wurde per `jdeps --print-module-deps --ignore-missing-deps` ermittelt;
|
||
> vollständige Ausgabe in `pdf-umbenenner-packaging/jdeps-output.txt`.
|
||
|
||
### Build-Kommandos
|
||
|
||
**Vollständiger Reactor-Build** (alle Module, Tests, Packaging):
|
||
|
||
```powershell
|
||
.\mvnw.cmd clean verify
|
||
```
|
||
|
||
Auf Unix-Systemen (headless CI):
|
||
|
||
```bash
|
||
./mvnw clean verify
|
||
```
|
||
|
||
**Nur das ausführbare JAR erzeugen** (überspringt Tests):
|
||
|
||
```powershell
|
||
.\mvnw.cmd clean package -pl pdf-umbenenner-bootstrap --also-make -DskipTests
|
||
```
|
||
|
||
**Selektiver Reactor-Build** (ohne Coverage-Modul, z. B. während der Entwicklung):
|
||
|
||
```powershell
|
||
.\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 den
|
||
`ServicesResourceTransformer` zusammengeführt statt überschrieben.
|
||
- Der Main-Class-Eintrag im Manifest verweist auf
|
||
`de.gecheckt.pdf.umbenenner.bootstrap.PdfUmbenennerApplication`.
|
||
Diese Klasse erweitert bewusst **nicht** `javafx.application.Application`,
|
||
um den JavaFX-Modul-System-Launcher-Check zu umgehen, der Fat-JAR-Ausführung
|
||
blockieren würde. Der GUI-Pfad ruft `Application.launch(...)` explizit auf.
|
||
|
||
---
|
||
|
||
## GUI: Selektive Wiederverarbeitung und Status-Reset
|
||
|
||
Die GUI ermöglicht nach Abschluss eines Verarbeitungslaufs zwei zusätzliche Aktionen auf der Ergebnisliste:
|
||
|
||
### Selektion in der Ergebnisliste
|
||
|
||
Die Ergebnisliste enthält eine **Checkbox pro Zeile** sowie eine **Master-Checkbox** zum Auswählen aller Einträge.
|
||
- Auswahl erfolgt wie im Windows Explorer mit **Shift/Strg-Mehrfachselektion**
|
||
- Alle vier Statustypen sind selektierbar: erfolgreich, retryable, permanent fehlgeschlagen, übersprungen
|
||
- Während eines Laufs ist die Selektion **gesperrt**
|
||
|
||
### Button „Erneut verarbeiten"
|
||
|
||
**Aktion:** DB-Status zurücksetzen + sofortiger Mini-Lauf nur für ausgewählte Dateien.
|
||
|
||
- Aktiv nur wenn kein Lauf läuft und mindestens 1 Eintrag selektiert ist
|
||
- Der Mini-Lauf arbeitet auf einem Snapshot der beim Klick ausgewählten Einträge
|
||
- Nicht ausgewählte Einträge bleiben unverändert in der Liste
|
||
- Verhalten identisch zu regulärem Lauf (gleiche Anwendungslogik, nur eingeschränkte Dateimenge)
|
||
|
||
**Besonderheit bei identischem Zieldateinamen:** Verarbeitet der KI-Provider wieder denselben Dateinamen wie ein vorangegangener erfolgreicher Lauf, erhält der Eintrag **Status erfolgreich** – es wird keine erneute Kopie erzeugt, kein Fehler.
|
||
|
||
**Fehlende Quelldatei:** Ist die Datei zum Zeitpunkt des Mini-Laufs nicht mehr vorhanden, erhält der Eintrag **Status permanent fehlgeschlagen** mit Meldung „Quelldatei nicht gefunden".
|
||
|
||
### Button „Status zurücksetzen"
|
||
|
||
**Aktion:** Nur DB-Status zurücksetzen, keine sofortige Verarbeitung.
|
||
|
||
- Aktiv nur wenn kein Lauf läuft und mindestens 1 Eintrag selektiert ist
|
||
- Betroffene Zeilen erhalten die Kennzeichnung **„Zurückgesetzt – wartet auf nächsten Lauf"**
|
||
- Beim nächsten regulären Lauf werden zurückgesetzte Dateien automatisch mitgenommen
|
||
- **Best-effort-Reset:** Erfolgreiche und fehlgeschlagene Resets werden pro Eintrag einzeln durchgeführt; Zusammenfassung zeigt Erfolge und Fehler
|
||
|
||
### Verhalten während eines Mini-Laufs
|
||
|
||
- Der **Abbrechen-Button** gilt auch für Mini-Läufe (Soft-Stop)
|
||
- **Tab 1 „Konfiguration" ist während des Mini-Laufs gesperrt**
|
||
- Nach Soft-Stop: bereits verarbeitete Einträge behalten neuen Status, noch nicht gestartete zurückgesetzte Einträge warten auf nächsten regulären Lauf
|
||
- Fortschrittsbalken zeigt Fortschritt für die ausgewählte Dateimenge
|
||
|
||
---
|
||
|
||
## Weitere Dokumentation
|
||
|
||
Die Bedienung der GUI ist in [`gui-bedienanleitung.md`](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 ermöglicht Konfiguration, Validierung, technische Diagnose und die Ausführung von Verarbeitungsläufen mit integrierter PDF-Vorschau und editierbarem Dateiname
|
||
- 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
|