docs: AP-A Zusammenfassung aller implementierten Klassen, Methoden und Dateien
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,168 @@
|
|||||||
|
# AP-A Token-Tracking Fundament – Zusammenfassung
|
||||||
|
|
||||||
|
Dieses Dokument fasst alle Klassen, Methoden und Dateien zusammen, die im Zuge
|
||||||
|
von AP-A (Token- und Kosten-Tracking-Fundament der V3.3-Spezifikation, #74)
|
||||||
|
neu erstellt oder substanziell erweitert wurden.
|
||||||
|
|
||||||
|
## Schema-Migration
|
||||||
|
|
||||||
|
- `pdf-umbenenner-adapter-out/src/main/resources/db/migration/V2__token_tracking.sql`
|
||||||
|
- Sechs neue Spalten in `processing_attempt`:
|
||||||
|
`input_tokens`, `output_tokens`,
|
||||||
|
`cache_creation_input_tokens`, `cache_read_input_tokens`,
|
||||||
|
`price_input_per_token_nano_usd`, `price_output_per_token_nano_usd`.
|
||||||
|
- Neue Tabelle `model_price` mit Composite Primary Key
|
||||||
|
`(provider, model_name)`, NOT-NULL-Preisen, Currency-CHECK auf `'USD'`,
|
||||||
|
`updated_at`-Spalte.
|
||||||
|
- Zwei zusätzliche Indizes auf `processing_attempt`:
|
||||||
|
`idx_processing_attempt_started_at_provider_fp_model`,
|
||||||
|
`idx_processing_attempt_run_id_provider_model`.
|
||||||
|
- Default-Preise für gpt-4o-mini, gpt-4o, gpt-4.1*, gpt-5*, claude-haiku-4-5,
|
||||||
|
claude-sonnet-4-6 und claude-opus-4-7 (`ON CONFLICT DO NOTHING`).
|
||||||
|
|
||||||
|
## Application-Modul
|
||||||
|
|
||||||
|
### DTOs (`application/dto`)
|
||||||
|
- `AiUsageMetadata` – Token-Verbrauchsmetadaten mit `empty()`,
|
||||||
|
`hasAnyTokenData()`, `hasCacheTokens()`.
|
||||||
|
- `ModelPriceEntry` – Schreib-/Validierungs-DTO mit Wertgrenzen-Validierung im
|
||||||
|
Konstruktor.
|
||||||
|
- `ModelPriceView` – Lese-/Anzeige-DTO mit nullable `updatedAt` und
|
||||||
|
`invalidUpdatedAt`-Flag.
|
||||||
|
- `ModelPriceKey` – Composite-Key für Löschungen.
|
||||||
|
- `ModelPriceChangeSet` – atomarer Block aus Upserts und Deletions, defensive
|
||||||
|
Listen-Kopie.
|
||||||
|
|
||||||
|
### Cost-Komponenten (`application/cost`)
|
||||||
|
- `CostResult` – interpretierte Kosten-Anzeige mit Status-Flags.
|
||||||
|
- `CostCalculator` – `formatRow(...)` und `calculateAttempt(...)` (echt
|
||||||
|
implementiert), `formatTotal(...)` als Stub für AP-B.
|
||||||
|
|
||||||
|
### Ports (`application/port/out`)
|
||||||
|
- `ModelPriceRepository` – `findAll`, `findByProviderAndModelName`, `upsert`,
|
||||||
|
`delete`, `saveAllChanges`.
|
||||||
|
- `AiInvocationSuccess` (erweitert) – neues Feld `usageMetadata`.
|
||||||
|
|
||||||
|
### Use Cases (`application/usecase`)
|
||||||
|
- `DefaultManageModelPricesUseCase` – CRUD-Fassade mit ChangeSet-Konflikt-
|
||||||
|
validierung (vier Regeln) und Provider-Whitelist beim Upsert.
|
||||||
|
- `ModelPriceValidationException` – deutsche Validierungsfehler-Exception.
|
||||||
|
|
||||||
|
### Application-Service-Anpassungen
|
||||||
|
- `AiNamingService` (erweitert) – reicht `AiUsageMetadata` aus dem
|
||||||
|
`AiInvocationSuccess` als Token-Felder in den `AiAttemptContext` weiter.
|
||||||
|
- `DocumentProcessingCoordinator` (erweitert) –
|
||||||
|
- neuer optionaler Konstruktor mit `ModelPriceRepository` und
|
||||||
|
`headlessMode`-Flag.
|
||||||
|
- `loadPriceSnapshot(modelName)` lädt Snapshot-Preis pro Versuch; Lookup-
|
||||||
|
Fehler liefern leeren Snapshot ohne Attempt-Verlust.
|
||||||
|
- `buildAttempt(...)` befüllt jetzt Token- und Preis-Snapshot-Felder im
|
||||||
|
`ProcessingAttempt`.
|
||||||
|
|
||||||
|
### Domain-Anpassungen
|
||||||
|
- `AiAttemptContext` (erweitert) – vier nullable Token-Felder
|
||||||
|
(`inputTokens`, `outputTokens`, `cacheCreationInputTokens`,
|
||||||
|
`cacheReadInputTokens`); Backward-compatible Convenience-Konstruktor.
|
||||||
|
- `ProcessingAttempt` (erweitert) – sechs nullable Token-/Preis-Snapshot-
|
||||||
|
Felder; Convenience-Konstruktor und `withoutAiFields(...)` ohne Verhaltens-
|
||||||
|
änderung.
|
||||||
|
|
||||||
|
## Adapter-Out-Modul
|
||||||
|
|
||||||
|
- `SqliteConnectionFactory` (neu) – zentrale Connection-Factory; setzt
|
||||||
|
`PRAGMA journal_mode=WAL` und `PRAGMA busy_timeout=5000`.
|
||||||
|
Foreign-Key-Pragma wird bewusst nicht implizit gesetzt (Verhalten der
|
||||||
|
bisherigen `DriverManager.getConnection`-Stellen erhalten).
|
||||||
|
- `SqliteUnitOfWorkAdapter`, `SqliteProcessingAttemptRepositoryAdapter`,
|
||||||
|
`SqliteHistoryQueryAdapter`, `SqliteDocumentRecordRepositoryAdapter`
|
||||||
|
(jeweils geändert) – nutzen die neue Factory.
|
||||||
|
- `SqliteProcessingAttemptRepositoryAdapter.save()` (erweitert) –
|
||||||
|
INSERT um sechs neue Spalten erweitert, neue Hilfsmethode
|
||||||
|
`setNullableLong(...)`.
|
||||||
|
- `SqliteHistoryQueryAdapter.mapToProcessingAttempt(...)` (erweitert) –
|
||||||
|
liest die sechs neuen Spalten via `readNullableLong(...)`.
|
||||||
|
- `SqliteSchemaInitializationAdapter` (geändert) – erwartete Spalten/Indizes
|
||||||
|
bleiben am V1-Zielschema; Doc-Klarstellung, dass V2 additiv auf der Baseline
|
||||||
|
arbeitet.
|
||||||
|
- `SqliteModelPriceRepositoryAdapter` (neu) – `findAll`,
|
||||||
|
`findByProviderAndModelName`, `upsert`, `delete`, `saveAllChanges`
|
||||||
|
(UPSERT via `ON CONFLICT(provider, model_name) DO UPDATE`, transaktionaler
|
||||||
|
Batch). Lese-Mapping behandelt `DateTimeParseException` als
|
||||||
|
`invalidUpdatedAt`.
|
||||||
|
- `ModelPriceRepositoryException` (neu) – technischer JDBC-Fehler.
|
||||||
|
|
||||||
|
### KI-Adapter
|
||||||
|
- `AnthropicClaudeHttpAdapter` (geändert) – neue Methode
|
||||||
|
`extractTokenUsageFromResponse(JSONObject)` für `usage.input_tokens`,
|
||||||
|
`usage.output_tokens`, `usage.cache_creation_input_tokens`,
|
||||||
|
`usage.cache_read_input_tokens` mit Validierung (negativ, > 10 Mio.,
|
||||||
|
nicht-numerisch → NULL + WARN).
|
||||||
|
- `OpenAiHttpAdapter` (geändert) – analoge Methode mit Mapping
|
||||||
|
`prompt_tokens → input_tokens`, `completion_tokens → output_tokens`;
|
||||||
|
Cache-Felder bleiben null.
|
||||||
|
|
||||||
|
## GUI-Modul
|
||||||
|
|
||||||
|
### Neuer Tab "Modell-Preise"
|
||||||
|
- `adapter-in-gui/modelprices/GuiModelPriceManagementPort` (neu) –
|
||||||
|
Bridge-Port für GUI-Zugriff auf Modell-Preise.
|
||||||
|
- `adapter-in-gui/modelprices/GuiModelPricesTab` (neu) – TableView mit
|
||||||
|
editierbaren Preisspalten (`In/1M USD`, `Out/1M USD`), Lösch-Button mit
|
||||||
|
Bestätigungsdialog, Add-Dialog mit Provider-Auswahl, Speichern-Aktion über
|
||||||
|
`ModelPriceChangeSet`. Konvertierung Nano-USD ↔ `$/1M Tokens` mit
|
||||||
|
HALF-UP-Rundung; unbekannte Provider werden read-only mit Tooltip
|
||||||
|
angezeigt; `updatedAt = null` als "ungueltig".
|
||||||
|
|
||||||
|
### Anbindung im Workspace
|
||||||
|
- `GuiConfigurationEditorWorkspace` (geändert) – sechster Tab "Modell-
|
||||||
|
Preise" wird angelegt; neue Methode `warnIfActiveModelHasNoPriceEntry()`
|
||||||
|
zeigt vor dem Speichern eine deutsche Warnung an, wenn das aktuell
|
||||||
|
ausgewählte Modell keinen Preis-Eintrag besitzt.
|
||||||
|
- `GuiStartupContext` (geändert) – neues optionales Feld
|
||||||
|
`modelPriceManagementPort` mit Backward-Kompatibilität.
|
||||||
|
- `BootstrapRunner` (geändert) – neue Methode
|
||||||
|
`buildGuiModelPriceManagementPort()` und Helfer für die Verdrahtung;
|
||||||
|
Coordinator wird mit `ModelPriceRepository` und `headlessMode`-Flag
|
||||||
|
versorgt.
|
||||||
|
|
||||||
|
### History-Tab
|
||||||
|
- `GuiHistoryTab` (geändert) – drei zusätzliche Spalten in der
|
||||||
|
Versuchstabelle: Input-Tokens, Output-Tokens, Kosten. Cache-only-Versuche
|
||||||
|
zeigen "nur Cache-Tokens, keine Standardkosten"; fehlender Preis-Snapshot
|
||||||
|
führt zu "Preis fehlt"; Mikrobeträge als "< $0.0001"; Cache-Beteiligung
|
||||||
|
ergänzt Suffix "(ohne Cache-Anteil)".
|
||||||
|
|
||||||
|
### Summary-Banner
|
||||||
|
- `BatchRunSummaryBanner` (geändert) – aus einzeiliger HBox wurde eine
|
||||||
|
vierzeilige VBox: Status-Zeile, Token-Zeile, Kosten-Zeile, optionale
|
||||||
|
Cache-only-Zeile. Neue Record-Klasse `BatchRunTokenSummary` mit
|
||||||
|
`empty()`-Default; bestehende `update(Map)`-Aufrufer bleiben funktionsfähig.
|
||||||
|
|
||||||
|
## Testanpassungen
|
||||||
|
|
||||||
|
- `pdf-umbenenner-application/.../service/AiNamingServiceTest` und
|
||||||
|
`pdf-umbenenner-bootstrap/.../e2e/StubAiInvocationPort` – alte
|
||||||
|
`AiInvocationSuccess`-Konstruktoraufrufe um `AiUsageMetadata.empty()`
|
||||||
|
ergänzt.
|
||||||
|
- `SqliteSchemaInitializationAdapterTest.fall1_leereDb_processingAttemptHatAlleErwartetenSpalten`
|
||||||
|
prüft jetzt zusätzlich die sechs Token-/Preis-Spalten.
|
||||||
|
- `GuiAdapterSmokeTest.editorWorkspace_startStateShowsEmptyHeaderDefaultsAndOneTab`
|
||||||
|
erwartet jetzt sechs Tabs inkl. "Modell-Preise".
|
||||||
|
|
||||||
|
## Build und Verifizierung
|
||||||
|
|
||||||
|
- `mvn clean verify` läuft auf dem Reactor `pdf-umbenenner-parent` durch
|
||||||
|
(Tests grün auf allen Modulen).
|
||||||
|
- Commit `08ec021` auf `main` gepusht.
|
||||||
|
|
||||||
|
## Bewusst ausgesparte Bereiche (für AP-B / AP-C)
|
||||||
|
|
||||||
|
- `CostCalculator.formatTotal(...)` ist ein Stub und wirft
|
||||||
|
`UnsupportedOperationException`.
|
||||||
|
- `TokenStatisticsReadModelPort`, `QueryCostAnalysisFullUseCase`,
|
||||||
|
`QueryCostAnalysisHeaderOnlyUseCase`, `QueryRunSummaryUseCase`,
|
||||||
|
`SqliteTokenStatisticsReadModelAdapter` sind nicht enthalten.
|
||||||
|
- Summary-Banner zeigt aktuell `0/0` Tokens und `$0.0000` Kosten, da das
|
||||||
|
Read-Model erst in AP-B verdrahtet wird.
|
||||||
|
- CLI-Befehle für Modell-Preise (#99) und Modell-Combobox-Filter (#98)
|
||||||
|
sind AP-C.
|
||||||
Reference in New Issue
Block a user