Kleinere Korrekturen
This commit is contained in:
332
docs/specs/V1.1 - Ist-Stand.md
Normal file
332
docs/specs/V1.1 - Ist-Stand.md
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
# V1.1 – Ist-Stand des PDF-Umbenenners
|
||||||
|
|
||||||
|
## Zweck dieses Dokuments
|
||||||
|
|
||||||
|
Dieses Dokument beschreibt den **tatsächlichen Ist-Stand der Software bis einschließlich V1.1**.
|
||||||
|
Es ergänzt die bestehenden Spezifikations- und Projektdokumente um den konkret erreichten Erweiterungsstand nach der vollständig umgesetzten und freigegebenen V1.
|
||||||
|
|
||||||
|
Ziel ist, dass eine KI oder ein Entwickler zusammen mit den übrigen Repository-Dokumenten den aktuellen Funktionsumfang und die Architektur **präzise und ohne Rückgriff auf Chat-Verläufe** verstehen kann.
|
||||||
|
|
||||||
|
Dieses Dokument ist **kein Soll-Konzept** und **kein neues Arbeitspaket**, sondern eine Beschreibung des erreichten Stands.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Einordnung des Stands
|
||||||
|
|
||||||
|
### Ausgangsbasis
|
||||||
|
|
||||||
|
Vor V1.1 lag eine vollständig umgesetzte, getestete, dokumentierte und freigegebene **V1** des Projekts vor.
|
||||||
|
Diese V1 entsprach dem Umsetzungsstand der Meilensteine **M1 bis M8**.
|
||||||
|
|
||||||
|
Damit war insbesondere bereits vorhanden:
|
||||||
|
|
||||||
|
- vollständiges Maven-Multi-Module-Projekt
|
||||||
|
- strikte hexagonale Architektur
|
||||||
|
- Batch-Verarbeitung über Standalone-JAR
|
||||||
|
- PDF-Erkennung und PDF-Textauslese
|
||||||
|
- SQLite-Persistenz
|
||||||
|
- Retry-, Skip- und Statuslogik
|
||||||
|
- KI-gestützte Ermittlung eines Benennungsvorschlags
|
||||||
|
- Dateinamensbildung und Zielkopie
|
||||||
|
- Logging, Qualitätsabsicherung, Dokumentation und Freigabestand
|
||||||
|
|
||||||
|
### Ziel von V1.1
|
||||||
|
|
||||||
|
V1.1 wurde bewusst **klein und minimal-invasiv** definiert.
|
||||||
|
|
||||||
|
Es handelt sich **nicht** um einen allgemeinen V2-Ausbau und **nicht** um einen Produktumbau mit GUI, Installer oder EXE.
|
||||||
|
|
||||||
|
Der Fokus von V1.1 ist ausschließlich:
|
||||||
|
|
||||||
|
- Erweiterung der bestehenden KI-Anbindung um **native Claude-Unterstützung**
|
||||||
|
- gleichzeitiger Erhalt des bisherigen **OpenAI-kompatiblen Wegs**
|
||||||
|
- Mehrprovider-Konfiguration mit **genau einem aktiven Provider**
|
||||||
|
- Wahrung der bestehenden Architekturprinzipien
|
||||||
|
- Wahrung der fachlichen und technischen Regeln aus V1
|
||||||
|
- Abwärtskompatibilität bestehender Konfigurationen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Inhaltlicher Umfang von V1.1
|
||||||
|
|
||||||
|
V1.1 erweitert die bestehende Anwendung um eine **Mehrprovider-fähige KI-Konfiguration**, bei der genau **ein Provider aktiv** ist.
|
||||||
|
|
||||||
|
### In V1.1 enthalten
|
||||||
|
|
||||||
|
- Unterstützung von **zwei real nutzbaren KI-Providern**
|
||||||
|
- OpenAI-kompatibler Provider
|
||||||
|
- nativer Claude-Provider
|
||||||
|
- Properties-basierte Konfiguration für mehrere Provider
|
||||||
|
- Auswahl genau **eines aktiven Providers**
|
||||||
|
- Beibehaltung des bisherigen fachlichen KI-Vertrags
|
||||||
|
- Integration der Providerwahl in die bestehende technische Konfiguration
|
||||||
|
- Migration alter V1-Konfigurationen auf die neue Struktur
|
||||||
|
- Sicherung alter Konfigurationen über `.bak`
|
||||||
|
- vollständige Tests und Nachschärfung der Build-/Qualitätshygiene
|
||||||
|
|
||||||
|
### In V1.1 ausdrücklich **nicht** enthalten
|
||||||
|
|
||||||
|
- GUI
|
||||||
|
- Installer
|
||||||
|
- EXE-Paketierung
|
||||||
|
- mehrere Profile pro Provider
|
||||||
|
- automatischer Fallback zwischen Providern
|
||||||
|
- neue fachliche Regeln für Dateinamen
|
||||||
|
- neue Retry-Semantik
|
||||||
|
- neue Statussemantik
|
||||||
|
- neue Persistenz-Wahrheiten
|
||||||
|
- Änderungen am Grundprinzip des Batch-Betriebs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fachlich-technische Kernaussage von V1.1
|
||||||
|
|
||||||
|
Die Anwendung verarbeitet weiterhin OCR-verarbeitete PDF-Dateien lokal und erzeugt daraus im Erfolgsfall korrekt benannte Zielkopien.
|
||||||
|
|
||||||
|
Der Unterschied zu V1 ist:
|
||||||
|
|
||||||
|
> Die Ermittlung des KI-basierten Benennungsvorschlags kann nun wahlweise
|
||||||
|
> über einen **OpenAI-kompatiblen Provider** oder über die **native Claude-API**
|
||||||
|
> erfolgen.
|
||||||
|
|
||||||
|
Dabei bleibt für den restlichen fachlichen Ablauf entscheidend:
|
||||||
|
|
||||||
|
- der Input bleibt ein aufbereiteter Dokumenttext
|
||||||
|
- die KI liefert weiterhin denselben fachlichen Vorschlagsinhalt
|
||||||
|
- der restliche Verarbeitungsfluss bleibt unverändert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unveränderte Regeln aus V1
|
||||||
|
|
||||||
|
V1.1 ändert **nicht** die fachlichen Kernregeln des Systems.
|
||||||
|
|
||||||
|
Insbesondere unverändert bleiben:
|
||||||
|
|
||||||
|
- Zielformat: `YYYY-MM-DD - Titel.pdf`
|
||||||
|
- Dublettenregel `(1)`, `(2)`, …
|
||||||
|
- 20-Zeichen-Regel für den Basistitel
|
||||||
|
- deutsche, verständliche Titel
|
||||||
|
- Quelldatei bleibt unverändert
|
||||||
|
- Fingerprint-basierte Identifikation
|
||||||
|
- SQLite als lokaler Persistenzspeicher
|
||||||
|
- Retry- und Skip-Regeln
|
||||||
|
- Statusmodell
|
||||||
|
- Run-Lock
|
||||||
|
- Start über Standalone-JAR / Task Scheduler
|
||||||
|
- keine Dauerlauf-Anwendung
|
||||||
|
- keine GUI / kein Webserver / kein App-Server
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architekturstand in V1.1
|
||||||
|
|
||||||
|
V1.1 wahrt die bestehende Architektur.
|
||||||
|
|
||||||
|
### Unverändert gültig
|
||||||
|
|
||||||
|
- strikte hexagonale Architektur
|
||||||
|
- Ports and Adapters
|
||||||
|
- Abhängigkeiten zeigen nach innen
|
||||||
|
- keine Infrastruktur im Domain-Kern
|
||||||
|
- keine direkte Adapter-zu-Adapter-Kopplung
|
||||||
|
- Logging bleibt technische Infrastruktur
|
||||||
|
- Konfiguration bleibt technische Infrastruktur
|
||||||
|
- Bootstrap verdrahtet die konkrete Laufzeitumgebung
|
||||||
|
|
||||||
|
### Bedeutung für die KI-Integration
|
||||||
|
|
||||||
|
Die Mehrprovider-Fähigkeit wird **architekturtreu** eingeführt:
|
||||||
|
|
||||||
|
- der fachliche/application-seitige KI-Vertrag bleibt erhalten
|
||||||
|
- die Provider-spezifischen Unterschiede liegen in den technischen Adaptern
|
||||||
|
- die konkrete Providerauswahl erfolgt über Konfiguration und Bootstrap
|
||||||
|
- es entsteht keine provider-spezifische Fachlogik im Kern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KI-Provider in V1.1
|
||||||
|
|
||||||
|
### Unterstützte Provider
|
||||||
|
|
||||||
|
V1.1 unterstützt genau diese zwei Providerarten:
|
||||||
|
|
||||||
|
1. **OpenAI-kompatibel**
|
||||||
|
2. **Claude nativ**
|
||||||
|
|
||||||
|
### Aktiver Provider
|
||||||
|
|
||||||
|
Es gibt immer **genau einen aktiven Provider**.
|
||||||
|
|
||||||
|
V1.1 führt **keinen** automatischen Fallback zwischen Providern ein.
|
||||||
|
Wenn der aktive Provider fehlschlägt, gilt der bestehende Fehler- und Retry-Rahmen.
|
||||||
|
|
||||||
|
### Keine Profilverwaltung
|
||||||
|
|
||||||
|
Pro Provider gibt es in V1.1 genau **eine** Konfiguration.
|
||||||
|
Benannte Profile oder mehrere alternative Konfigurationssätze pro Provider sind nicht Bestandteil von V1.1.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KI-Vertrag bleibt unverändert
|
||||||
|
|
||||||
|
V1.1 ändert **nicht** den fachlichen Ergebnisvertrag der KI.
|
||||||
|
|
||||||
|
Die Erweiterung betrifft den technischen Zugriffsweg auf die KI, **nicht** den fachlichen Inhalt der KI-Antwort.
|
||||||
|
|
||||||
|
Damit bleibt der Grundsatz bestehen:
|
||||||
|
|
||||||
|
- die KI liefert denselben fachlichen Vorschlagsinhalt wie zuvor
|
||||||
|
- die Anwendung behält die Hoheit über Validierung, Datumsauflösung, Titelregeln und weitere technische Verarbeitung
|
||||||
|
- der restliche Systemablauf bleibt gegenüber V1 stabil
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfigurationsmodell in V1.1
|
||||||
|
|
||||||
|
### Allgemeiner Grundsatz
|
||||||
|
|
||||||
|
Die `.properties`-Datei bleibt die **Wahrheit** der Konfiguration.
|
||||||
|
|
||||||
|
### Erweiterung in V1.1
|
||||||
|
|
||||||
|
Die Konfiguration kann nun mehrere Provider-Konfigurationen enthalten, von denen genau **eine aktiv** ist.
|
||||||
|
|
||||||
|
### Abwärtskompatibilität
|
||||||
|
|
||||||
|
Bestehende V1-Konfigurationen bleiben nutzbar.
|
||||||
|
|
||||||
|
Dazu wurde in V1.1 vorgesehen:
|
||||||
|
|
||||||
|
- Erkennung alter Konfigurationsstruktur
|
||||||
|
- Migration auf die neue Struktur beim ersten Start
|
||||||
|
- vorherige Anlage einer Sicherung mit `.bak`
|
||||||
|
|
||||||
|
### Legacy-Kompatibilität beim API-Key
|
||||||
|
|
||||||
|
Für den OpenAI-kompatiblen Provider wurde die Abwärtskompatibilität auch für bestehende API-Key-Setups beibehalten.
|
||||||
|
|
||||||
|
Die Auflösung erfolgt in dieser Reihenfolge:
|
||||||
|
|
||||||
|
1. spezifische Umgebungsvariable für den OpenAI-kompatiblen Provider
|
||||||
|
2. bisherige Legacy-Umgebungsvariable
|
||||||
|
3. Property-basierter API-Key
|
||||||
|
|
||||||
|
Dadurch brechen bestehende Setups nicht still.
|
||||||
|
|
||||||
|
### Strikte Provider-Validierung
|
||||||
|
|
||||||
|
Die Konfiguration des aktiven Providers wird vor dem eigentlichen Lauf sauber validiert.
|
||||||
|
|
||||||
|
Dazu gehört insbesondere die Base-URL-Prüfung:
|
||||||
|
|
||||||
|
- syntaktisch gültige URI
|
||||||
|
- absolute URI
|
||||||
|
- nur `http` oder `https`
|
||||||
|
|
||||||
|
Ungültige Provider-Konfiguration ist eine ungültige Startkonfiguration und verhindert den Laufbeginn.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Persistenz und Nachvollziehbarkeit
|
||||||
|
|
||||||
|
Das bestehende Zwei-Ebenen-Modell bleibt erhalten:
|
||||||
|
|
||||||
|
- Dokument-Stammsatz
|
||||||
|
- Versuchshistorie
|
||||||
|
|
||||||
|
V1.1 führt **keine neue Persistenz-Wahrheit** ein.
|
||||||
|
|
||||||
|
Die durch V1 etablierten Regeln zu Status, Retry, Zielerfolg, Proposal-Quelle und Historisierung bleiben in Kraft.
|
||||||
|
|
||||||
|
Die Erweiterung um mehrere Provider dient der technisch sauberen Mehrprovider-Nutzung und der konsistenten Nachvollziehbarkeit des verwendeten Providers im Rahmen der bestehenden Architektur.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Qualitäts- und Stabilisierungsschritte nach der V1.1-Implementierung
|
||||||
|
|
||||||
|
Nach der funktionalen Einführung von V1.1 wurde der Stand zusätzlich qualitativ nachgeschärft.
|
||||||
|
|
||||||
|
Diese Nachschärfungen gehören zum erreichten Ist-Stand.
|
||||||
|
|
||||||
|
### 1. Rückwärtskompatibilität und Provider-Validierung
|
||||||
|
|
||||||
|
Es wurden Korrekturen durchgeführt für:
|
||||||
|
|
||||||
|
- Legacy-Fallback beim OpenAI-kompatiblen API-Key
|
||||||
|
- strikte Validierung der Provider-Base-URL
|
||||||
|
- Sicherstellung, dass alte Setups nicht still brechen
|
||||||
|
|
||||||
|
### 2. Dokumentation
|
||||||
|
|
||||||
|
Es wurde eine README für das Repository ergänzt, damit der Projektstand und die Grundbenutzung nachvollziehbar dokumentiert sind.
|
||||||
|
|
||||||
|
### 3. Compiler-, Test- und Build-Hygiene
|
||||||
|
|
||||||
|
Es wurden mehrere kleinere Qualitätskorrekturen durchgeführt, unter anderem:
|
||||||
|
|
||||||
|
- Bereinigung von Raw-Type-/Unchecked-Warnungen in Tests
|
||||||
|
- Beseitigung veralteter API-Nutzung in Bootstrap-Testhilfen
|
||||||
|
- Bereinigung des Logging-Klassenpfads im Testkontext
|
||||||
|
- bewusste Konfiguration des Annotation Processings
|
||||||
|
|
||||||
|
### 4. Mutationstest- und Build-Verbesserungen
|
||||||
|
|
||||||
|
Die Qualität des Test- und PIT-Stands wurde gezielt verbessert, insbesondere in:
|
||||||
|
|
||||||
|
- `adapter-out`
|
||||||
|
- `bootstrap`
|
||||||
|
|
||||||
|
Zusätzlich wurde ein PIT-Timeout bereinigt, das durch einen langsamen Integrationstest mit Netzwerkaufruf verursacht wurde.
|
||||||
|
|
||||||
|
### 5. Bewertung verbliebener Build-Hinweise
|
||||||
|
|
||||||
|
Verbleibende Log4j2-/Shade-Hinweise wurden geprüft und als funktional unkritisch eingeordnet, soweit sie keine reale Auswirkung auf den Produktivbetrieb haben.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ergebnisstatus von V1.1
|
||||||
|
|
||||||
|
V1.1 ist als **fertiger, implementierter und getesteter Ist-Stand** zu verstehen.
|
||||||
|
|
||||||
|
Das bedeutet:
|
||||||
|
|
||||||
|
- die Erweiterung ist umgesetzt
|
||||||
|
- die Erweiterung ist in die bestehende Architektur eingebettet
|
||||||
|
- die relevanten Qualitäts- und Stabilitätskorrekturen wurden nachgezogen
|
||||||
|
- der Projektstand nach V1.1 ist gegenüber V1 fachlich stabil erweitert und technisch nachgeschärft
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verhältnis zu den übrigen Repository-Dokumenten
|
||||||
|
|
||||||
|
Dieses Dokument ersetzt **nicht** die bestehenden Spezifikationsdokumente.
|
||||||
|
|
||||||
|
Es ergänzt sie um die Aussage:
|
||||||
|
|
||||||
|
> **Was ist nach Abschluss von V1.1 zusätzlich tatsächlich vorhanden?**
|
||||||
|
|
||||||
|
Für eine vollständige Einordnung bleiben weiterhin maßgeblich:
|
||||||
|
|
||||||
|
- `CLAUDE.md`
|
||||||
|
- `docs/specs/technik-und-architektur.md`
|
||||||
|
- `docs/specs/fachliche-anforderungen.md`
|
||||||
|
- `docs/specs/meilensteine.md`
|
||||||
|
|
||||||
|
Dieses Dokument beschreibt den **erreichten zusätzlichen Ist-Zustand bis einschließlich V1.1**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kompakte Zusammenfassung für KI-Systeme
|
||||||
|
|
||||||
|
Wenn eine KI diesen Stand kurz einordnen soll, gilt:
|
||||||
|
|
||||||
|
- V1 des `pdf-umbenenner` war vollständig umgesetzt und freigegeben
|
||||||
|
- V1.1 ist eine **kleine, minimal-invasive Erweiterung**
|
||||||
|
- V1.1 fügt **native Claude-Unterstützung** hinzu
|
||||||
|
- der bisherige **OpenAI-kompatible Weg bleibt erhalten**
|
||||||
|
- die Konfiguration unterstützt mehrere Provider, aber **genau einen aktiven Provider**
|
||||||
|
- bestehende Konfigurationen bleiben per Migration und Legacy-Fallback kompatibel
|
||||||
|
- fachliche Regeln, Architekturprinzipien und Kernverhalten aus V1 bleiben unverändert
|
||||||
|
- nach der Implementierung wurden zusätzliche Qualitäts-, Build- und Testhygiene-Maßnahmen durchgeführt
|
||||||
|
- der Ist-Zustand des Projekts umfasst damit **V1 + V1.1**
|
||||||
@@ -248,23 +248,6 @@ public class StartConfigurationValidator {
|
|||||||
|
|
||||||
// === Helper methods for common validation patterns ===
|
// === Helper methods for common validation patterns ===
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates that a required directory path is not null, exists, and is a directory.
|
|
||||||
* <p>
|
|
||||||
* Used for paths like source and target folders that must already exist before processing can begin.
|
|
||||||
*/
|
|
||||||
private void validateRequiredExistingDirectory(Path path, String fieldName, List<String> errors) {
|
|
||||||
if (path == null) {
|
|
||||||
errors.add("- " + fieldName + ": must not be null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Files.exists(path)) {
|
|
||||||
errors.add("- " + fieldName + ": path does not exist: " + path);
|
|
||||||
} else if (!Files.isDirectory(path)) {
|
|
||||||
errors.add("- " + fieldName + ": path is not a directory: " + path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates that a required file path is not null and its parent directory exists and is a directory.
|
* Validates that a required file path is not null and its parent directory exists and is a directory.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -324,14 +307,13 @@ public class StartConfigurationValidator {
|
|||||||
* or exists and is a directory.
|
* or exists and is a directory.
|
||||||
*/
|
*/
|
||||||
private void validateOptionalExistingDirectory(Path directoryPath, String fieldName, List<String> errors) {
|
private void validateOptionalExistingDirectory(Path directoryPath, String fieldName, List<String> errors) {
|
||||||
if (directoryPath != null && !directoryPath.toString().isBlank()) {
|
if (directoryPath != null && !directoryPath.toString().isBlank() && Files.exists(directoryPath)) {
|
||||||
if (Files.exists(directoryPath)) {
|
|
||||||
if (!Files.isDirectory(directoryPath)) {
|
if (!Files.isDirectory(directoryPath)) {
|
||||||
errors.add("- " + fieldName + ": exists but is not a directory: " + directoryPath);
|
errors.add("- " + fieldName + ": exists but is not a directory: " + directoryPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If it doesn't exist yet, that's acceptable - we don't auto-create
|
// If it doesn't exist yet, that's acceptable - we don't auto-create
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ import java.nio.file.Paths;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import de.gecheckt.pdf.umbenenner.application.config.provider.MultiProviderConfiguration;
|
import de.gecheckt.pdf.umbenenner.application.config.provider.MultiProviderConfiguration;
|
||||||
import de.gecheckt.pdf.umbenenner.application.config.startup.StartConfiguration;
|
import de.gecheckt.pdf.umbenenner.application.config.startup.StartConfiguration;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.ConfigurationPort;
|
import de.gecheckt.pdf.umbenenner.application.port.out.ConfigurationPort;
|
||||||
@@ -28,7 +25,6 @@ import de.gecheckt.pdf.umbenenner.application.port.out.ConfigurationPort;
|
|||||||
*/
|
*/
|
||||||
public class PropertiesConfigurationPortAdapter implements ConfigurationPort {
|
public class PropertiesConfigurationPortAdapter implements ConfigurationPort {
|
||||||
|
|
||||||
private static final Logger LOG = LogManager.getLogger(PropertiesConfigurationPortAdapter.class);
|
|
||||||
private static final String DEFAULT_CONFIG_FILE_PATH = "config/application.properties";
|
private static final String DEFAULT_CONFIG_FILE_PATH = "config/application.properties";
|
||||||
|
|
||||||
private final Function<String, String> environmentLookup;
|
private final Function<String, String> environmentLookup;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ package de.gecheckt.pdf.umbenenner.application.port.out;
|
|||||||
*/
|
*/
|
||||||
public class DocumentPersistenceException extends RuntimeException {
|
public class DocumentPersistenceException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8362115097253107643L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@code DocumentPersistenceException} with the given message.
|
* Constructs a new {@code DocumentPersistenceException} with the given message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.ClockPort;
|
import de.gecheckt.pdf.umbenenner.application.port.out.ClockPort;
|
||||||
import de.gecheckt.pdf.umbenenner.application.service.AiResponseValidator.AiValidationResult;
|
|
||||||
import de.gecheckt.pdf.umbenenner.domain.model.AiErrorClassification;
|
import de.gecheckt.pdf.umbenenner.domain.model.AiErrorClassification;
|
||||||
import de.gecheckt.pdf.umbenenner.domain.model.DateSource;
|
import de.gecheckt.pdf.umbenenner.domain.model.DateSource;
|
||||||
import de.gecheckt.pdf.umbenenner.domain.model.NamingProposal;
|
import de.gecheckt.pdf.umbenenner.domain.model.NamingProposal;
|
||||||
|
|||||||
@@ -1339,8 +1339,6 @@ class DocumentProcessingCoordinatorTest {
|
|||||||
private final CapturingDocumentRecordRepository recordRepo;
|
private final CapturingDocumentRecordRepository recordRepo;
|
||||||
private final CapturingProcessingAttemptRepository attemptRepo;
|
private final CapturingProcessingAttemptRepository attemptRepo;
|
||||||
boolean failOnExecute = false;
|
boolean failOnExecute = false;
|
||||||
Consumer<TransactionOperations> lastOperations = null;
|
|
||||||
|
|
||||||
CapturingUnitOfWorkPort(CapturingDocumentRecordRepository recordRepo,
|
CapturingUnitOfWorkPort(CapturingDocumentRecordRepository recordRepo,
|
||||||
CapturingProcessingAttemptRepository attemptRepo) {
|
CapturingProcessingAttemptRepository attemptRepo) {
|
||||||
this.recordRepo = recordRepo;
|
this.recordRepo = recordRepo;
|
||||||
@@ -1349,7 +1347,6 @@ class DocumentProcessingCoordinatorTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeInTransaction(Consumer<TransactionOperations> operations) {
|
public void executeInTransaction(Consumer<TransactionOperations> operations) {
|
||||||
this.lastOperations = operations;
|
|
||||||
if (failOnExecute) {
|
if (failOnExecute) {
|
||||||
throw new DocumentPersistenceException("Simulated transaction failure");
|
throw new DocumentPersistenceException("Simulated transaction failure");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1488,7 +1488,6 @@ class BatchRunProcessingUseCaseTest {
|
|||||||
private static class CapturingProcessingLogger implements ProcessingLogger {
|
private static class CapturingProcessingLogger implements ProcessingLogger {
|
||||||
int infoCallCount = 0;
|
int infoCallCount = 0;
|
||||||
int debugCallCount = 0;
|
int debugCallCount = 0;
|
||||||
int debugSensitiveAiContentCallCount = 0;
|
|
||||||
int warnCallCount = 0;
|
int warnCallCount = 0;
|
||||||
int errorCallCount = 0;
|
int errorCallCount = 0;
|
||||||
|
|
||||||
@@ -1504,7 +1503,6 @@ class BatchRunProcessingUseCaseTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void debugSensitiveAiContent(String message, Object... args) {
|
public void debugSensitiveAiContent(String message, Object... args) {
|
||||||
debugSensitiveAiContentCallCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -94,7 +94,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>${maven-failsafe-plugin.version}</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ class BootstrapRunnerEdgeCasesTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createRunContext_generatesUniqueRunId() throws Exception {
|
void createRunContext_generatesUniqueRunId() throws Exception {
|
||||||
// While we can't directly call the private createRunContext method,
|
new StartConfiguration(
|
||||||
// we can verify its effects through BatchRunContext behavior
|
|
||||||
StartConfiguration mockConfig = new StartConfiguration(
|
|
||||||
Files.createDirectories(tempDir.resolve("source")),
|
Files.createDirectories(tempDir.resolve("source")),
|
||||||
Files.createDirectories(tempDir.resolve("target")),
|
Files.createDirectories(tempDir.resolve("target")),
|
||||||
Files.createFile(tempDir.resolve("db.sqlite")),
|
Files.createFile(tempDir.resolve("db.sqlite")),
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class PdfUmbenennerApplicationTest {
|
|||||||
void applicationEntry_isStaticMain() throws Exception {
|
void applicationEntry_isStaticMain() throws Exception {
|
||||||
// Verify main is static and returns void
|
// Verify main is static and returns void
|
||||||
Method main = PdfUmbenennerApplication.class.getDeclaredMethod("main", String[].class);
|
Method main = PdfUmbenennerApplication.class.getDeclaredMethod("main", String[].class);
|
||||||
int modifiers = main.getModifiers();
|
main.getModifiers();
|
||||||
|
|
||||||
// Main should be public (inherited from Object or declared)
|
// Main should be public (inherited from Object or declared)
|
||||||
assertEquals("void", main.getReturnType().getSimpleName(),
|
assertEquals("void", main.getReturnType().getSimpleName(),
|
||||||
|
|||||||
Reference in New Issue
Block a user