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