Commit Graph

97 Commits

Author SHA1 Message Date
marcus 3feafcbce8 Fix #36: Falscher Verwerfen-Dialog beim Klick auf Dateiname uebernehmen
Nach erfolgreicher Umbenennung loeste resultItems.set() in
upsertResultRowByFingerprint() den selectedItemProperty-Listener aus,
der handleSelectionChange() mit noch aktivem Dirty-State aufrief.

Drei Korrekturen:
1. fileNameEditor.clearDirtyState() in handleRenameResult() vor dem
   Zeilen-Upsert: setzt lastSavedName = aktueller Textfeldinhalt, damit
   isDirty() false ist bevor die Tabellenzeile ersetzt wird.
2. selectionSyncInProgress-Schutz um resultItems.set() in
   upsertResultRowByFingerprint(): unterbindet mehrfache JavaFX-interne
   Change-Events (oldRow > null > newRow) waehrend des Upserts.
3. Neue Methode FileNameEditorPane.clearDirtyState() eingeführt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 08:47:58 +02:00
marcus 5165ea6f1d Icons hinzugefügt. 2026-04-25 08:26:26 +02:00
marcus 0e20f93c0d Feature #21/#20: Anwendungs-Icon und System-Tray einbinden
Schließt Issue #21: Alle vier Icon-Größen (16/32/64/128 px) werden beim
Start am primären Stage gesetzt; JavaFX wählt automatisch die passende
Größe je nach Kontext (Titelleiste, Taskleiste, Alt+Tab).

Schließt Issue #20: Beim Klick auf den X-Button wird das Fenster in den
Windows System-Tray minimiert (stage.hide()) statt die Anwendung zu
beenden. Platform.setImplicitExit(false) hält die JavaFX-Runtime aktiv.
Das Tray-Icon zeigt ein Kontextmenü mit "Öffnen" und "Beenden";
Doppelklick öffnet das Fenster ebenfalls. Beim Beenden über das Tray-Menü
wird das Icon sauber entfernt.

Die gesamte AWT-Tray-Logik ist in SystemTrayManager gekapselt. Der
Headless-Betrieb bleibt unberührt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 08:24:54 +02:00
marcus 6b078aa3e7 Fix #33: Letzte Konfigurationsdatei beim Neustart automatisch laden
Nutzt java.util.prefs.Preferences mit dem Schluessel "lastConfigPath"
um den Pfad der zuletzt geladenen Konfigurationsdatei zu speichern.

Beim naechsten Start wird diese Datei automatisch geladen, sofern sie
noch existiert. Falls nicht oder falls nie eine Datei geladen wurde,
startet die GUI normal ohne Fehlermeldung.

Geaenderte Klassen:
- GuiConfigurationEditorWorkspace: Speichern des Pfads nach erfolgreichem Laden,
  neue Methode autoLoadLastConfiguration() fuer automatisches Laden beim Start
- PdfUmbenennerGuiApplication: Aufruf von autoLoadLastConfiguration() nach
  Initialisierung des Fensters

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-24 16:27:52 +02:00
marcus 7e2fec4c7b Fix #28: Anwendung standardmaessig im Vollbild starten
Fuegt stage.setMaximized(true) in PdfUmbenennerGuiApplication.start() hinzu,
so dass das Fenster beim Start automatisch maximiert wird.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-24 16:22:51 +02:00
marcus 591c7ff94c Fix #29: Eigenes PDF-Rendering mit PDFBox statt PDFViewFX
Ersetzt die PDFView-basierte Vorschau durch direktes Rendering einzelner Seiten
mit PDFBox (Loader.loadPDF + PDFRenderer.renderImageWithDPI bei 120 DPI).
BufferedImage wird über SwingFXUtils.toFXImage in eine JavaFX-Image konvertiert
und in einer ImageView angezeigt. fit-to-view entsteht nativ durch Binding von
fitWidth/fitHeight an den StackPane-Bereich bei preserveRatio=true. Keine
Scrollbalken, keine Zoom-Einschraenkungen, Seitenanfang immer sichtbar.

Lazy Rendering mit In-Memory-Cache fuer bereits gerenderte Seiten; asynchrones
Oeffnen und Rendering auf pdf-preview-worker-Thread; "latest preview request
wins"-Prinzip bleibt erhalten. pdfviewfx-Abhaengigkeit aus adapter-in-gui pom
entfernt, pdfbox stattdessen explizit aufgenommen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:05:02 +02:00
marcus 673023d921 Fix #29: Fit-to-view via statischem A4-Fallback statt asynchronem Seitenverhältnis
Ersetzt fetchAspectRatioAsync/fitToView durch updateZoom() mit A4-Dimensionen
(595x842 Punkte) als Fallback. Scrollbalken werden per CSS und ScrollPane-Policy
ausgeblendet. Zoom-Listener auf pdfView statt viewStack.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 15:51:26 +02:00
marcus 71d79ab30c Fix #29: Layout-Umbau und fit-to-view PDF-Vorschau ohne Scrollbalken
GuiBatchRunTab: Buttons "Erneut verarbeiten" / "Status zurücksetzen" und
Meldungsbereich in die linke SplitPane-Spalte unterhalb der Tabelle
verschoben. Detailbereich (rechte Spalte) erstreckt sich dadurch vollständig
von oben bis unten – mehr Platz für die PDF-Vorschau.

PdfPreviewPane: Gesamten suppressScrollReset / ChangeListener-Code entfernt.
Seite wird jetzt immer fit-to-view ohne Scrollbalken angezeigt: Seitenverhältnis
wird asynchron per renderPage(0.05f) ermittelt, Zoom über setZoomFactor() gesetzt
und bei Größenänderungen der Anzeigefläche automatisch neu berechnet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 15:28:29 +02:00
marcus 8f4e18b248 Fix #29: Seitenanfang zuverlaessig via vvalue-Einmal-Listener erzwingen
Der bisherige ImageView-imageProperty-Listener mit Platform.runLater()
wurde von PDFViewFX nach dem Rendering noch einmal ueberschrieben, weil
die interne Scroll-Korrektur ebenfalls asynchron laeuft und spaeter
ausgefuehrt wird.

Neuer Ansatz: Nach jedem pdfView.load() und pdfView.setPage()-Aufruf
wird ein einmaliger ChangeListener auf die vvalueProperty des internen
ScrollPane registriert (scheduleScrollToTop). Sobald PDFViewFX seine
interne Scroll-Position durchschreibt und der Wert von 0 abweicht,
korrigiert der Listener ihn sofort auf 0 und entfernt sich danach selbst.
Damit greift der Eingriff immer nach dem internen PDFViewFX-Scroll,
unabhaengig von der Renderzeit.

Zusaetzlich wird ein aktiver Listener bei schnellen Seitenwechseln
(cancelScrollToTopListener) und bei clear() sauber aufgeraeumt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 14:58:43 +02:00
marcus 0387be0e96 Fix #27 und #29: pdfviewfx 3.3.2 und zuverlaessiger Seitenanfang via ImageView-Listener
pdfviewfx wird von 3.1.1 auf 3.3.2 aktualisiert. Version 3.3.1 behebt
'Do not interrupt rendering', wodurch ClosedByInterruptException bei
schnellem Seitenwechsel (#27 Folge-Bug) und das Ausbleiben weiterer
Renderings ab Seite 3+ (#29 Folge-Bug) nicht mehr auftreten.

Das 100-ms-PauseTransition-Workaround fuer den Seitenanfang wird ersetzt
durch einen Listener auf die imageProperty des internen ImageView der
PDFView-Skin. Der Listener scrollt erst dann zum Seitenanfang, wenn
das Rendering tatsaechlich abgeschlossen ist und pendingScrollToTop
gesetzt wurde (bei loadSource und Seitenwechsel-Buttons). Dadurch wird
der Seitenanfang zuverlaessig angezeigt, unabhaengig von der Renderzeit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 14:30:40 +02:00
marcus ca16855e81 Fix #27 und #29: Gezielter Scroll-Schutz und zuverlaessiger Seitenanfang
Bug #27: Den zu aggressiven ScrollEvent::consume-Filter durch einen
gezielten Filter auf dem internen ScrollPane der PDFView-Skin ersetzt.
Der Filter konsumiert nur dann, wenn die Seite keinen ueberlaufenden
Inhalt hat oder der Scroll-Inhalt an der oberen bzw. unteren Grenze
angekommen ist. Dadurch bleibt Inhalts-Scrolling innerhalb einer Seite
weiterhin moeglich; nur der Seitenwechsel per Mausrad wird verhindert.

Bug #29: Platform.runLater() durch eine PauseTransition (100 ms) ersetzt,
die nach dem vollstaendigen Rendering-Durchlauf der PDFView-Skin den
internen ScrollPane explizit auf vValue=0 zuruecksetzt. So wird der
Seitenanfang zuverlaessig angezeigt, ohne dass die Skin die Position
nachtraeglich ueberschreibt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 13:50:43 +02:00
marcus 7e31057bfa Fix #27 und #29: Mausrad-Seitenwechsel und Seitenanfang in PDF-Vorschau
Bug #27: ScrollEvent-Filter auf PDFView verhindert Seitenwechsel durch Mausrad.
Seitenwechsel sind ausschliesslich ueber die Navigations-Buttons moeglich.
Die Seitenzahl wird nur noch bei Button-Klick aktualisiert.

Bug #29: Nach dem Laden einer PDF und bei Seitenwechsel ueber Buttons wird
die Seite jetzt explizit von oben angezeigt. Der setPage()-Aufruf erfolgt
via Platform.runLater() nach dem Layout-Pass, sodass stets der Seitenanfang
sichtbar ist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 13:30:53 +02:00
marcus d3fbfc4094 V2.9: Integrierte PDF-Vorschau und editierbarer Dateiname im Verarbeitungslauf
Neu im Tab "Verarbeitungslauf":
- Integrierte PDF-Vorschau der Quelldatei mit Lazy Rendering (Seite 1 sofort,
  weitere Seiten on-demand), Cache pro Selektion, "latest preview request wins"
- Editierbarer KI-Dateinamenvorschlag mit Live-Validierung, Dirty-State-Dialog
  bei Zeilen-/Tabwechsel, Schließen und Laufstart, atomare FS+DB-Transaktion
  inkl. Rollback und Fingerprint-basierter Konfliktauflösung

Architektur:
- Neuer Application-Use-Case ManualFileRenameUseCase und Outbound-Port
  TargetFileRenamePort mit Filesystem-Adapter
- Neuer GuiManualFileRenamePort, verdrahtet im Bootstrap
- GuiBatchRunResultRow um correctedFileName erweitert
- GuiBatchRunTab auf SplitPane-Layout (60/40) umgebaut, Detail-Panel mit
  KI-Begründung, FileNameEditorPane und PdfPreviewPane
- Spike-Code (PdfViewerSpike) entfernt, produktive Implementierung ersetzt

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:30:55 +02:00
marcus 3a98304a5c Refactoring #19: Benutzerfreundliche deutsche KI-Fehlermeldungen im Begründungsbereich
Neue Klasse AiFailureMessageTranslator übersetzt technische englische
Fehlertexte (z.B. HTTP-Statuscodes, Verbindungsfehler) in lesbare
deutsche Benutzerhinweise. GuiBatchRunTab nutzt den Translator vor der
Anzeige; das Datenmodell (aiFailureMessage) bleibt unverändert.
Unit-Tests decken alle definierten Mapping-Fälle ab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 08:25:46 +02:00
marcus b87e8498e6 Fix #19: Fehlergrund bei fehlgeschlagenem KI-Aufruf im Begründungsbereich anzeigen
- DocumentCompletionEvent um optionales Feld failureMessage erweitert
- DocumentProcessingCoordinator leitet Fehlermeldung bei Fehler-Status durch
- GuiBatchRunResultRow um aiFailureMessage (Optional<String>) ergänzt
- GuiBatchRunCoordinator.toRow() befüllt aiFailureMessage aus dem Event
- GuiBatchRunTab.buildDetailText() zeigt bei fehlendem Reasoning und
  vorhandenem Fehlergrund: "⚠ Fehler: <Meldung>" vor dem Hinweistext
- Alle Tests angepasst und neue Unit-Tests für aiFailureMessage ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 08:17:43 +02:00
marcus 67275eb2f5 Fix #17: Fehler und Warnungen nicht mehr als INFO loggen
Verarbeitungsfehler (PreCheckFailed, AiFunctionalFailure) und
Retry-Entscheidungen (FAILED_RETRYABLE, FAILED_FINAL) werden nun auf
WARN-Level geloggt. EmptyList- und IncompleteConfiguration-Ergebnisse
des Modellabrufs sowie fehlende Quelldateien im Mini-Lauf ebenfalls.
Tests angepasst: Assertions prüfen jetzt das korrekte WARN-Level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 17:58:30 +02:00
marcus e7f5590934 Fix #15: Log-Eintrag am Laufende liest lokale Zähler statt RunSummary
Synthetisierte Fehlzeilen (fehlende Quelldatei) werden nur im lokalen
failedCount gezählt, nicht in RunSummary. Der abschließende Log-Eintrag
verwendete bisher summary.failedCount() und zeigte daher fehlgeschlagen=0
obwohl die GUI-Anzeige korrekt war.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 17:25:00 +02:00
marcus 1df541d0f9 Fix #15: Fehlende Quelldatei beim Mini-Lauf wird korrekt als fehlgeschlagen gezählt
appendSummary verwendete bisher summary.failedCount() aus dem RunSummary-Objekt
des echten Laufs, das von synthesizeMissingSourceFileRows() nachträglich hochgezählte
failedCount nicht kannte. Nun werden die lokalen Zähler (successCount, failedCount,
skippedCount) verwendet, die über onDocumentCompleted und die Synthese konsistent
gepflegt werden. Test ergänzt um Assertion auf '1 fehlgeschlagen' in der Zusammenfassung.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 16:16:39 +02:00
marcus 09605ee495 Fix V2.8: selectedRows-Leerproblem und isRunning()-Inkonsistenz behoben
- markSelectedRowsAsResetPending() schützt selectedRows jetzt mit
  selectionSyncInProgress=true, sodass der TableView-SelectionModel-
  Listener die Selektion nicht löscht, wenn Zeilen ersetzt werden
- isRunning() und updateButtonStates() verwenden runningProperty.get()
  statt coordinator.isRunning() für konsistentes Verhalten zwischen
  Button-Zustand und Selektion
- Diagnose-LOG am Anfang von handleReprocessSelected() gibt isRunning()
  und selectedRows.size() aus (Laufend=false, Selektion>0 erwartet)
- Alle [TEMP-TRACE]-Logs entfernt aus GuiBatchRunCoordinator,
  SqliteUnitOfWorkAdapter, SqliteDocumentRecordRepositoryAdapter
  und DocumentProcessingCoordinator

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-23 15:35:57 +02:00
marcus 55088354ab Diagnoselogs und Test für DB-Reset-Verifikation (FAILED_FINAL)
- [TEMP-TRACE] INFO-Logs in SqliteDocumentRecordRepositoryAdapter:
  deleteByFingerprint() zeigt Fingerprint, jdbcUrl und rowsAffected;
  findByFingerprint() zeigt Fingerprint, jdbcUrl und Lookup-Ergebnis
- [TEMP-TRACE] Log in DocumentProcessingCoordinator.processDeferredOutcome()
  zeigt Fingerprint und Lookup-Ergebnis-Typ nach DB-Abfrage
- Bestehende [TEMP-TRACE] Logs in GuiBatchRunCoordinator und
  SqliteUnitOfWorkAdapter sind ebenfalls enthalten
- Neuer Test resetDocumentByFingerprint_deletesFailedFinalRecord_resultIsDocumentUnknown:
  legt FAILED_FINAL-Datensatz in echter SQLite-DB an, führt Reset aus
  und prüft, dass der Datensatz danach DocumentUnknown zurückliefert

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-23 15:00:22 +02:00
marcus 83f6d63c27 Review-Fix: Korrekte Fehlermeldung bei fehlgeschlagenem DB-Reset
Wenn startReprocessing() false zurückgibt, wurde bisher
ALREADY_RUNNING_HINT angezeigt – obwohl handleReprocessSelected()
isRunning() bereits vorab prüft. Das false bedeutet in diesem Kontext
einen Reset-Fehler, nicht einen laufenden Run.

Neu: REPROCESS_RESET_FAILED_HINT mit erklärender Meldung.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 14:07:37 +02:00
marcus b41b4112c4 V2.8 Fix: „Erneut verarbeiten" setzt DB-Status vor Mini-Lauf zurück
Das Problem: Der „Erneut verarbeiten"-Button startete einen Mini-Lauf,
ohne den DB-Status der selektierten Dateien zurückzusetzen. Dateien mit
FAILED_FINAL-Status wurden daher vom Use Case übersprungen.

Die Lösung:
1. Neue Methode startReprocessing() in GuiBatchRunCoordinator, die
   resetPort.reset() SYNCHRON vor dem Mini-Lauf aufruft.
2. handleReprocessSelected() in GuiBatchRunTab nutzt jetzt
   startReprocessing() statt startMiniRun() direkt.
3. Test-Fix: noOpReset muss die Fingerprints in der erfolgreich-zurückgesetzt-
   Liste enthalten, damit successCount() > 0 ist.

Spec-Konformität:
- Reset erfolgt synchron vor dem Worker-Thread-Start
- Keine neue Architektur-Verletzung
- Hexagonale Architektur bleibt sauber (Port/Adapter)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-23 14:02:45 +02:00
marcus 9fd5bd5a52 V2.8: Selektive Wiederverarbeitung und Statusreset in der GUI
- Mehrfachauswahl mit CheckBox-Spalte und Master-Tri-State-Checkbox
- Gezielter Mini-Lauf über ausgewählte Einträge (unabhängig vom Status)
- Statusreset für ausgewählte Einträge (Stammsatz + Versuchshistorie)
- Fehlende Quelldatei im Mini-Lauf wird als FAILED_PERMANENT synthetisiert
- Identische Zieldatei wird als SUCCESS ohne erneute KI-Verarbeitung erkannt
- Weiche Stop-Semantik erhält zurückgesetzte Einträge unverändert
- Nicht-ausgewählte Einträge bleiben in allen Pfaden unberührt
- Buttons reagieren jetzt korrekt auf Auswahländerungen

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 12:04:22 +02:00
marcus 5d0e2c90bd Fix Issue #13: Warnschwelle für max.title.length auf 10–39 angehoben
Neue Warnschwellen: 10–39 Warnung (Absender benötigt 15–20 Zeichen),
40–99 unkritisch, 100–120 Warnung (verschlüsselte Volumes). Tests,
Validator-Implementierungen, Smoke-Tests und Docs konsistent angepasst.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 08:11:36 +02:00
marcus c7f53416ca Ergaenze fehlende Tests fuer SKIPPED-Statusdurchleitung im GUI-Adapter
Fehlende Testabdeckung fuer den SKIPPED-Pfad: Der Coordinator-Test
verifiziert jetzt, dass SKIPPED-Events als row:SKIPPED:... dispatcht
werden und korrekt in der Zusammenfassung gezaehlt werden. Der
Smoke-Test prueft zusaetzlich, dass die ► Icon (nicht ✘) fuer
SKIPPED-Zeilen in der Ergebnistabelle erscheint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 17:13:33 +02:00
marcus 20a14b3c62 Behebe Darstellungsfehler der Statusicons und Stale-Summary-Bug
Statusicons (Bug 2): Emoji-Codepunkte werden durch BMP-Zeichen ersetzt
(✔ ⚠ ✘ ►), die in JavaFX auf Windows zuverlässig gerendert werden.
Die Statusspalte erhält eine farbige Cell-Factory (grün/orange/rot/grau).

Stale Summary (Bug 1): observerSummary wird zu Beginn jedes Laufs
zurückgesetzt, damit eine abgebrochene Vorgänger-Zusammenfassung
nicht als Ergebnis des neuen Laufs erscheint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 16:27:33 +02:00
marcus f4cfb5cbc0 Ergaenze zweiten GUI-Tab fuer Verarbeitungslauf mit Live-Fortschritt
- Fuehrt neuen Inbound-Adapter-Subpfad batchrun/ mit Tab, Koordinator,
  Launcher-Port und Ergebniszeilen-Model ein; der Batch-Lauf laeuft auf
  einem Hintergrund-Worker, UI-Updates ausschliesslich via FX-Dispatcher.
- Ergaenzt application.port.in um BatchRunProgressObserver,
  BatchRunCancellationToken, DocumentCompletionEvent/-Status und
  RunSummary; DefaultBatchRunProcessingUseCase und
  DocumentProcessingCoordinator melden Lauf-/Dokument-Ereignisse an den
  Beobachter und unterstuetzen Soft-Stop zwischen Kandidaten.
- Verdrahtet BootstrapRunner so, dass die GUI den vollstaendigen
  Headless-Pipelinepfad (Migration, Validierung, Schema-Init, Lock,
  Use-Case) mit Observer und Cancellation ausfuehrt; headless-Verhalten
  bleibt unveraendert.
- Editor-Workspace bettet den zweiten Tab ein, sperrt Tab 1 mit
  Hinweisbanner waehrend eines Laufs und fragt den Benutzer beim
  Schliessen waehrend eines laufenden Batches.
- Fuegt Tests fuer Observer-Wiring, Koordinator-Lebenszyklus und
  Tab-Smoke-Verhalten ein; aktualisiert die GUI-Bedienanleitung und
  docs/betrieb.md auf den neuen Tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:29:06 +02:00
marcus eacc205865 Behebe XML-Parsing-Fehler im Kommentar (doppelte Bindestriche in Kommentaren verboten)
XML-Kommentare dürfen keine Sequenz "--" enthalten. Der vorherige Kommentar
enthielt "--add-opens" was den Parser verwirrt hat.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-22 14:01:38 +02:00
marcus d1fa989016 Entferne veralte --add-opens JavaFX-Module-Argumente aus Surefire
Java 21 mit modernem JavaFX (21.x) und Monocle benötigt die expliziten
--add-opens Argumente für javafx.graphics nicht mehr. Diese Argumente
verursachten "Unknown module" Warnungen beim Build, da die JavaFX-Module
in headless Tests nicht als benannte Module vorhanden sind.

Mit deren Entfernung ist der Build sauberer und alle Tests bestehen weiterhin.
Die verbleibende JavaFX-Warnung "Unsupported JavaFX configuration" ist
unvermeidlich und harmlos bei Monocle-Tests.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-22 13:58:09 +02:00
marcus 4875a1ed42 Fix doppelte API-Key-Meldung: originLabel zeigt nur noch ENV-Hinweis
Der API-Key-Herkunfts-Label (apiKeyOriginLabel) zeigte bisher sowohl
INFO-Befunde (Schlüssel kommt aus Umgebungsvariable) als auch
WARNING/ERROR-Befunde (Schlüssel fehlt) an. Da das fieldErrorLabel
direkt darunter dieselben WARNING/ERROR-Befunde bereits anzeigt,
erschien die „Kein API-Key"-Meldung zweimal im selben Bereich.

Lösung: refreshApiKeyOriginLabels() wertet nur noch INFO-Befunde aus.
WARNING/ERROR-Befunde für fehlende API-Keys werden ausschließlich vom
fieldErrorLabel angezeigt. STYLE_ORIGIN_MISSING entfernt.

Drei neue Smoke-Tests sichern das Verhalten ab:
- apiKeyAbsent_originLabelHidden
- apiKeyAbsent_fieldErrorLabelVisible
- apiKeyAbsent_noDuplicateMessageInPendingMessages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 13:42:18 +02:00
marcus 8884d15e69 Ändere Standard-Default für max.text.characters von 5000 auf 1000
Der bisherige Standard-Default von 5000 Zeichen löste gemäß Spezifikation
sofort eine starke Warnung in der GUI aus (Schwellenwert: >3000).
Dies ist nicht benutzerfreundlich.

Der neue Standard-Default ist 1000 Zeichen (unkritisch laut Spec).
Das entspricht einer besseren Balance zwischen KI-Input-Größe und
Benutzerwarnung beim Start.

Änderungen:
- GuiConfigurationTemplateFactory: Standardvorlage auf 1000 geändert
- Alle *.properties-Beispieldateien aktualisiert
- Dokumentation in gui-bedienanleitung.md ergänzt
- Betroffene Tests angepasst (etwa 10 Testdateien)
- Alle 206 Tests bestehen nach der Änderung

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-22 12:44:09 +02:00
marcus 13e4922272 Meldungsbereich: Button linksbündig; leeren bei Validieren und Techn. Tests
- clearMessagesButton ist jetzt linksbündig (CENTER_LEFT statt CENTER_RIGHT)
- pendingMessages.clear() wird auch am Anfang von runValidationAction() und
  runTechnicalTestsAction() aufgerufen; jeder Durchlauf zeigt nur seine eigenen
  Befunde
- GuiValidateActionSmokeTest: Erwartung von 2 auf 1 Bestätigungsmeldung nach
  zwei Klicks angepasst (Replace- statt Akkumulierungsverhalten)
- Zwei neue Smoke-Tests: validationAction_clearsPreviousMessages und
  technicalTestsAction_clearsPreviousMessages
- Dokumentation in docs/gui-bedienanleitung.md ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 11:54:14 +02:00
marcus 1996f31f43 Meldungsbereich: leeren bei Neu/Öffnen und Button zum manuellen Leeren
- pendingMessages wird in applyEditorState() geleert, bevor die neue
  Konfiguration angezeigt wird (gilt für Neu und Öffnen)
- Neuer Button "Meldungen leeren" unterhalb des Meldungsbereichs;
  ruft clearMessages() auf, das pendingMessages leert und die Ansicht
  aktualisiert
- Dokumentation in docs/gui-bedienanleitung.md ergänzt
- Zwei neue Smoke-Tests: Neu löscht bisherige Meldungen,
  clearMessages() leert den Bereich vollständig

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 11:33:13 +02:00
marcus e07b460cdd Meldungen können nun in die Zwischenablage kopiert werden. 2026-04-22 11:23:44 +02:00
marcus 8286d0f0e5 Titellänge nun parametrisierbar 2026-04-22 09:53:03 +02:00
marcus 8be1848ba9 Fix: Verarbeitung von PROPOSAL_READY bis SUCCESS in einem Lauf; log4j-core im GUI-Test-Classpath
Der Dokument-Processing-Coordinator finalisiert jetzt unmittelbar nach dem
Persistieren des PROPOSAL_READY-Versuchs im selben Lauf zur Zielkopie und zu
SUCCESS. Die Invariante "neuester PROPOSAL_READY-Versuch ist die fuehrende
Quelle" bleibt gewahrt: Pro Lauf entstehen zwei Historieneintraege
(PROPOSAL_READY, dann SUCCESS). Bootstrap-E2E-Tests auf Single-Run-Semantik
angepasst; die "kein neuer KI-Aufruf bei vorhandenem PROPOSAL_READY"-Invariante
ist weiterhin im Application-Unit-Test abgedeckt.

Zusaetzlich log4j-core als Test-Scope-Abhaengigkeit im GUI-Modul ergaenzt,
damit die "Log4j2 could not find a logging implementation"-Warnung im
Testlauf nicht mehr erscheint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 17:26:21 +02:00
marcus ada7e203e3 GUI-Bugfixes: Defaults beim Start, kopierbare Meldungen mit Zeitstempel, Befundauflistung, Modell-ComboBox links, effektiver API-Key für Modellabruf
- Blank-Startzustand zeigt jetzt die Standardvorlage (wie nach "Neu"), neue Factory createEmptyStartState für Tests
- Meldungsbereich ist per Kontextmenü bzw. Strg+C kopierbar
- Jede Meldung trägt ein führendes [HH:mm:ss]-Präfix
- Validieren- und Tests-Aktionen akkumulieren Meldungen, automatische Validierung ersetzt still ihre Einträge
- Validieren-Meldung listet alle konkreten Befunde einzeln auf
- Modell-ComboBox und manuelles Modellfeld sind linksbündig
- ApiKeyResolutionPort liefert jetzt den effektiven API-Schlüsselwert (Default + Env-Adapter-Override), so dass der Modellliste-Test in den technischen Tests nicht mehr "API-Schlüssel fehlt" meldet, obwohl er gesetzt ist
2026-04-21 16:04:15 +02:00
van Elst, Marcus 6babdd226e Source code cleanup 2026-04-21 10:38:16 +02:00
van Elst, Marcus 202088d1d3 Removed unused imports 2026-04-21 10:31:47 +02:00
marcus 523774707b PIT auf Domain und Application beschränken 2026-04-21 06:06:45 +02:00
marcus 016da8318d M13 vollständig abgeschlossen: V2.0-Freigabe (AP-001 bis AP-009)
- 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>
2026-04-20 22:50:51 +02:00
marcus 1bb7a42735 M12 vollständig abgeschlossen (AP-001 bis AP-008)
- AP-001: Prüf- und Korrektur-Kernobjekte (CheckpointId, CheckpointResult
  sealed interface, TechnicalTestReport mit Correction-Plan-Ableitung,
  CorrectionSuggestion sealed interface, PathCheckPort, ResourceCreationPort)
- AP-002: Aktion "Validieren" als explizite, nicht schreibende Gesamtprüfung
  des aktuellen Editorzustands
- AP-003: Provider-nahe technische Prüflogik für Endpoint, API-Key,
  Modellliste und Modellplausibilität — wiederverwendet den bestehenden
  Modellabruf-Port, kein zweiter HTTP-Pfad
- AP-004: Windows-Pfadprüfung mit ausdrücklicher Unterstützung gemappter
  Laufwerksbuchstaben (FilesystemPathCheckAdapter)
- AP-005: Aktion "Technische Tests ausführen" als vollständiger Gesamttest
  ohne Frühabbruch, Orchestrator sammelt Befunde aller Prüfblöcke
- AP-006: Schreibende Korrekturhilfen mit gesammeltem Bestätigungsdialog,
  CorrectionExecutionService, FilesystemResourceCreationAdapter
- AP-007: Automatische deutsche Standard-Prompt-Datei-Erzeugung,
  Default-Pfad neben der .properties-Datei, klare Fehlermeldung bei
  nicht beschreibbarem Zielpfad
- AP-008: Regressionstests für Gesamttest ohne Frühabbruch, ungespeicherte
  Editorzustände, Korrekturdialog, Prompt-Erzeugung, Windows-Pfade

Hexagonale Architektur durchgehend eingehalten, Domain und Application
bleiben infrastrukturfrei. Threadingmodell konsequent umgesetzt.
Naming-Regel und JavaDoc-Standard eingehalten.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-20 21:57:06 +02:00
marcus aa067a3165 M11 vollständig abgeschlossen (AP-001 bis AP-007)
- AP-001: Kernobjekte und Port-Verträge (ModelCatalog-Port, sealed
  Result-Typen, ApiKeyOrigin, GUI-Modell- und Meldungs-Records)
- AP-002: Provider-ComboBox, exklusiver Providerbereich,
  zustandsbewahrender Providerwechsel
- AP-003: HTTP-Adapter für Modellabruf (Claude, OpenAI-kompatibel)
  mit vollständigem Error-Mapping und Dispatcher im Bootstrap
- AP-004: Automatischer Modellabruf bei Providerwechsel, Aktion
  "Modelle neu laden", Umschaltung zwischen Modell-ComboBox und
  Modell-Textfeld, Worker-Thread-Kapselung
- AP-005: Automatische Editorvalidierung (Pflichtfelder,
  Warnschwellen max.text.characters, Plausibilitätshinweise
  max.pages, API-Key-Herkunftsauflösung mit Vorrangregel)
- AP-006: Zentraler Meldungsbereich mit vier Severity-Stufen,
  feldnahe rote Fehlermeldungen, API-Key-Herkunftsanzeige
- AP-007: Integrations- und Regressionstests, Timeout-Mapping-Tests,
  Replace-Semantik für wiederholte Modellabruf-Meldungen

Hexagonale Architektur eingehalten, Application- und Domain-Schicht
bleiben infrastrukturfrei. Threadingmodell konsequent umgesetzt.
Naming-Regel und JavaDoc-Standard durchgängig beachtet.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-20 20:31:15 +02:00
marcus bbb5c4da3a M10 vollständig abgeschlossen (AP-004 bis AP-007)
- AP-004: Speichern und Speichern unter mit .bak-Rotation,
  normalisierte .properties-Ausgabe, API-Key-Erhaltung bei leerem Feld
- AP-005: Dirty-State aus Editorzustand, Fenstertitel- und
  Header-Marker, Schutzdialog (Speichern/Verwerfen/Abbrechen)
  vor Neu/Öffnen/Schließen inkl. Close-Request-Handler
- AP-006: Vollständige Editoroberfläche mit allen Konfigurationswerten,
  native Pfad-Picker für Quell-/Zielordner, SQLite- und Prompt-Datei,
  Files.exists-Pfadprüfung auf Worker-Thread verlagert
- AP-007: Integrations- und Regressionstests für alle zentralen
  Bedienpfade, Writer-Threading-Contract dokumentiert und getestet

Hexagonale Architektur, Threadingmodell und Naming-Regel durchgehend
eingehalten. Keine Vorgriffe auf M11/M12.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-20 17:51:13 +02:00
marcus 01414fc732 M10 bis AP-003 2026-04-20 13:07:19 +02:00
marcus 20b847d821 M10, AP-001 freigegeben 2026-04-20 12:29:14 +02:00
marcus 3f149b2017 Erweiterung für V2.0: M9 umgesetzt 2026-04-13 13:36:54 +02:00