## Ergebnis: minimale Sprint-20B-Vertikale **Empfehlung:** `/portfolio/performance` als kompakte Sprint-20B-Hauptansicht ausbauen. Bestehende Berechnungen und Verträge reichen weitgehend; keine Migration und kein neuer Performance-Endpoint nötig. ### Zielansicht 1. **Eine kompakte Karte „Performance wird eingerichtet“** - Fortschritt: `1/3 abgeschlossen`, semantischer Progressbar. - Exakt drei dauerhaft sichtbare Aufgaben, abgeleitet aus `expected_scopes`: 1. PostFinance-Historie ergänzen → `/portfolio/data#portfolio-data-ingestion` 2. True-Wealth-Stichtage und Ein-/Auszahlungen ergänzen → `/portfolio/truewealth` 3. Krypto-Historie vervollständigen → `/crypto` - Aufgabe gilt als abgeschlossen, wenn für den Scope mindestens `ttwror_status` und `xirr_status` beide `complete` sind. - Keine zusätzlichen prominenten Diagnosehinweise neben dieser Karte. 2. **Hauptinhalt auf genau diese fachlichen Flächen reduzieren** - Aktueller erfasster Wert - Davon Anlagen - Anlageergebnis - Persönliche Rendite (XIRR) - TTWROR - Ein gemeinsamer Wert-/Cashflow-Chart - Höchstens **ein** sichtbarer Datenstatus 3. **Technisches ausschließlich in ein geschlossenes `
`** - Coverage-Daten und Reason-Codes - Bewertungsstichtag/Data-Cutoff - Engine-/Versionsangaben, Fingerprint und Quellen - Attribution/Wertbrücke nur dort, sofern weiterhin benötigt - Keine Policy-Warnung oder Portfolioorientierung auf der Performance-Hauptfläche ## Relevante Oberflächen - `frontend/src/pages/PortfolioPage.vue:14-17` schaltet zwischen Übersicht, Performance, Daten und Strategie. - `frontend/src/router/index.ts:44-50` stellt alle benötigten direkten Ziele bereits bereit. - `frontend/src/components/performance/PortfolioPerformancePanel.vue` - Aktuell bereits XIRR, TTWROR und Anlageergebnis: Zeilen 39–52. - Chart bereits vorhanden: Zeilen 54–64. - Derzeit zu viele sichtbare Status-/Diagnoseflächen: Badge Zeile 8, Amber-Hinweis Zeilen 33–37, Benchmark/Coverage Zeilen 74–77 und Metadaten Zeilen 79–82. - Scope-Auswahl Zeilen 12–18 ist irreführend: Der Performance-Request bleibt immer Portfolio-weit; für andere Scopes werden lediglich Statuswerte angezeigt. - `frontend/src/components/wealth/WealthCockpitPanel.vue` - Liefert aktuelles erfasstes Vermögen und Anlagevermögen über `totals`: Verwendung u. a. Zeilen 68–70. - Zeigt derzeit sechs KPI-Karten, prominente Hinweise und Readiness separat: Zeilen 22–32. - Policy-Hauptsektion Zeilen 75–89 darf nicht in die Sprint-20B-Performancefläche übernommen werden. - Gute vorhandene Diagnosegrenze: geschlossenes `
` Zeilen 120–144. - `frontend/src/components/portfolio-data/DataIngestionReconciliationPanel.vue` - Zielanker existiert bereits als `id="portfolio-data-ingestion"`: Zeile 2. - Import folgt weiterhin Preview → Confirm: Zeilen 33–55. - Diagnose-Reason-Codes sind bereits hinter „Technische Details“ verborgen: Zeilen 11–23 und 72–77. ## API-Inventar und minimale Änderungen Vorhanden: - `GET /api/portfolio/wealth-cockpit` - Route: `src/jarvis_finance/api/routers/overview.py:55-71` - Frontend-Client: `frontend/src/api/portfolio.ts:124` - Liefert `totals.investments_chf`, aktuelles Vermögen, Readiness, Diagnostics und eingebettete Performance-Coverage. - `GET /api/portfolio/performance` - Route: `src/jarvis_finance/api/routers/overview.py:148-175` - Client: `frontend/src/api/portfolio.ts:134-139` - Liefert Anlageergebnis, XIRR, TTWROR und Chartserien. - `GET /api/portfolio/performance/coverage` - Route: `src/jarvis_finance/api/routers/overview.py:142-145` - Client: `frontend/src/api/portfolio.ts:129` - Vertrag enthält exakt die drei erwarteten Scopes: `frontend/src/api/portfolio.ts:35-36`. - Strikte Backend-Schemas: - `src/jarvis_finance/api/schemas/portfolio_performance.py:96-142` - `src/jarvis_finance/api/schemas/wealth_cockpit.py:94-115` **Kleinste sinnvolle API-Anpassung:** `GET /portfolio/performance/coverage` um optionale `from`/`to`-Parameter ergänzen und an `build_performance_coverage(...)` weiterreichen. Der Service unterstützt periodenspezifische Grenzen bereits; derzeit ruft die Route ihn ohne Zeitraum auf. So stimmen Fortschritt und Status mit dem ausgewählten Performance-Zeitraum überein. Response-Schema und Datenbank bleiben unverändert. Frontend-seitig `getPortfolioPerformanceCoverage(from, to, refresh)` entsprechend erweitern. Alternativ kann kurzfristig die in `WealthCockpit.performance_coverage` enthaltene periodenspezifische Coverage verwendet werden, diese passt aber nicht sauber zu benutzerdefinierten Performance-Zeiträumen. ## Konkreter Implementierungsumfang 1. **`PortfolioPerformancePanel.vue`** - Setup-Karte und drei feste Scope-Aufgaben ergänzen. - `getWealthCockpit` zusätzlich für aktuelles Vermögen/Anlagen laden. - Scope-Auswahl entfernen; Sprint-20B-Hauptansicht ausschließlich Portfolio-weit halten. - Sichtbare Benchmark-, Wertbrücken-, Coverage- und Metadatenflächen in ein Diagnose-`
` verschieben. - Nur einen kombinierten Datenstatus anzeigen. 2. **`frontend/src/api/portfolio.ts`** - Coverage-Client um Zeitraumparameter ergänzen. - Bei Berührung die optional deklarierten Felder `ttwror`, `xirr` und `attribution` an das tatsächlich verpflichtende Pydantic-Schema angleichen. 3. **`overview.py`** - Optionale Coverage-Queryparameter validieren und durchreichen; keine neue Route. 4. **Tests** - `PortfolioPerformancePanel.test.ts`: exakt eine Setup-Karte, `1/3`, exakt drei Links, fünf Kennzahlen plus Chart, höchstens ein Hauptstatus, technische Inhalte nur im geschlossenen `
`, keine Policy-Warnung. - `PortfolioPage.test.ts`: direkte Performance-/Daten-Navigation bleibt erhalten. - `test_portfolio_performance_foundation.py`: Coverage-Route respektiert `from`/`to`, bleibt read-only und fail-closed. ## Wichtige Fallstricke - Den Fortschritt nicht aus dem globalen Coverage-Status ableiten; immer die drei erwarteten Scope-Zeilen zählen. - `partial` darf nicht als abgeschlossen gelten und fehlende Werte dürfen nie als `0` erscheinen. - „Aktueller Wert“ und Performance-Endwert nicht verwechseln: aktuelles Vermögen aus dem Wealth-Cockpit, periodisches `closing_value` aus dem Performance-Vertrag. - Keine Scope-Auswahl behalten, solange der Request keine echte Scope-/Account-Zuordnung übermittelt. - XIRR ist annualisiert, TTWROR kumuliert; Beschriftung nicht verkürzen oder vertauschen. - Policy-Diagnosen aus `WealthCockpit.diagnostics` herausfiltern, statt daraus eine sichtbare Warnung zu erzeugen. - Chart-Zeitachsen weiterhin gemeinsam über Wert- und Cashflow-Punkte skalieren; der bestehende Test schützt vor der früheren Cashflow-X-Achsen-Verzerrung. **Dateien geändert/erstellt:** keine. Read-only-Inventar; Arbeitsbaum blieb unverändert, `git diff --check` war sauber.