## Sprint-22-Audit — **BLOCK / nicht releasebereit** ### Abnahmematrix | # | Abnahmebedingung | Vorhandene Evidenz | Bewertung | |---|---|---|---| | 1 | PostFinance aus Mengen, Kursen, FX und Settlement-Cash | `test_postfinance_model_combines_depot_and_settlement_cash_once_and_ignores_performance_gate` | **Schwach.** Test injiziert bereits fertig berechnete `portfolio_valuation_snapshots`; Mengen-, Kurs- und FX-Berechnung sowie Übergabe vom täglichen Marktwertlauf ins neue Read Model werden nicht durchgängig getestet. | | 2 | Fehlender August-Report blockiert Modellgrafik nicht | Derselbe Backendtest; Frontendtest `shows the model chart…while verified performance remains blocked` | **Teilweise.** Die UI-Kombination ist belegt, aber der Backendtest erzeugt keinen real unvollständigen PostFinance-Coverage-/Reportzustand. | | 3 | XIRR/TTWROR bleiben bei unvollständiger Coverage gesperrt | Bestehende Performance-/Coverage-Tests; Frontend-Fixture mit beiden Statuswerten `not_ready` | **Teilweise.** Kein neuer End-to-End-Test verbindet konkret unvollständige PostFinance-Coverage mit `verified_performance`. | | 4 | Grafik mit zwei modellierten Tageswerten | Modellwerttest plus `WealthCockpitPanel.test.ts` | **Gut belegt.** | | 5 | Gemischte Stichtage unterdrücken Grafik nicht | `test_mixed_anchor_dates_and_one_unknown_account_do_not_suppress_known_total_or_chart` | **Gut belegt.** | | 6 | Kein heutiger Kurs rückwirkend historisch | `test_historical_days_never_receive_a_later_current_price_and_carry_is_forward_only` | **Gut für Read Model.** Kein echter Daily-Job→Historie-Integrationstest. | | 7 | Neuer Importanker plus Abgleichsdifferenz | `test_new_official_anchor_adds_correction_marker_without_mutating_predecessor_model` | **Gut belegt** für den synthetischen True-Wealth-Fall. | | 8 | Replay und täglicher Marktwertlauf idempotent | Read-Model-Replay im ersten Modelltest; bestehende Marktwerttests | **Unzureichend.** Der umfassende Daily-Job-Idempotenzfall heißt `scenario_daily_job_…`, wird von pytest in dieser Datei nicht gesammelt. Nur drei andere Marktwerttests werden gesammelt. | | 9 | PostFinance Positionen/Cash nicht doppelt zählen | Erster Modellwerttest | **Gut auf Read-Model-Ebene**, aber nicht vom echten Daily Job bis zur API. | | 10 | Raiffeisen-Metadaten kontospezifisch | `test_household_import_metadata_is_canonical_account_specific` | **Teilweise.** Synthetische zwei Konten; keine Regression für 5632/5031, generisches Raiffeisen-Konto, Duplicate-Zuordnung oder bestätigte Transaktions-Lineage. | | 11 | Vier Sprint-21-Cash-Snapshots erkannt | `test_effective_cash_evidence_recognizes_each_supported_snapshot_type…` | **Fehlt.** Test prüft nur drei synthetische Typen und keinen `calculated_balance`; keine Produktionskopie bzw. vier bestätigten Sprint-21-Zeilen. | | 12 | Einzelnes unbekanntes Konto blockiert übrige Werte nicht | Mixed-anchor-Test und Frontendtest | **Gut belegt.** | | 13 | Normale GETs/Dashboard schreiben nicht | `test_normal_cockpit_get_is_read_only_and_uses_only_stored_data`; Modell-Replay prüft `total_changes` | **Gut synthetisch belegt**, einschließlich blockierter Socket-Verbindung. Produktiver Sentinel-Smoke fehlt. | | 14 | Browser-UAT Laptop und iPad | Nur zwei jsdom-Komponententests | **Fehlt.** Keine echten Viewports, Overflow-, Netzwerk-, Konsole-, Touchziel- oder Screenshot-Prüfung. | ### Release-blockierende Befunde 1. **Falsche Kennzeichnung eines Modellwerts als bestätigter Anker** `modelled_wealth.py:575-593` fällt bei fehlendem Anker im Zeitraum auf den ersten verfügbaren Punkt zurück und setzt dessen Qualität bedingungslos auf `confirmed`. Ein rein modellierter oder fortgeschriebener Periodenstart kann dadurch in API und UI als „Bestätigter Ausgangswert“ erscheinen. Dafür existiert kein Gegenbeispieltest. 2. **Risiko doppelter Cash-Bewegungen** `modelled_wealth.py:104-109` und `cash_service.py:175-185` addieren kanonische `transactions` und verknüpfte `budget_transactions` ohne durable Deduplizierung. Wenn derselbe bestätigte Import in beiden Ledgers repräsentiert ist, wird der Saldo doppelt fortgeschrieben. Der vorhandene Test enthält nur eine Budgetbewegung und kann diesen Fehler nicht erkennen. 3. **Privacy-Leak im neuen API-Vertrag** `_bank_accounts()` gibt `accounts.account_name` unverändert als Label in `unknown_accounts` aus (`modelled_wealth.py:378-390`, `560-573`). Anders als bestehende Cockpitpfade wird `safe_account_label()` nicht verwendet. Vollständige private Konto-/IBAN-Bezeichnungen könnten dadurch im API-Payload erscheinen. 4. **Daily-Job-Idempotenzbeweis ist nicht aktiv** Der stärkste vorhandene Testfall ist als `scenario_*` definiert und wird bei direkter pytest-Collection nicht gesammelt. Damit fehlt der ausdrücklich verlangte Replay-/Doppelzählungsnachweis für den normalen vollständigen Daily Job. 5. **Keine Produktionskopie-/Produktionsrehearsal-Evidenz** Nicht nachgewiesen sind: - die vier realen Sprint-21-Cash-Snapshots; - tatsächliche 5632/5031-/Generic-Raiffeisen-Zuordnung; - produktiver GET-No-Write-Sentinel; - Daily-Job-Idempotenz und PostFinance-Doppelzählung auf einer sicheren Kopie. 6. **Keine Browser-UAT und keine vollständigen Release-Gates** Full Backend/Frontend, Ruff, Compile, Typecheck, Build, Secret-Safety, CI, adversarialer Frozen-Candidate-Review und Laptop/iPad-UAT fehlen weiterhin. ### Weitere relevante Risiken - **Performance/N+1:** Das Read Model iteriert bis zu 5.000 Kalendertage und führt pro Tag und Bankkonto mehrere SQL-Abfragen aus (`modelled_wealth.py:475-557`). Für `all` gibt es keinen Query-/Laufzeit-Benchmark oder Produktionsrehearsal. - **Chart-Sichtbarkeit:** `chart_visible` basiert auf `event_dates`, das Cash-Transaktionstage nicht enthält (`462-474`, `614`). Zwei unterschiedliche, durch bestätigte Cash-Bewegungen erzeugte Tageswerte können daher existieren, während die Grafik verborgen bleibt. - **Geändertes bestehendes Cash-Verhalten:** `list_cash_positions()` lässt nun jeden jüngsten Snapshot das bisherige `balance_mode` übersteuern und addiert Bewegungen. Abgedeckt ist lediglich „neuerer manueller Snapshot gewinnt“; Regressionen für vier Typen, Same-day-Präzedenz, doppelte Ledger-Lineage und Multi-Currency fehlen. - **Schema:** Keine Migration ist im Diff enthalten; Schema bleibt 51. Das entspricht der Absicht. Der neue Code setzt jedoch bestehende Schema-51-Tabellen und Mapping-Spalten voraus, ohne Produktionskopie-Smoke. - **API-Verhalten:** Der Defaultzeitraum ändert sich von `ytd` auf `1m`, und die Performanceberechnung von `method="twr"` auf `method="both"`. Diese Verhaltens-/Laufzeitänderungen haben keine dedizierte Kompatibilitätsregression. ### Tatsächlich ausgeführte Prüfung - Backend-Fokus inklusive Modell-, Cockpit-, Cash- und Marktwerttests: **34 passed** - Frontend-Fokus: **6 passed** - `git diff --check`: bestanden - Pytest-Collection der Portfolio-Analytics-Datei: nur **3 Tests**; der umfassende `scenario_daily_job_…`-Fall wurde nicht gesammelt. - Full Suite wurde bewusst nicht als bestanden gewertet und ist weiterhin ausstehend. **Dateien geändert/erstellt:** keine.