V1.1 Arbeitspakete angelegt für Claude
This commit is contained in:
596
docs/workpackages/V1.1 - Arbeitspakete.md
Normal file
596
docs/workpackages/V1.1 - Arbeitspakete.md
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
# V1.1 – Arbeitspakete
|
||||||
|
|
||||||
|
> **Aktive Erweiterung:** Zusätzliche KI-Provider-Familie **Anthropic Claude** über die native Messages API, neben der bestehenden OpenAI-kompatiblen Anbindung. Bewusst minimale Erweiterung des freigegebenen Basisstands.
|
||||||
|
|
||||||
|
> **Ablage im Repository:** `docs/workpackages/V1.1 - Arbeitspakete.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Lesereihenfolge für jedes Arbeitspaket
|
||||||
|
|
||||||
|
Vor jedem AP **vollständig** lesen:
|
||||||
|
1. `CLAUDE.md`
|
||||||
|
2. `docs/specs/technik-und-architektur.md`
|
||||||
|
3. `docs/specs/fachliche-anforderungen.md`
|
||||||
|
4. dieses Dokument: Abschnitte 1 bis 6
|
||||||
|
5. **nur** das aktive Arbeitspaket aus Abschnitt 7
|
||||||
|
|
||||||
|
Nicht vorgreifen. Nicht raten. Bei echter Unklarheit knapp benennen statt erfinden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Arbeitsweise (verbindlich)
|
||||||
|
|
||||||
|
Diese Regeln ersetzen die nicht vorhandene `WORKFLOW.md` und gelten für alle APs in diesem Dokument.
|
||||||
|
|
||||||
|
### 1.1 Scope-Disziplin
|
||||||
|
- Es wird **ausschließlich** das aktive Arbeitspaket umgesetzt.
|
||||||
|
- Keine Inhalte späterer Arbeitspakete vorwegnehmen.
|
||||||
|
- Keine kosmetischen Refactorings ohne direkten Bezug zum AP.
|
||||||
|
- Keine Umbenennungen außerhalb des AP-Scopes.
|
||||||
|
- Vor Änderungen die betroffenen Klassen über Typsuche im Repo lokalisieren, **nicht** über vermutete Pfade.
|
||||||
|
|
||||||
|
### 1.2 Build- und Testpflicht
|
||||||
|
Build-Kommando vom Projekt-Root, identisch für alle APs:
|
||||||
|
|
||||||
|
```
|
||||||
|
.\mvnw.cmd clean verify -pl pdf-umbenenner-domain,pdf-umbenenner-application,pdf-umbenenner-adapter-out,pdf-umbenenner-adapter-in-cli,pdf-umbenenner-bootstrap --also-make
|
||||||
|
```
|
||||||
|
|
||||||
|
- Nach jeder substanziellen Änderung: Build ausführen.
|
||||||
|
- Vor Abschluss eines AP: Build muss **fehlerfrei** sein, alle Tests grün.
|
||||||
|
- Schlägt der Build fehl: Ursache sauber beheben, nicht kaschieren.
|
||||||
|
- Bestehende Tests dürfen nicht stillschweigend gelöscht oder deaktiviert werden. Sie werden bei Bedarf **angepasst** und der Grund wird im AP-Output dokumentiert.
|
||||||
|
|
||||||
|
### 1.3 Pflicht-Tests pro AP
|
||||||
|
- Jede neue Klasse mit fachlich oder technisch relevanter Logik bekommt mindestens einen Unit-Test.
|
||||||
|
- Jede in einem AP geänderte Klasse, die bisher Tests hatte, behält Tests; betroffene Tests werden angepasst.
|
||||||
|
- Pro AP gibt es eine Liste **kritischer Pflicht-Testfälle** (siehe jeweiliges AP). Diese sind namentlich umzusetzen.
|
||||||
|
- Darüber hinaus gilt die übliche Repo-Praxis (Coverage, PIT-Mutationstests in den unmittelbar betroffenen Modulen, soweit bereits etabliert).
|
||||||
|
|
||||||
|
### 1.4 Dokumentation
|
||||||
|
Pro AP werden mitgepflegt, soweit relevant:
|
||||||
|
- JavaDoc und `package-info` der berührten Klassen
|
||||||
|
- Konfigurationsbeispiele
|
||||||
|
- unmittelbar betroffene Repository-Dokumente
|
||||||
|
|
||||||
|
### 1.5 Naming-Regel
|
||||||
|
In Code, Kommentaren und JavaDoc dürfen **keine** Versions- oder AP-Bezeichner erscheinen:
|
||||||
|
- Verboten: `V1.0`, `V1.1`, `M1`–`M8`, `AP-001` … `AP-006`
|
||||||
|
- Stattdessen: zeitlose technische Bezeichnungen.
|
||||||
|
|
||||||
|
### 1.6 Pflicht-Output-Format am Ende jedes AP
|
||||||
|
Am Ende der AP-Bearbeitung gibt Sonnet **genau** diesen Block aus:
|
||||||
|
|
||||||
|
```
|
||||||
|
- Scope erfüllt: ja/nein
|
||||||
|
- Geänderte Dateien:
|
||||||
|
- <Pfad>
|
||||||
|
- ...
|
||||||
|
- Neue Dateien:
|
||||||
|
- <Pfad>
|
||||||
|
- ...
|
||||||
|
- Build-Kommando: <verwendetes Kommando>
|
||||||
|
- Build-Status: ERFOLGREICH / FEHLGESCHLAGEN
|
||||||
|
- Pflicht-Tests umgesetzt: <Liste der namentlich geforderten Testfälle>
|
||||||
|
- Offene Punkte: keine / <Beschreibung>
|
||||||
|
- Risiken: keine / <Beschreibung>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Erweiterungsziel und Nicht-Ziele
|
||||||
|
|
||||||
|
### 2.1 Ziel
|
||||||
|
- Der bestehende OpenAI-kompatible KI-Weg bleibt unverändert nutzbar.
|
||||||
|
- Zusätzlich wird die **native Anthropic Messages API** als zweite, gleichwertig unterstützte Provider-Familie integriert.
|
||||||
|
- Genau **ein** Provider ist pro Lauf aktiv – ausschließlich über Konfiguration.
|
||||||
|
- Kein automatischer Fallback, keine Parallelnutzung, keine Profilverwaltung.
|
||||||
|
- Der fachliche KI-Vertrag (`NamingProposal`) bleibt unverändert.
|
||||||
|
- Bestehende Properties-Dateien werden beim ersten Start kontrolliert ins neue Schema migriert; vorher wird automatisch eine `.bak`-Sicherung angelegt.
|
||||||
|
|
||||||
|
### 2.2 Explizit nicht Bestandteil
|
||||||
|
- Provider-Familien jenseits der zwei explizit unterstützten
|
||||||
|
- Profilverwaltung mit mehreren Konfigurationen je Provider-Familie
|
||||||
|
- automatische Fallback-Umschaltung
|
||||||
|
- parallele Nutzung mehrerer Provider in einem Lauf
|
||||||
|
- Änderung des fachlichen Ergebnisvertrags
|
||||||
|
- Änderung der Dateinamensregeln, Retry-Regeln, Batch-Betriebsmodells
|
||||||
|
- Persistenz- oder Schemaänderungen jenseits der einen additiven Provider-Identifikator-Spalte
|
||||||
|
|
||||||
|
### 2.3 Architekturtreue (unverhandelbar)
|
||||||
|
- strikte hexagonale Architektur, Abhängigkeiten zeigen nach innen
|
||||||
|
- `AiNamingPort` bleibt provider-neutral
|
||||||
|
- provider-spezifische Endpunkte, Header, Auth, Request-/Response-Formate leben **ausschließlich** im jeweiligen Adapter-Out
|
||||||
|
- keine direkte Adapter-zu-Adapter-Kopplung, keine gemeinsame „abstrakte KI-Adapter"-Zwischenschicht
|
||||||
|
- die Provider-Auswahl ist eine **Bootstrap-Verdrahtungsentscheidung**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Zielzustand der Konfiguration (verbindlich)
|
||||||
|
|
||||||
|
### 3.1 Properties-Schema
|
||||||
|
```properties
|
||||||
|
# bestehende, unveränderte Parameter
|
||||||
|
source.folder=...
|
||||||
|
target.folder=...
|
||||||
|
sqlite.file=...
|
||||||
|
max.retries.transient=...
|
||||||
|
max.pages=...
|
||||||
|
max.text.characters=...
|
||||||
|
prompt.template.file=...
|
||||||
|
runtime.lock.file=...
|
||||||
|
log.directory=...
|
||||||
|
log.level=...
|
||||||
|
log.ai.sensitive=...
|
||||||
|
|
||||||
|
# neue Provider-Auswahl (Pflicht)
|
||||||
|
ai.provider.active=openai-compatible
|
||||||
|
|
||||||
|
# OpenAI-kompatible Provider-Familie
|
||||||
|
ai.provider.openai-compatible.baseUrl=...
|
||||||
|
ai.provider.openai-compatible.model=...
|
||||||
|
ai.provider.openai-compatible.timeoutSeconds=...
|
||||||
|
ai.provider.openai-compatible.apiKey=...
|
||||||
|
|
||||||
|
# Anthropic-Provider-Familie (Claude)
|
||||||
|
ai.provider.claude.baseUrl=https://api.anthropic.com
|
||||||
|
ai.provider.claude.model=...
|
||||||
|
ai.provider.claude.timeoutSeconds=...
|
||||||
|
ai.provider.claude.apiKey=...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Zulässige Werte für `ai.provider.active`
|
||||||
|
- `openai-compatible`
|
||||||
|
- `claude`
|
||||||
|
|
||||||
|
Jeder andere Wert ist eine ungültige Startkonfiguration und führt zu Exit-Code `1`.
|
||||||
|
|
||||||
|
### 3.3 Pflichtwerte je aktivem Provider
|
||||||
|
| Provider | Pflicht | Optional / mit Default |
|
||||||
|
|---|---|---|
|
||||||
|
| `openai-compatible` | `baseUrl`, `model`, `timeoutSeconds`, `apiKey` (Env hat Vorrang) | – |
|
||||||
|
| `claude` | `model`, `timeoutSeconds`, `apiKey` (Env hat Vorrang) | `baseUrl` (Default `https://api.anthropic.com`) |
|
||||||
|
|
||||||
|
Für den **inaktiven** Provider werden keine Pflichtwerte erzwungen.
|
||||||
|
|
||||||
|
### 3.4 Umgebungsvariablen für API-Schlüssel
|
||||||
|
| Provider | Umgebungsvariable |
|
||||||
|
|---|---|
|
||||||
|
| `openai-compatible` | `OPENAI_COMPATIBLE_API_KEY` |
|
||||||
|
| `claude` | `ANTHROPIC_API_KEY` |
|
||||||
|
|
||||||
|
- Pro Provider gilt: Umgebungsvariable hat **Vorrang** vor dem Properties-Wert derselben Provider-Familie.
|
||||||
|
- Schlüssel verschiedener Provider werden **niemals** vermischt.
|
||||||
|
- Wenn der Betrieb bisher eine andere Umgebungsvariable für den OpenAI-kompatiblen Key genutzt hat, ist diese vom Betreiber auf `OPENAI_COMPATIBLE_API_KEY` umzustellen. Das ist im Abschlussnachweis (AP-006) zu dokumentieren.
|
||||||
|
|
||||||
|
### 3.5 Legacy-Form (vor V1.1)
|
||||||
|
Eindeutig erkennbar an mindestens einem der flachen Schlüssel:
|
||||||
|
```
|
||||||
|
api.baseUrl
|
||||||
|
api.model
|
||||||
|
api.timeoutSeconds
|
||||||
|
api.key
|
||||||
|
```
|
||||||
|
ohne Vorhandensein von `ai.provider.active`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Anthropic Messages API – verbindlicher technischer Faktenblock
|
||||||
|
|
||||||
|
> Quelle: offizielle Claude API-Dokumentation. Diese Werte sind verbindlich und nicht zu erfinden, abzuleiten oder zu „verbessern".
|
||||||
|
|
||||||
|
### 4.1 Endpoint und Methode
|
||||||
|
- Methode: `POST`
|
||||||
|
- URL: `{baseUrl}/v1/messages`
|
||||||
|
- Default-`baseUrl`: `https://api.anthropic.com`
|
||||||
|
|
||||||
|
### 4.2 Pflicht-Header
|
||||||
|
| Header | Wert |
|
||||||
|
|---|---|
|
||||||
|
| `x-api-key` | API-Schlüssel aus `ANTHROPIC_API_KEY` (Env) bzw. `ai.provider.claude.apiKey` (Properties) |
|
||||||
|
| `anthropic-version` | `2023-06-01` |
|
||||||
|
| `content-type` | `application/json` |
|
||||||
|
|
||||||
|
Nicht `Authorization: Bearer …` verwenden. Anthropic nutzt `x-api-key`.
|
||||||
|
|
||||||
|
### 4.3 Request-Body (relevante Felder)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model": "<modellname aus ai.provider.claude.model>",
|
||||||
|
"max_tokens": <Integer, > 0, Pflicht>,
|
||||||
|
"system": "<optional, top-level Feld - NICHT als Message mit role=system>",
|
||||||
|
"messages": [
|
||||||
|
{ "role": "user", "content": "<Prompt-Text>" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- `max_tokens` ist **Pflicht** (Unterschied zu OpenAI). Konkreter Wert: zweckmäßig fest verdrahtet im Adapter, ausreichend groß für die JSON-Antwort der Anwendung. Kein neuer Properties-Schlüssel.
|
||||||
|
- `system` wird **nicht** als Message mit `role=system` modelliert. Anthropic akzeptiert nur `user` und `assistant` im `messages`-Array; ein System-Prompt geht ausschließlich ins Top-Level-Feld `system`.
|
||||||
|
- Der bestehende Prompt der Anwendung wird **unverändert** als Inhalt der einen `user`-Message übergeben. Falls der bestehende Prompt-Mechanismus eine System-Komponente kennt, wandert diese in das `system`-Feld; sonst bleibt `system` weg.
|
||||||
|
|
||||||
|
### 4.4 Response-Body (relevante Felder)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "...",
|
||||||
|
"type": "message",
|
||||||
|
"role": "assistant",
|
||||||
|
"content": [
|
||||||
|
{ "type": "text", "text": "<die eigentliche Antwort>" }
|
||||||
|
],
|
||||||
|
"stop_reason": "...",
|
||||||
|
"usage": { "input_tokens": 0, "output_tokens": 0 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Der für die Anwendung relevante Text wird **konkateniert aus allen Blöcken in `content` mit `type == "text"`** in Reihenfolge gewonnen.
|
||||||
|
- Andere Block-Typen werden ignoriert.
|
||||||
|
- Liefert die API kein einziges `text`-Block, ist das ein technischer Fehler des Adapters (klassifiziert wie ein leerer/unbrauchbarer Antwortinhalt).
|
||||||
|
|
||||||
|
### 4.5 Fehlerklassifikation im Claude-Adapter
|
||||||
|
| Symptom | Klassifikation | Anmerkung |
|
||||||
|
|---|---|---|
|
||||||
|
| HTTP 4xx (außer 429) | technischer Fehler | Auth-Fehler (401/403) zählen hier rein |
|
||||||
|
| HTTP 429 | technischer Fehler | rate limit |
|
||||||
|
| HTTP 5xx | technischer Fehler | |
|
||||||
|
| Timeout | technischer Fehler | |
|
||||||
|
| Verbindung fehlgeschlagen | technischer Fehler | |
|
||||||
|
| JSON nicht parsebar | technischer Fehler | |
|
||||||
|
| Kein `content[*].text`-Block | technischer Fehler | |
|
||||||
|
| Antworttext nicht nach `NamingProposal` parsebar | greift bestehende Antwort-Validierung der Application | nicht im Adapter behandeln |
|
||||||
|
|
||||||
|
Alle technischen Adapterfehler werden auf die **bestehende** transiente Fehlersemantik der Anwendung abgebildet. Es entsteht **keine** neue Fehlerkategorie.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Verbindliche Regeln für jedes AP
|
||||||
|
|
||||||
|
1. **Minimale Erweiterung.** Nichts ändern, was nicht für die Erweiterung zwingend erforderlich ist.
|
||||||
|
2. **Einheitlicher fachlicher KI-Vertrag.** `NamingProposal` bleibt unverändert. Keine provider-spezifische Verzweigung in Application/Domain.
|
||||||
|
3. **Genau ein aktiver Provider.** Kein Fallback, keine Profilverwaltung.
|
||||||
|
4. **Properties-Datei bleibt führend.** Keine alternative Konfigurationsquelle.
|
||||||
|
5. **Bestehender OpenAI-Pfad bleibt funktional unverändert.**
|
||||||
|
6. **Architekturgrenzen** (siehe 2.3) werden niemals durchbrochen.
|
||||||
|
7. **Rückwärtsverträglichkeit der SQLite-Daten** bleibt erhalten.
|
||||||
|
8. **Build muss am Ende jedes AP fehlerfrei sein.**
|
||||||
|
9. **Alle Pflicht-Testfälle des AP** sind umgesetzt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Granularität und Reihenfolge
|
||||||
|
|
||||||
|
Sechs Arbeitspakete in dieser zwingenden Reihenfolge:
|
||||||
|
|
||||||
|
| AP | Thema | Risiko | Charakter |
|
||||||
|
|---|---|---|---|
|
||||||
|
| AP-001 | Konfigurations-Schema einführen (additiv) | niedrig | reine Erweiterung |
|
||||||
|
| AP-002 | Legacy-Migration mit `.bak` | mittel | Datei-Umschreibung, geschützt durch Sicherung |
|
||||||
|
| AP-003 | Bootstrap-Provider-Auswahl + bestehender Adapter umschalten | hoch | Verhaltensänderung im Wiring |
|
||||||
|
| AP-004 | Persistenz: Provider-Identifikator additiv | mittel | additive DB-Schema-Migration |
|
||||||
|
| AP-005 | Nativer Anthropic-Adapter implementieren und verdrahten | mittel | neue Adapter-Klasse |
|
||||||
|
| AP-006 | Regression, Smoke, Doku, Abschlussnachweis | niedrig | Absicherung |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 7. Arbeitspakete
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-001 – Konfigurations-Schema einführen (additiv)
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
Keine.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Das neue, verschachtelte Properties-Schema (Abschnitt 3.1) wird im Code als parsbare und validierbare Struktur eingeführt. Der bestehende Lese- und Validierungspfad bleibt **unangetastet** – das neue Schema wird parallel additiv eingeführt. Es findet **kein** Wechsel im Bootstrap und **keine** Migration in diesem AP.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. Im Modul `pdf-umbenenner-application` (oder dem Modul, in dem die heutigen Configuration-Klassen leben – per Typsuche lokalisieren) **neue** Konfigurationstypen einführen, mindestens:
|
||||||
|
- eine Repräsentation einer einzelnen Provider-Konfiguration (Felder: `model`, `timeoutSeconds`, `baseUrl`, `apiKey`)
|
||||||
|
- eine Repräsentation der Provider-Auswahl (`activeProviderId`) plus Map oder zwei Felder für die beiden Provider-Familien
|
||||||
|
- einen klar benannten Aufzählungstyp oder konstanten String-Set für die zulässigen Werte `openai-compatible` und `claude`
|
||||||
|
2. Im Adapter-Out-Modul den **Properties-Parser** so erweitern, dass er die neuen Schlüssel aus Abschnitt 3.1 erkennt und in die neuen Typen aus Schritt 1 einliest. Der bestehende Parser für die alten flachen Schlüssel bleibt **unverändert** lauffähig (parallele Erkennung).
|
||||||
|
3. Eine **Validierung** für die neuen Typen einführen. Sie prüft:
|
||||||
|
- `ai.provider.active` ist gesetzt und ein zulässiger Wert
|
||||||
|
- alle Pflichtwerte des aktiven Providers sind vorhanden (Tabelle 3.3)
|
||||||
|
- `timeoutSeconds` ist eine positive Ganzzahl
|
||||||
|
- für Claude: Default-`baseUrl` wird gesetzt, wenn der Wert fehlt
|
||||||
|
- für den **inaktiven** Provider werden keine Pflichtwerte erzwungen
|
||||||
|
- **API-Schlüssel-Auflösung:** Umgebungsvariable des aktiven Providers (Tabelle 3.4) hat Vorrang vor dem Properties-Wert; ist beides leer, ist die Konfiguration ungültig
|
||||||
|
4. **Bootstrap und bestehende Adapter werden in diesem AP nicht umgestellt.** Die neuen Typen sind ausschließlich über neue Tests erreichbar. Der Default-Lauf der Anwendung verwendet weiterhin die alten Klassen.
|
||||||
|
5. JavaDoc für alle neuen Klassen und Methoden ergänzen.
|
||||||
|
6. Konfigurationsbeispiel (`*.example.properties` o.ä.) **nicht** in diesem AP ändern. Folgt in AP-002 zusammen mit der Migration.
|
||||||
|
|
||||||
|
### Pflicht-Testfälle (kritisch, namentlich umzusetzen)
|
||||||
|
1. `parsesNewSchemaWithOpenAiCompatibleActive` – vollständiges neues Schema, OpenAI aktiv, alle Pflichtwerte gesetzt → erfolgreich geparst, Validierung grün.
|
||||||
|
2. `parsesNewSchemaWithClaudeActive` – vollständiges neues Schema, Claude aktiv, alle Pflichtwerte gesetzt → erfolgreich geparst, Validierung grün.
|
||||||
|
3. `claudeBaseUrlDefaultsWhenMissing` – Claude aktiv, `ai.provider.claude.baseUrl` fehlt → Default `https://api.anthropic.com` wird gesetzt, Validierung grün.
|
||||||
|
4. `rejectsMissingActiveProvider` – `ai.provider.active` fehlt → Validierung schlägt fehl mit klarer Meldung.
|
||||||
|
5. `rejectsUnknownActiveProvider` – `ai.provider.active=foo` → Validierung schlägt fehl.
|
||||||
|
6. `rejectsMissingMandatoryFieldForActiveProvider` – aktiver Provider hat ein Pflichtfeld leer → Validierung schlägt fehl.
|
||||||
|
7. `acceptsMissingMandatoryFieldForInactiveProvider` – inaktiver Provider unvollständig → Validierung grün.
|
||||||
|
8. `envVarOverridesPropertiesApiKeyForActiveProvider` – `OPENAI_COMPATIBLE_API_KEY` gesetzt, Properties-Key ebenfalls gesetzt → effektiver Key ist der aus der Env-Var. Analog für `ANTHROPIC_API_KEY`.
|
||||||
|
9. `envVarOnlyResolvesForActiveProvider` – Env-Var nur für inaktiven Provider gesetzt, aktiver Provider hat Properties-Key → effektiver Key ist der Properties-Key des aktiven Providers; die Env-Var des inaktiven Providers wird ignoriert.
|
||||||
|
10. `bestehende Tests bleiben grün` – alle bisherigen Configuration-Tests laufen weiter.
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: Unit-Tests für die neuen Typen (Equality, Defaults), Parser-Tests, Validator-Tests.
|
||||||
|
|
||||||
|
### Explizit NICHT Teil dieses AP
|
||||||
|
- Migration der Legacy-Datei
|
||||||
|
- `.bak`-Sicherung
|
||||||
|
- Bootstrap-Umstellung
|
||||||
|
- Änderung am bestehenden OpenAI-Adapter
|
||||||
|
- nativer Claude-Adapter
|
||||||
|
- Persistenz-Änderungen
|
||||||
|
- Logging-Änderungen
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- Build fehlerfrei
|
||||||
|
- alle Pflicht-Testfälle umgesetzt und grün
|
||||||
|
- bestehende Tests grün
|
||||||
|
- JavaDoc vollständig für neue Klassen
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-002 – Legacy-Migration mit `.bak`
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
AP-001 abgeschlossen.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Beim ersten Start mit erkannter Legacy-Form wird die Properties-Datei kontrolliert in das neue Schema überführt. Vor jeder Migration wird eine `.bak`-Sicherung angelegt. Nach erfolgreicher Migration läuft die Anwendung **noch** auf dem alten Bootstrap-Pfad weiter (Umschaltung folgt in AP-003); aber die Datei auf der Platte ist bereits im neuen Format und beim nächsten Start sofort durch das neue Schema lesbar.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. Eine neue Komponente im Adapter-Out-Modul anlegen, die rein auf Properties-Datei-Ebene arbeitet (kein HTTP, kein DB-Zugriff). Verantwortlichkeiten:
|
||||||
|
- Erkennen der Legacy-Form (Abschnitt 3.5)
|
||||||
|
- `.bak`-Sicherung anlegen: `<dateiname>.bak`. Wenn `.bak` schon existiert, mit aufsteigendem numerischen Suffix sichern (`<dateiname>.bak`, `<dateiname>.bak.1`, …) – **niemals** überschreiben.
|
||||||
|
- Werte umschreiben gemäß Tabelle:
|
||||||
|
| Legacy | Ziel |
|
||||||
|
|---|---|
|
||||||
|
| `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` ergänzen.
|
||||||
|
- Leere/auskommentierte Platzhalter für die Claude-Sektion einfügen mit kurzem Hinweis-Kommentar (ein Block, max. 6 Zeilen).
|
||||||
|
- Alle übrigen Schlüssel (`source.folder`, `target.folder`, `sqlite.file`, `max.*`, `prompt.template.file`, `runtime.lock.file`, `log.*`) **unverändert** und in **stabiler Reihenfolge** übernehmen.
|
||||||
|
- Die migrierte Datei in-place schreiben (`.tmp` + atomischer Move/Rename, kein Truncate-and-write auf das Original).
|
||||||
|
- Anschließend die Datei erneut über den **neuen** Parser aus AP-001 laden und über den neuen Validator validieren. Schlägt das fehl, ist dies ein harter Startfehler (Exit-Code 1, klare Meldung, `.bak` bleibt erhalten).
|
||||||
|
2. Die Migration wird beim Programmstart **vor** dem bestehenden Konfigurationsladen aufgerufen, sobald die Datei bekannt ist. Dieser Aufruf passiert im Bootstrap genau an einer Stelle und ist als eigene Methode klar benennbar.
|
||||||
|
3. Wird **kein** Legacy erkannt (also bereits neues Schema), passiert nichts: keine `.bak`, keine Schreibvorgänge.
|
||||||
|
4. Bestehende ConfigurationPort-Implementierung **nicht** umstellen – das passiert in AP-003. Die Anwendung läuft nach AP-002 fachlich weiter wie zuvor; ihr Eingangs-File ist nur jetzt in beiden Formen lesbar.
|
||||||
|
5. Konfigurationsbeispiel im Repo (z. B. `*.example.properties`) auf das **neue** Schema umstellen. Die Datei zeigt beide Provider-Sektionen mit sprechenden Platzhalterwerten.
|
||||||
|
6. JavaDoc und kurzer Abschnitt in der Repo-Doku zur Migration ergänzen (was passiert, wann, wie wird gesichert, was bei Fehler).
|
||||||
|
|
||||||
|
### Pflicht-Testfälle
|
||||||
|
1. `migratesLegacyFileWithAllFlatKeys` – Legacy-Datei mit allen vier `api.*`-Schlüsseln wird korrekt ins neue Schema überführt; Werte bleiben inhaltlich identisch; übrige Schlüssel bleiben unverändert.
|
||||||
|
2. `createsBakBeforeOverwriting` – vor Migration existiert keine `.bak`, danach existiert sie mit dem **Original-Inhalt**.
|
||||||
|
3. `bakSuffixIsIncrementedIfBakExists` – `.bak` existiert bereits → neue Sicherung als `.bak.1`. Keine Sicherung wird überschrieben.
|
||||||
|
4. `noOpForAlreadyMigratedFile` – Datei bereits im neuen Schema → kein Schreibvorgang, kein `.bak`.
|
||||||
|
5. `reloadAfterMigrationSucceeds` – nach Migration kann der neue Parser/Validator aus AP-001 die Datei fehlerfrei laden.
|
||||||
|
6. `migrationFailureKeepsBak` – Migration schreibt fehlerhafte Datei (Test-Mock erzwingt Validierungsfehler nach Schreiben) → Bootstrap meldet harten Startfehler, `.bak` ist unangetastet.
|
||||||
|
7. `legacyDetectionRequiresAtLeastOneFlatKey` – Datei mit `ai.provider.active=...` und ohne `api.*` → kein Legacy, keine Migration.
|
||||||
|
8. `legacyValuesEndUpInOpenAiCompatibleNamespace` – Werte `api.baseUrl`, `api.model`, `api.timeoutSeconds`, `api.key` landen exakt in den vier Zielschlüsseln; `ai.provider.active=openai-compatible` ist gesetzt.
|
||||||
|
9. `unrelatedKeysSurviveUnchanged` – Schlüssel wie `source.folder`, `max.pages`, `log.level` bleiben mit identischem Wert erhalten.
|
||||||
|
10. `inPlaceWriteIsAtomic` – Test-Doppel für das Dateisystem belegt: erst `.tmp` schreiben, dann atomic move; kein Punkt, an dem das Original teilbeschrieben ist.
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: temporäre Dateien in `@TempDir`, Repository-/Integrationstests für die Migrations-Komponente.
|
||||||
|
|
||||||
|
### Explizit NICHT Teil
|
||||||
|
- Bootstrap-Umstellung des aktiven Konfigurationspfads
|
||||||
|
- Änderung am bestehenden OpenAI-Adapter
|
||||||
|
- Claude-Adapter
|
||||||
|
- Persistenz
|
||||||
|
- Logging-Änderungen über die Migrations-Meldungen hinaus
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- Build fehlerfrei, alle Pflicht-Testfälle grün
|
||||||
|
- Beispiel-Properties-Datei im neuen Schema
|
||||||
|
- Kurz-Doku zur Migration im Repo
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-003 – Bootstrap-Provider-Auswahl und Umstellung des bestehenden OpenAI-Adapters
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
AP-001 und AP-002 abgeschlossen.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Das Bootstrap-Modul wählt anhand von `ai.provider.active` genau eine `AiNamingPort`-Implementierung als aktive Implementierung aus und verdrahtet sie. Der bestehende OpenAI-kompatible Adapter konsumiert ab jetzt seine Werte aus dem Namensraum `ai.provider.openai-compatible.*`. Sein fachliches Verhalten bleibt **unverändert**. Der aktive Provider wird beim Laufstart geloggt.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. Im Bootstrap-Modul eine **Provider-Selektor-Komponente** einführen, die als Eingabe den Wert von `ai.provider.active` und alle bekannten `AiNamingPort`-Implementierungen erhält und genau eine zurückgibt. Initial kennt sie nur die OpenAI-Implementierung; die Erweiterung um Claude erfolgt in AP-005 an genau dieser Stelle.
|
||||||
|
2. Bestehende `AiNamingPort`-Implementierung für die OpenAI-kompatible Schnittstelle so anpassen, dass sie die Werte aus `ai.provider.openai-compatible.*` konsumiert. Der bisherige fachliche Vertrag, das Request-/Response-Mapping und das Fehlerverhalten bleiben **identisch**.
|
||||||
|
3. Bestehenden ConfigurationPort/`Configuration`-Lesepfad so umstellen, dass intern **nur noch** das neue Schema verwendet wird. Die alten flachen Klassen/Methoden, die nur zum Lesen von `api.*` dienten, werden entfernt – aber **nur**, wenn sie nirgends sonst benötigt werden (per Suche prüfen). Falls noch Verweise existieren, wird der entsprechende Konsument im selben AP auf das neue Schema umgestellt.
|
||||||
|
4. Bestehende Konfigurations-Tests des Repos auf das neue Schema umstellen. Tests, die explizit das alte flache Schema geprüft haben, werden zu Migrations-Tests verschoben (gehört bereits zu AP-002) **oder** auf das neue Schema umgeschrieben. Kein Test wird stillschweigend gelöscht.
|
||||||
|
5. Logging-Anbindung erweitern: beim Laufstart wird der **aktive Provider-Identifikator** geloggt (Standard-Loglevel `INFO`). Alle übrigen geforderten Log-Inhalte (siehe `CLAUDE.md`, Logging-Mindestumfang) bleiben unverändert.
|
||||||
|
6. Sicherstellen, dass die Sensibilitätsregel für KI-Inhalte unverändert greift und provider-unabhängig gilt.
|
||||||
|
7. Adapter-zu-Adapter-Kopplung aktiv vermeiden: Der Provider-Selektor lebt im Bootstrap, **nicht** im Adapter-Out-Modul.
|
||||||
|
8. JavaDoc für Selektor und betroffene Klassen ergänzen.
|
||||||
|
|
||||||
|
### Pflicht-Testfälle
|
||||||
|
1. `bootstrapWiresOpenAiCompatibleAdapterWhenActive` – `ai.provider.active=openai-compatible` → Selektor liefert die OpenAI-Implementierung.
|
||||||
|
2. `bootstrapFailsHardWhenActiveProviderUnknown` – Wert ist syntaktisch gesetzt, aber kein gültiger Provider → harter Startfehler, Exit-Code 1.
|
||||||
|
3. `bootstrapFailsHardWhenSelectedProviderHasNoImplementation` – Wert ist `claude`, aber Implementierung noch nicht registriert (Zustand nach AP-003) → harter Startfehler mit klarer Meldung. Dieser Test wird in AP-005 angepasst, sobald Claude registriert ist.
|
||||||
|
4. `openAiAdapterReadsValuesFromNewNamespace` – Adapter-Test: gegebene `ai.provider.openai-compatible.*`-Werte landen 1:1 im HTTP-Request an die bisherige Endpoint-URL.
|
||||||
|
5. `openAiAdapterBehaviorIsUnchanged` – bestehender Adapter-Verhaltenstest (Request-Form, Response-Mapping, Fehlerklassifikation) wird auf die neue Konfigurationsquelle umgestellt und bleibt grün.
|
||||||
|
6. `activeProviderIsLoggedAtRunStart` – Smoke- oder Bootstrap-Test belegt, dass der aktive Provider bei Laufstart in einem definierten Log-Eintrag erscheint.
|
||||||
|
7. `existingDocumentProcessingTestsRemainGreen` – sämtliche bestehenden End-to-End-/Integrations-Tests des bestehenden OpenAI-Pfads bleiben grün, ggf. mit angepasster Konfiguration.
|
||||||
|
8. `legacyFileEndToEndStillRuns` – Test-Doppel: Anwendung startet mit Legacy-Datei → Migration aus AP-002 läuft → Bootstrap aus AP-003 wählt OpenAI → Lauf läuft fachlich durch wie zuvor.
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: Bootstrap-/Wiring-Tests, ggf. Smoke-Test ohne realen externen Aufruf.
|
||||||
|
|
||||||
|
### Explizit NICHT Teil
|
||||||
|
- Claude-Adapter
|
||||||
|
- Persistenz-Erweiterung um Provider-Identifikator
|
||||||
|
- neue Fehlersemantik
|
||||||
|
- Refactoring außerhalb der Adapter-Anbindung
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- Build fehlerfrei, Pflicht-Testfälle grün
|
||||||
|
- bestehender OpenAI-Pfad fachlich unverändert
|
||||||
|
- aktiver Provider wird beim Laufstart geloggt
|
||||||
|
- keine Verweise mehr auf das alte flache Schema im Produktivpfad
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-004 – Persistenz: Provider-Identifikator additiv
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
AP-003 abgeschlossen.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Das SQLite-Schema wird **additiv** um eine Spalte für den Provider-Identifikator je Versuch erweitert. Bestehende Datensätze bleiben lesbar und korrekt interpretierbar (Default-Wert für Altdaten). Neue Versuche schreiben den Identifikator des für den Versuch aktiven Providers.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. Im SQLite-Schema der Versuchshistorie eine neue Spalte hinzufügen, z. B. `ai_provider TEXT NULL` (Spaltenname per bestehender Repo-Konvention wählen, sonst wie hier vorgeschlagen). Die Spalte ist nullable.
|
||||||
|
2. Schema-Migration umsetzen:
|
||||||
|
- Bei Programmstart prüfen, ob die Spalte existiert; wenn nein, per `ALTER TABLE` ergänzen.
|
||||||
|
- Vorhandene Zeilen behalten den Wert `NULL`.
|
||||||
|
- Migration muss idempotent sein (mehrfacher Start ohne Fehler).
|
||||||
|
3. Die Versuchshistorie-Schreiblogik so erweitern, dass beim Anlegen eines neuen Versuchs der **Identifikator des aktiv ausgewählten Providers** mitgeschrieben wird (`openai-compatible` oder `claude`). Der Wert kommt aus der bereits in AP-003 verfügbaren Provider-Auswahl.
|
||||||
|
4. Dokument-Stammsatz wird **nicht** verändert.
|
||||||
|
5. Lesepfad anpassen, sodass der neue Wert mitausgelesen wird; bestehende Mapper/Domain-Typen werden minimal um ein optionales Feld erweitert. Application und Domain bekommen dadurch keinen provider-spezifischen Code – das Feld bleibt ein opaker String.
|
||||||
|
6. JavaDoc und kurzer Abschnitt zur Schema-Erweiterung in der Repo-Doku ergänzen.
|
||||||
|
|
||||||
|
### Pflicht-Testfälle
|
||||||
|
1. `addsProviderColumnOnFreshDb` – frische DB → Schema enthält neue Spalte.
|
||||||
|
2. `addsProviderColumnOnExistingDbWithoutColumn` – DB ohne Spalte (Simulation Altbestand) → Migration legt Spalte nullable an.
|
||||||
|
3. `migrationIsIdempotent` – mehrfacher Start ändert nichts und wirft keinen Fehler.
|
||||||
|
4. `existingRowsKeepNullProvider` – Altzeilen behalten `NULL`.
|
||||||
|
5. `newAttemptsWriteOpenAiCompatibleProvider` – aktiver Provider OpenAI → neuer Versuch hat `ai_provider='openai-compatible'`.
|
||||||
|
6. `newAttemptsWriteClaudeProvider` – aktiver Provider Claude (für diesen Test wird die Provider-Auswahl gemockt; in AP-005 wird derselbe Test mit echtem Claude-Adapter wiederholt) → `ai_provider='claude'`.
|
||||||
|
7. `repositoryReadsProviderColumn` – Repository-Test: gespeicherter Wert wird korrekt zurückgelesen.
|
||||||
|
8. `legacyDataReadingDoesNotFail` – Test mit DB-Datei aus dem Vor-V1.1-Stand: Lesen ohne Fehler, neuer Wert ist Optional/leer.
|
||||||
|
9. `existingHistoryTestsRemainGreen` – alle bestehenden Tests rund um die Versuchshistorie bleiben grün, ggf. mit minimaler Anpassung.
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: Repository-Tests gegen echte SQLite-Instanz (in-memory oder temporär), Schema-Migrations-Tests.
|
||||||
|
|
||||||
|
### Explizit NICHT Teil
|
||||||
|
- Claude-Adapter (folgt in AP-005)
|
||||||
|
- Änderungen am Dokument-Stammsatz
|
||||||
|
- neue Wahrheitsquellen
|
||||||
|
- Reporting/Statistiken
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- Build fehlerfrei, Pflicht-Testfälle grün
|
||||||
|
- bestehende Datenbestände bleiben lesbar
|
||||||
|
- Provider-Identifikator wird für neue Versuche geschrieben
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-005 – Nativer Anthropic-Adapter implementieren und verdrahten
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
AP-001 bis AP-004 abgeschlossen.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Eine zweite `AiNamingPort`-Implementierung wird im Adapter-Out-Modul angelegt, die die **native Anthropic Messages API** anspricht (siehe Faktenblock in Abschnitt 4). Sie wird im Provider-Selektor aus AP-003 als zweite Option registriert. Der Adapter bildet die Anthropic-Antwort auf den **bestehenden** fachlichen Vertrag ab; es entsteht kein Sonderweg in Application oder Domain.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. Im Adapter-Out-Modul eine neue Klasse anlegen, die `AiNamingPort` implementiert. Naming nach bestehender Repo-Konvention; per Typsuche prüfen, wie die OpenAI-Implementierung benannt ist, und analog vorgehen.
|
||||||
|
2. HTTP-Aufruf gemäß Faktenblock 4 umsetzen:
|
||||||
|
- URL aus `ai.provider.claude.baseUrl` (Default `https://api.anthropic.com`) plus Pfad `/v1/messages`
|
||||||
|
- Methode `POST`
|
||||||
|
- Header `x-api-key`, `anthropic-version: 2023-06-01`, `content-type: application/json`
|
||||||
|
- Request-Body mit `model`, `max_tokens`, `messages` (eine `user`-Message mit dem bestehenden Prompt-Text), optional `system` falls die bestehende Prompt-Mechanik ein System-Segment kennt
|
||||||
|
- Timeout aus `ai.provider.claude.timeoutSeconds`
|
||||||
|
3. API-Schlüssel-Auflösung exakt nach Tabelle 3.4: zuerst `ANTHROPIC_API_KEY`, dann `ai.provider.claude.apiKey`.
|
||||||
|
4. Antwortverarbeitung gemäß 4.4: Konkatenation aller `content[*].text`-Blöcke in Reihenfolge. Fehlt jeder `text`-Block oder ist die Antwort nicht parsebar → technischer Adapterfehler nach Tabelle 4.5.
|
||||||
|
5. Den so gewonnenen Antworttext **unverändert** an die bestehende Antwortverarbeitung der Anwendung weitergeben (`NamingProposal`-Validierung passiert in Application/Domain wie bisher).
|
||||||
|
6. Fehlerklassifikation streng nach Tabelle 4.5. Keine neuen Fehlerklassen.
|
||||||
|
7. Den Provider-Selektor aus AP-003 um die neue Implementierung erweitern. **Keine** gemeinsame Basisklasse zwischen den beiden Adaptern, **keine** Hilfsklasse, die HTTP-Logik teilt. Was beide Adapter brauchen, kommt aus dem Repo-üblichen HTTP-/JSON-Standard, nicht aus einer neuen Adapter-Zwischenschicht.
|
||||||
|
8. Den in AP-001 angelegten Test `bootstrapFailsHardWhenSelectedProviderHasNoImplementation` so anpassen, dass er ab jetzt auf einen neuen, weiterhin **unbekannten** Provider-Wert testet (Negativfall bleibt erhalten, aber `claude` ist jetzt registriert).
|
||||||
|
9. Konfigurationsbeispiel im Repo um sprechende Claude-Beispielwerte ergänzen.
|
||||||
|
10. JavaDoc für die neue Klasse und ggf. neue Hilfstypen.
|
||||||
|
|
||||||
|
### Pflicht-Testfälle
|
||||||
|
1. `claudeAdapterBuildsCorrectRequest` – gegebener Prompt → HTTP-Request mit korrekter URL (`<baseUrl>/v1/messages`), Methode POST, allen drei Pflicht-Headern, Body enthält `model`, `max_tokens > 0`, `messages` mit genau einer `user`-Message und korrektem Prompt.
|
||||||
|
2. `claudeAdapterUsesEnvVarApiKey` – `ANTHROPIC_API_KEY` gesetzt, Properties-Wert ebenfalls → Header `x-api-key` enthält den Env-Wert.
|
||||||
|
3. `claudeAdapterFallsBackToPropertiesApiKey` – Env-Var leer, Properties-Wert gesetzt → Header `x-api-key` enthält den Properties-Wert.
|
||||||
|
4. `claudeAdapterFailsValidationWhenBothKeysMissing` – beides leer → Konfigurationsfehler beim Start (greift auf AP-001-Validierung).
|
||||||
|
5. `claudeAdapterParsesSingleTextBlock` – Mock-Response mit einem Block `{type:"text", text:"..."}` → Antworttext gleich dem Block-Text.
|
||||||
|
6. `claudeAdapterConcatenatesMultipleTextBlocks` – mehrere `text`-Blöcke → Antworttext gleich der Konkatenation in Reihenfolge.
|
||||||
|
7. `claudeAdapterIgnoresNonTextBlocks` – Mix aus `text`- und Nicht-`text`-Blöcken → nur die `text`-Inhalte landen im Antworttext.
|
||||||
|
8. `claudeAdapterFailsOnEmptyTextContent` – Response ohne jeden `text`-Block → technischer Adapterfehler.
|
||||||
|
9. `claudeAdapterMapsHttp401AsTechnical` – Mock-Response 401 → technischer Fehler nach Tabelle 4.5.
|
||||||
|
10. `claudeAdapterMapsHttp429AsTechnical` – Mock-Response 429 → technischer Fehler.
|
||||||
|
11. `claudeAdapterMapsHttp500AsTechnical` – Mock-Response 500 → technischer Fehler.
|
||||||
|
12. `claudeAdapterMapsTimeoutAsTechnical` – simulierter Timeout → technischer Fehler.
|
||||||
|
13. `claudeAdapterMapsUnparseableJsonAsTechnical` – Response-Body ist kein gültiges JSON → technischer Fehler.
|
||||||
|
14. `bootstrapSelectsClaudeWhenActive` – `ai.provider.active=claude` → Selektor liefert die Claude-Implementierung.
|
||||||
|
15. `claudeProviderIdentifierLandsInAttemptHistory` – End-zu-End mit gemocktem HTTP-Layer: nach erfolgreichem Lauf hat der neue Versuch `ai_provider='claude'` (knüpft an AP-004 an).
|
||||||
|
16. `existingOpenAiPathRemainsGreen` – sämtliche bestehenden Tests des OpenAI-Pfads bleiben unverändert grün.
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: Adapter-Tests mit gemocktem HTTP-Client (kein realer Netzwerkzugriff), Bootstrap-Wiring-Tests.
|
||||||
|
|
||||||
|
### Explizit NICHT Teil
|
||||||
|
- automatische Fallback-Logik zwischen Providern
|
||||||
|
- gemeinsame Adapter-Basisklasse
|
||||||
|
- Erweiterung des Persistenz-Schemas über AP-004 hinaus
|
||||||
|
- Anpassung des Prompts (eine etwaige System-/User-Trennung der bestehenden Prompt-Datei darf genutzt werden, aber keine inhaltliche Änderung des Prompts)
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- Build fehlerfrei, alle Pflicht-Testfälle grün
|
||||||
|
- nativer Anthropic-Adapter wird über Konfiguration auswählbar und liefert auf Mock-Basis korrekte Ergebnisse
|
||||||
|
- bestehender OpenAI-Pfad unverändert grün
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AP-006 – Regression, Smoke, Doku-Konsolidierung, Abschlussnachweis
|
||||||
|
|
||||||
|
### Voraussetzung
|
||||||
|
AP-001 bis AP-005 abgeschlossen.
|
||||||
|
|
||||||
|
### Ziel
|
||||||
|
Der vollständige Erweiterungsstand wird automatisiert abgesichert, dokumentarisch konsolidiert und als minimale, architekturtreue Erweiterung des Basisstands belastbar nachgewiesen.
|
||||||
|
|
||||||
|
### Konkret zu erledigende Schritte
|
||||||
|
1. **Smoke-Test je Provider:** Zwei Smoke-Tests einrichten, die für je eine Provider-Konfiguration den Bootstrap-Pfad bis zur erfolgreichen Verdrahtung des `AiNamingPort` durchlaufen, **ohne** realen externen HTTP-Aufruf (gemockter HTTP-Layer). Beide müssen grün sein.
|
||||||
|
2. **Regression OpenAI:** Alle bestehenden End-to-End-/Integrations-Tests des OpenAI-Pfads laufen grün. Falls Anpassungen in vorigen APs Tests berührt haben, ist hier der finale Konsistenz-Check.
|
||||||
|
3. **Migration Smoke:** Ein End-zu-End-Test, der mit einer Legacy-Datei (Inhalt aus der bekannten Demo-Konfig) startet und nach einem ersten Lauf folgendes nachweist:
|
||||||
|
- `.bak` existiert mit Original-Inhalt
|
||||||
|
- Properties-Datei ist im neuen Schema
|
||||||
|
- `ai.provider.active=openai-compatible`
|
||||||
|
- der Lauf hat fachlich gleich funktioniert wie mit dem neuen Schema
|
||||||
|
4. **PIT-/Mutationstests** in den unmittelbar betroffenen Modulen ausführen, soweit bereits etabliert. Lücken im neuen Code, die deutlich unter dem bestehenden Niveau liegen, gezielt schließen. Keine willkürliche Coverage-Kosmetik.
|
||||||
|
5. **Doku-Konsolidierung:**
|
||||||
|
- Beispiel-Properties-Datei zeigt das vollständige neue Schema für **beide** Provider mit sprechenden Platzhaltern.
|
||||||
|
- Repo-Doku enthält einen kurzen Abschnitt „KI-Provider auswählen" mit den zulässigen Werten und der Env-Var-Konvention (`OPENAI_COMPATIBLE_API_KEY`, `ANTHROPIC_API_KEY`).
|
||||||
|
- Repo-Doku enthält einen kurzen Abschnitt „Migration von der Vorgängerversion" mit dem Hinweis auf `.bak`.
|
||||||
|
- JavaDoc aller in der Erweiterung neu eingeführten oder substanziell geänderten Klassen ist vorhanden.
|
||||||
|
6. **Abschlussnachweis:** Eine kurze, im Repository verbleibende Markdown-Datei unter `docs/workpackages/V1.1 - Abschlussnachweis.md` anlegen, die mindestens enthält:
|
||||||
|
- Datum, betroffene Module
|
||||||
|
- Liste der ausgeführten Pflicht-Testfälle pro AP (kann tabellarisch sein)
|
||||||
|
- Belegte Eigenschaften: zwei Provider unterstützt, genau einer aktiv, kein Fallback, fachlicher Vertrag unverändert, Persistenz rückwärtsverträglich, Migration nachgewiesen, `.bak` nachgewiesen, aktiver Provider geloggt
|
||||||
|
- explizite Bestätigung: keine Architekturbrüche, keine neuen Bibliotheken außer denen, die für HTTP/JSON ohnehin im Repo etabliert sind
|
||||||
|
- Hinweis auf die Betreiberaufgabe, ggf. die Umgebungsvariable des OpenAI-Keys auf `OPENAI_COMPATIBLE_API_KEY` umzustellen
|
||||||
|
7. Den vollständigen Reactor-Build ausführen und das Ergebnis im AP-Output festhalten.
|
||||||
|
|
||||||
|
### Pflicht-Testfälle
|
||||||
|
1. `smokeBootstrapWithOpenAiCompatibleActive`
|
||||||
|
2. `smokeBootstrapWithClaudeActive`
|
||||||
|
3. `e2eMigrationFromLegacyDemoConfig`
|
||||||
|
4. `regressionExistingOpenAiSuiteGreen` (Sammelnachweis, nicht ein einzelner Test)
|
||||||
|
5. `e2eClaudeRunWritesProviderIdentifierToHistory`
|
||||||
|
6. `e2eOpenAiRunWritesProviderIdentifierToHistory`
|
||||||
|
7. `legacyDataFromBeforeV11RemainsReadable`
|
||||||
|
|
||||||
|
Test-Kategorien zusätzlich: Mutationstests in betroffenen Modulen, Konsistenz-Checks der Doku-Beispiele gegen den realen Parser (z. B. „Beispiel-Properties-Datei wird vom Parser ohne Fehler geladen").
|
||||||
|
|
||||||
|
### Explizit NICHT Teil
|
||||||
|
- weitere Provider
|
||||||
|
- Komfortfunktionen
|
||||||
|
- großflächiges Refactoring
|
||||||
|
|
||||||
|
### Definition of Done
|
||||||
|
- vollständiger Reactor-Build fehlerfrei
|
||||||
|
- alle Pflicht-Testfälle grün
|
||||||
|
- Smoke-Tests je Provider grün
|
||||||
|
- Doku konsolidiert
|
||||||
|
- Abschlussnachweis-Datei im Repo
|
||||||
|
- Pflicht-Output-Block ausgegeben
|
||||||
Reference in New Issue
Block a user