379 lines
18 KiB
Markdown
379 lines
18 KiB
Markdown
# V2.9 – Integrierte PDF-Vorschau und Dateinamen-Bearbeitung
|
||
|
||
**Status:** Freigegeben
|
||
**Erstellt:** 2026-04-24
|
||
**Überarbeitet:** 2026-04-24 (nach zwei ChatGPT-Reviews, finale Version)
|
||
**Autor:** Marcus (mit Claude als Mentor)
|
||
|
||
---
|
||
|
||
## Ziel
|
||
|
||
V2.9 erweitert den Tab „Verarbeitungslauf" um zwei eng verzahnte Funktionen:
|
||
|
||
1. **Integrierte PDF-Vorschau** – beim Anklicken einer Zeile wird die erste Seite der
|
||
Quelldatei direkt im Detailbereich rechts gerendert (kein separates Fenster, kein
|
||
zusätzlicher Klick)
|
||
2. **Editierbarer Dateiname** – der von der KI vorgeschlagene Dateiname kann direkt
|
||
in der GUI korrigiert werden, bevor er als endgültig gilt
|
||
|
||
Beide Funktionen zusammen ermöglichen einen natürlichen Review-Zyklus:
|
||
**KI benennt → Benutzer schaut rein → Benutzer korrigiert bei Bedarf → fertig.**
|
||
|
||
---
|
||
|
||
## Hintergrund
|
||
|
||
### Bisheriger Zustand
|
||
|
||
- Der Detailbereich rechts zeigt nur KI-Begründung als TextArea
|
||
- Ob der vorgeschlagene Dateiname sinnvoll ist, kann der Benutzer nur anhand des
|
||
KI-Reasonings beurteilen – den tatsächlichen Dokumentinhalt sieht er nicht
|
||
- Der generierte Dateiname ist nach dem Lauf nicht mehr veränderbar
|
||
- Die Spike-Implementierung (PDFViewFX + jai-imageio-jpeg2000 für JBIG2-Unterstützung)
|
||
hat die technische Machbarkeit bereits bestätigt; der Spike-Code wird im Rahmen
|
||
von V2.9 durch produktionsreifen Code ersetzt
|
||
|
||
### Motivation
|
||
|
||
- Benutzer sollen schnell beurteilen können, ob der KI-Dateiname passt,
|
||
ohne ein externes Programm öffnen zu müssen
|
||
- Korrekturen sollen direkt in der Anwendung möglich sein – für nicht-technische
|
||
Benutzer (z. B. Familienmitglieder) ist das eine wesentliche UX-Verbesserung
|
||
- Die Anwendung wird vom reinen Batch-Prozessor zum assistierten
|
||
Dokumenten-Review-Werkzeug weiterentwickelt
|
||
|
||
---
|
||
|
||
## Zielbild
|
||
|
||
Nach Abschluss von V2.9 kann der Benutzer:
|
||
|
||
1. Eine Zeile in der Ergebnisliste anklicken
|
||
2. Sofort die erste Seite der zugehörigen **Quelldatei** als Vorschau sehen –
|
||
ohne weiteren Klick, direkt im Detailbereich
|
||
3. Weitere Seiten bei Bedarf **auf Anfrage** laden (Lazy Rendering)
|
||
4. Den vorgeschlagenen Dateinamen **direkt in der GUI bearbeiten** und speichern
|
||
5. Den headless-Betrieb unverändert nutzen – V2.9 betrifft ausschließlich die GUI
|
||
|
||
---
|
||
|
||
## Layout-Änderung im Tab „Verarbeitungslauf"
|
||
|
||
### Bisheriges Layout
|
||
|
||
```
|
||
[ Fortschrittsbalken ]
|
||
[ Ergebnistabelle (~75% Breite) | KI-Begründung (~25%) ]
|
||
[ Buttons ]
|
||
[ Statuszeile ]
|
||
```
|
||
|
||
### Neues Layout
|
||
|
||
```
|
||
[ Fortschrittsbalken ]
|
||
[ Ergebnistabelle (~60% Breite) | Detailbereich (~40% Breite) ]
|
||
[ | KI-Begründung ]
|
||
[ | Dateiname (editierbar) ]
|
||
[ | PDF-Vorschau (Seite X/Y) ]
|
||
[ Buttons ]
|
||
[ Statuszeile ]
|
||
```
|
||
|
||
- Tabelle und Detailbereich sind durch einen **verschiebbaren Splitter** (SplitPane)
|
||
getrennt – der Benutzer kann das Verhältnis anpassen
|
||
- Standard-Split: 60% Tabelle / 40% Detailbereich
|
||
- Der Detailbereich ist vertikal aufgebaut: KI-Begründung oben (kompakt),
|
||
darunter Dateiname-Feld, darunter PDF-Vorschau (nimmt verfügbaren Restplatz)
|
||
- Die PDF-Vorschau rendert die erste Seite **„fit to width"** – Seitenverhältnis wird
|
||
beibehalten, die Seite füllt die verfügbare Panelbreite aus
|
||
|
||
---
|
||
|
||
## Fachliche Anforderungen
|
||
|
||
### PDF-Vorschau
|
||
|
||
#### Grundverhalten
|
||
|
||
- Beim Anklicken einer Zeile in der Ergebnisliste wird **automatisch** Seite 1 der
|
||
zugehörigen **Quelldatei** gerendert und im Vorschaubereich angezeigt
|
||
- Das Rendering erfolgt **asynchron im Hintergrund** – die GUI bleibt während des
|
||
Ladens reaktionsfähig
|
||
- Während des Renderings wird ein **Ladeindikator** (z. B. ProgressIndicator) angezeigt
|
||
- Die Vorschau zeigt immer die **Quelldatei**, nicht die umbenannte Zieldatei
|
||
|
||
#### Lazy Rendering und Seitennavigation
|
||
|
||
- Beim ersten Anklicken einer Zeile wird **ausschließlich Seite 1** gerendert
|
||
- Unterhalb der Vorschau wird die aktuelle Seite sowie die Gesamtseitenzahl
|
||
angezeigt: „Seite 1 / 12"
|
||
- Navigation:
|
||
- Button **„Nächste Seite"** lädt und rendert die jeweils nächste Seite on-demand
|
||
- Button **„Vorherige Seite"** lädt die vorherige Seite
|
||
- Bereits gerenderte Seiten werden **gecacht** – ein erneuter Wechsel auf eine
|
||
bereits gerenderte Seite erfordert kein erneutes Rendering
|
||
- Der Cache wird geleert wenn eine andere Zeile angeklickt wird
|
||
- Die Navigations-Buttons sind bei Seite 1 (Zurück) bzw. letzter Seite (Weiter)
|
||
deaktiviert
|
||
|
||
#### Abbruchverhalten bei schnellem Wechsel (Latest Preview Request Wins)
|
||
|
||
- Es gilt das Prinzip **„latest preview request wins"**: Wenn während eines laufenden
|
||
Renderings eine neue Vorschau-Anforderung eingeht – sei es durch Selektionswechsel
|
||
oder durch Seitennavigation innerhalb derselben PDF – wird das laufende Rendering
|
||
abgebrochen bzw. sein Ergebnis verworfen
|
||
- Nur das Ergebnis der zuletzt angeforderten Vorschau darf im Vorschaubereich landen
|
||
- Veraltete Render-Ergebnisse werden niemals angezeigt
|
||
|
||
#### Fehlerfälle PDF-Vorschau
|
||
|
||
| Situation | Verhalten |
|
||
|---|---|
|
||
| Quelldatei nicht mehr vorhanden | Meldung im Vorschaubereich: „Quelldatei nicht gefunden" |
|
||
| PDF nicht lesbar / korrupt | Meldung im Vorschaubereich: „PDF konnte nicht geöffnet werden" |
|
||
| PDF passwortgeschützt / verschlüsselt | Meldung im Vorschaubereich: „PDF ist passwortgeschützt und kann nicht angezeigt werden" |
|
||
| JBIG2-Bilder nicht vollständig dekodierbar | Seite wird teilweise gerendert; kein Fehler-Abbruch; kein Hinweis nötig |
|
||
| Kein Eintrag selektiert | Vorschaubereich zeigt neutralen Platzhaltertext |
|
||
|
||
#### Technische Grundlage
|
||
|
||
- Bibliothek: `com.dlsc.pdfviewfx:pdfviewfx` (bereits im Spike erfolgreich getestet)
|
||
- Zusatzabhängigkeit für JBIG2 und erweiterte Bildformate:
|
||
`com.github.jai-imageio:jai-imageio-jpeg2000` (bereits im Spike ergänzt)
|
||
- Der Spike-Code (`PdfViewerSpike.java`, Spike-Button in `GuiBatchRunTab`) wird
|
||
vollständig entfernt und durch die produktive Implementierung ersetzt
|
||
- Rendering läuft in einem dedizierten Background-Thread (nicht im JavaFX
|
||
Application Thread)
|
||
|
||
---
|
||
|
||
### Editierbarer Dateiname
|
||
|
||
#### Zustandsmodell
|
||
|
||
Der Dateiname-Bereich kennt drei klar getrennte Zustände:
|
||
|
||
| Zustand | Beschreibung |
|
||
|---|---|
|
||
| **KI-Vorschlag** | Der von der KI ursprünglich generierte Name – unveränderlich in der DB gespeichert; dient als Referenz für „Zurücksetzen auf KI-Vorschlag" |
|
||
| **Letzter gespeicherter Name** | Der zuletzt per „Dateiname übernehmen" bestätigte Name (= aktueller FS- und DB-Stand); ist nach dem Batch-Lauf zunächst identisch mit dem KI-Vorschlag |
|
||
| **Aktuelle Eingabe** | Der aktuell im Textfeld eingetippte, noch nicht gespeicherte Wert |
|
||
|
||
**Anzeige-Regel:** Im Textfeld wird beim Selektieren einer Zeile immer der
|
||
**letzte gespeicherte Name** angezeigt – nicht der KI-Vorschlag.
|
||
Wurde noch nie manuell gespeichert, sind beide identisch.
|
||
|
||
**Dirty-State-Regel:** Dirty-State besteht wenn die **aktuelle Eingabe** vom
|
||
**letzten gespeicherten Namen** abweicht. Der KI-Vorschlag ist keine Dirty-Basis.
|
||
|
||
#### Anzeige
|
||
|
||
- Unterhalb der KI-Begründung und oberhalb der PDF-Vorschau befindet sich ein
|
||
Bereich „Dateiname"
|
||
- Der Dateiname wird in einem **editierbaren Textfeld** (TextField) angezeigt
|
||
- Das Textfeld zeigt den **letzten gespeicherten Namen** ohne Dateierweiterung
|
||
(`.pdf` wird separat als nicht editierbares Label daneben angezeigt)
|
||
- Solange kein Eintrag selektiert ist, ist das Textfeld leer und deaktiviert
|
||
- Wenn das Textfeld vom letzten gespeicherten Namen abweicht (**Dirty State**),
|
||
wird dies durch eine visuelle Markierung am Textfeld angezeigt (z. B. farbiger Rand)
|
||
|
||
#### Tastatur- und Schaltflächen-Verhalten
|
||
|
||
| Aktion | Verhalten |
|
||
|---|---|
|
||
| **Enter** im Textfeld | Löst „Dateiname übernehmen" aus (sofern Validierung grün) |
|
||
| **Escape** im Textfeld | Verwirft aktuelle Eingabe; stellt **letzten gespeicherten Namen** wieder her |
|
||
| **„Dateiname übernehmen"** | Startet die atomare Speicher-Transaktion |
|
||
| **„Zurücksetzen auf KI-Vorschlag"** | Setzt das Textfeld auf den ursprünglichen KI-Vorschlag zurück (kein Speichern – nur Textfeld-Inhalt) |
|
||
|
||
Hinweis: „Zurücksetzen auf KI-Vorschlag" und Escape haben **unterschiedliche Semantik**:
|
||
Escape = zurück zum letzten gespeicherten Stand; „Zurücksetzen" = zurück zum KI-Ursprung.
|
||
|
||
#### Speichern-Transaktion (Alles oder Nichts)
|
||
|
||
Das Speichern eines geänderten Dateinamens ist eine **atomare Operation** bestehend
|
||
aus zwei Persistenzschritten:
|
||
|
||
1. Zieldatei im Dateisystem umbenennen
|
||
2. Eintrag in der SQLite-DB aktualisieren
|
||
|
||
**Schlägt Schritt 1 oder 2 fehl, wird die gesamte Aktion abgebrochen:**
|
||
- Bereits durchgeführte Teilschritte werden zurückgerollt
|
||
- Dateisystem und DB bleiben im vorherigen Zustand
|
||
- Eine Fehlermeldung im Statusbereich informiert den Benutzer
|
||
- Das Textfeld behält den eingegebenen Wert – der Benutzer kann es erneut versuchen
|
||
|
||
Nach erfolgreicher Transaktion (Projektionsschritt, nicht Teil der Transaktion):
|
||
- Tabellenspalte „Neuer Dateiname" wird aktualisiert
|
||
- Erfolgsmeldung im Statusbereich
|
||
|
||
Mögliche Fehlerursachen für Schritt 1: Datei-Lock durch andere Prozesse (Scanner, AV),
|
||
fehlende Schreibrechte, Read-only-Dateisystem, Netzlaufwerk nicht erreichbar.
|
||
|
||
#### Konfliktsemantik bei vorhandenem Zieldateinamen
|
||
|
||
Existiert im Zielordner bereits eine Datei mit dem neu eingegebenen Namen,
|
||
wird anhand des **Fingerprints** (SHA-256 des Dateiinhalts) entschieden:
|
||
|
||
| Situation | Verhalten |
|
||
|---|---|
|
||
| **Gleicher Fingerprint** | Dateien sind inhaltlich identisch → keine Aktion; Meldung im Statusbereich: „Identische Datei bereits vorhanden – keine Umbenennung nötig"; weder FS noch DB werden geändert |
|
||
| **Unterschiedlicher Fingerprint** | Warnung im Statusbereich; Dateiname im FS erhält automatisch ein Suffix `(1)`, `(2)` usw.; DB wird mit dem tatsächlichen neuen Namen inkl. Suffix aktualisiert |
|
||
|
||
#### Validierung des Dateinamens
|
||
|
||
Folgende Prüfungen erfolgen **live während der Eingabe**:
|
||
|
||
| Prüfung | Verhalten bei Verletzung |
|
||
|---|---|
|
||
| Dateiname ist leer oder nur Leerzeichen | Speichern-Button deaktiviert, Hinweistext unterhalb des Feldes |
|
||
| Führende oder abschließende Leerzeichen | Speichern-Button deaktiviert, Hinweistext |
|
||
| Unerlaubte Zeichen (`\ / : * ? " < > \|`) | Speichern-Button deaktiviert, Hinweistext |
|
||
| Reservierte Windows-Namen (`CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, `LPT1`–`LPT9`) | Speichern-Button deaktiviert, Hinweistext |
|
||
| Dateiname endet auf Punkt | Speichern-Button deaktiviert, Hinweistext |
|
||
| Dateiname + Zielpfad + `.pdf` überschreitet 259 Zeichen | Speichern-Button deaktiviert, Hinweistext |
|
||
|
||
Die 259-Zeichen-Grenze ist eine **bewusste Produktregel** für maximale
|
||
Windows-Kompatibilität (Windows MAX_PATH = 260 Zeichen inkl. Null-Terminator).
|
||
|
||
#### Zustände des Dateiname-Bereichs
|
||
|
||
| Zeilenstatus | Verhalten |
|
||
|---|---|
|
||
| Kein Eintrag selektiert | Textfeld leer, deaktiviert |
|
||
| Eintrag mit Status `DONE` (erfolgreich) | Textfeld editierbar, letzter gespeicherter Name vorausgefüllt |
|
||
| Eintrag mit Status `FAILED_*` | Textfeld leer, deaktiviert (kein Dateiname vorhanden) |
|
||
| Eintrag mit Status `SKIPPED` | Textfeld deaktiviert |
|
||
| Lauf aktiv | Textfeld deaktiviert, alle Buttons deaktiviert |
|
||
|
||
#### Verhalten bei fehlender Zieldatei
|
||
|
||
Ist die Zieldatei zum Zeitpunkt des Speicherns nicht mehr im Zielordner vorhanden:
|
||
|
||
- Schritt 1 der Transaktion schlägt fehl
|
||
- Gemäß Alles-oder-Nichts-Prinzip: DB wird **nicht** aktualisiert
|
||
- Fehlermeldung im Statusbereich: „Zieldatei nicht gefunden – Umbenennung nicht möglich"
|
||
- Das Textfeld behält den eingegebenen Wert
|
||
|
||
#### Verhalten bei ungespeicherten Änderungen (Dirty State)
|
||
|
||
Ein Hinweisdialog erscheint, wenn der Benutzer mit aktivem Dirty-State eine der
|
||
folgenden Aktionen ausführt:
|
||
|
||
- Eine andere Zeile in der Ergebnistabelle anklicken
|
||
- Den Tab wechseln (Konfiguration ↔ Verarbeitungslauf)
|
||
- Die Anwendung schließen
|
||
- Einen neuen Lauf starten
|
||
|
||
Dialog-Text: „Der Dateiname wurde geändert aber nicht gespeichert. Änderungen verwerfen?"
|
||
Optionen: **„Verwerfen"** (Dirty State wird geleert, Aktion wird fortgesetzt) /
|
||
**„Zurück"** (Dialog schließt, Benutzer bleibt im Textfeld)
|
||
|
||
---
|
||
|
||
## Architektur
|
||
|
||
### Manuelle Namenskorrektur als Application-Use-Case
|
||
|
||
Die manuelle Dateinamen-Korrektur wird als **eigenständiger Application-Use-Case**
|
||
modelliert, nicht im GUI-Adapter implementiert:
|
||
|
||
- Ein neuer Use-Case `ManualFileRenameUseCase` (o. ä.) kapselt die atomare Transaktion
|
||
aus FS-Rename + DB-Update
|
||
- Der `GuiBatchRunCoordinator` (GUI-Adapter) delegiert ausschließlich an diesen Use-Case
|
||
- Dateisystem- und DB-Zugriffe laufen ausschließlich über bestehende oder neue
|
||
Ports/Adapter – kein Direktzugriff aus dem GUI-Adapter
|
||
- Damit bleibt die hexagonale Architektur gewahrt und der Use-Case ist unabhängig
|
||
von der GUI testbar
|
||
|
||
### Komponenten-Übersicht
|
||
|
||
| Komponente | Änderung |
|
||
|---|---|
|
||
| `GuiBatchRunTab` | Hauptumbau: SplitPane, Detailbereich-Redesign, Spike-Code entfernen |
|
||
| `GuiBatchRunResultRow` | Neues Feld: `correctedFileName` als `Optional<String>` |
|
||
| `GuiBatchRunCoordinator` | Delegiert Dateinamen-Korrektur an neuen Use-Case |
|
||
| `ManualFileRenameUseCase` | Neuer Application-Use-Case: atomares FS-Rename + DB-Update |
|
||
| `pom.xml` (GUI-Modul) | PDFViewFX + jai-imageio-jpeg2000 bleiben; Spike-Klasse entfernen |
|
||
| Domain / Ports | Ggf. neuer Port für Datei-Rename-Operation erforderlich |
|
||
| Headless-Betrieb | Unberührt |
|
||
|
||
---
|
||
|
||
## Abhängigkeiten zwischen den Funktionen
|
||
|
||
- PDF-Vorschau und editierbarer Dateiname sind **unabhängig voneinander nutzbar**
|
||
- Beide beziehen sich auf den in der Ergebnistabelle selektierten Eintrag
|
||
- Beim Selektionswechsel mit Dirty-State: Hinweisdialog erscheint (siehe oben)
|
||
- PDF-Vorschau-Cache wird beim Selektionswechsel geleert
|
||
|
||
---
|
||
|
||
## Verhalten während eines laufenden Batch-Laufs
|
||
|
||
- Der Detailbereich (PDF-Vorschau + Dateinamen-Editor) ist **vollständig deaktiviert**
|
||
während ein regulärer Lauf oder Mini-Lauf aktiv ist
|
||
- Bereits angezeigte Vorschau bleibt sichtbar, aber Navigation und Bearbeitung
|
||
sind gesperrt
|
||
|
||
---
|
||
|
||
## Nicht in V2.9 enthalten
|
||
|
||
- Löschen der Quelldatei nach Bestätigung (spätere Version)
|
||
- Vollständiger PDF-Viewer mit freiem Scrollen und Zoom (Issue #23: DPI-Optimierung)
|
||
- Historien-Tab / SQLite-Ansicht (Issue #7, V3.0)
|
||
- Automatischer Scheduler / System-Tray (Issues #20, #22)
|
||
- Kompakteres Layout der Konfigurationsseite (Issue #24)
|
||
- Anwendungs-Icon (Issue #21)
|
||
|
||
---
|
||
|
||
## Abnahmekriterien
|
||
|
||
### Fachliche Akzeptanz
|
||
|
||
#### PDF-Vorschau
|
||
- [ ] Beim Anklicken einer Zeile wird Seite 1 der Quelldatei automatisch gerendert – ohne extra Klick
|
||
- [ ] Während des Renderings ist ein Ladeindikator sichtbar; die GUI bleibt reaktionsfähig
|
||
- [ ] Die Vorschau rendert „fit to width" mit beibehaltenem Seitenverhältnis
|
||
- [ ] Seitenanzahl wird angezeigt: „Seite 1 / X"
|
||
- [ ] „Nächste Seite" / „Vorherige Seite" laden Seiten on-demand
|
||
- [ ] Bereits gerenderte Seiten werden gecacht; Selektionswechsel leert den Cache
|
||
- [ ] Navigations-Buttons sind korrekt deaktiviert (erste / letzte Seite)
|
||
- [ ] Schneller Selektionswechsel oder Seitenwechsel während Rendering: nur das zuletzt angeforderte Ergebnis wird angezeigt (latest preview request wins)
|
||
- [ ] Quelldatei nicht vorhanden → verständliche Fehlermeldung im Vorschaubereich
|
||
- [ ] PDF nicht lesbar / korrupt → verständliche Fehlermeldung im Vorschaubereich
|
||
- [ ] PDF passwortgeschützt → verständliche Fehlermeldung im Vorschaubereich
|
||
|
||
#### Dateiname-Editor
|
||
- [ ] Textfeld zeigt beim Selektieren den **letzten gespeicherten Namen** (nicht KI-Vorschlag) ohne `.pdf`-Erweiterung; `.pdf` als nicht editierbares Label daneben sichtbar
|
||
- [ ] Dateiname ist direkt im Textfeld editierbar
|
||
- [ ] Dirty-State (Abweichung von letztem gespeichertem Namen) wird visuell am Textfeld angezeigt
|
||
- [ ] Enter im Textfeld löst „Dateiname übernehmen" aus (wenn Validierung grün)
|
||
- [ ] Escape im Textfeld stellt den **letzten gespeicherten Namen** wieder her
|
||
- [ ] „Zurücksetzen auf KI-Vorschlag" setzt das Textfeld auf den KI-Ursprung zurück (ohne Speichern)
|
||
- [ ] Validierung prüft live: leer/nur Leerzeichen, führende/abschließende Leerzeichen, unerlaubte Zeichen, reservierte Windows-Namen, endet auf Punkt, Pfadlänge > 259
|
||
- [ ] Bei Validierungsfehler: Speichern-Button deaktiviert, Hinweistext sichtbar
|
||
- [ ] „Dateiname übernehmen" ist atomar: FS und DB werden beide aktualisiert oder nichts davon
|
||
- [ ] Bei Fehler in FS oder DB: kein Teilupdate, Rollback, Fehlermeldung im Statusbereich, Textfeld behält Eingabe
|
||
- [ ] Nach Erfolg: Tabellenspalte und Statusbereich aktualisiert (Projektionsschritt)
|
||
- [ ] Dateikonflikt mit gleichem Fingerprint → keine Aktion, Meldung „Identische Datei bereits vorhanden"
|
||
- [ ] Dateikonflikt mit unterschiedlichem Fingerprint → Warnung, Suffix `(1)` usw., DB mit tatsächlichem Namen
|
||
- [ ] Zieldatei fehlt → Fehlermeldung, weder FS noch DB werden geändert
|
||
- [ ] Ungespeicherte Änderungen bei Selektionswechsel → Hinweisdialog erscheint
|
||
- [ ] Ungespeicherte Änderungen bei Tabwechsel → Hinweisdialog erscheint
|
||
- [ ] Ungespeicherte Änderungen beim App-Schließen → Hinweisdialog erscheint
|
||
- [ ] Ungespeicherte Änderungen bei Laufstart → Hinweisdialog erscheint
|
||
- [ ] Status `FAILED_*` und `SKIPPED` → Dateiname-Textfeld deaktiviert
|
||
- [ ] Während eines aktiven Laufs: Detailbereich vollständig deaktiviert
|
||
|
||
### Technische DoD
|
||
- [ ] Spike-Button und `PdfViewerSpike.java` sind vollständig entfernt
|
||
- [ ] Tab „Verarbeitungslauf" zeigt Tabelle und Detailbereich nebeneinander (SplitPane, 60/40, verschiebbar)
|
||
- [ ] `ManualFileRenameUseCase` ist im Application-Modul implementiert und unabhängig von der GUI testbar
|
||
- [ ] headless-Betrieb ist unverändert funktionsfähig
|
||
- [ ] `mvn clean verify` ist grün
|