Neuer Knopf auf Plan-Ebene: Liste plus Wizard in zwei Schritten. Ein
Ist-Satz haengt am PLAN, nicht am Szenario -- die Zuordnung laeuft ueber
die Herkunfts-Kette sourceElementId.
computePlan nimmt neu { actuals }: Die Werte schnappen in jedem erfassten
Jahr auf die Realitaet und laufen von dort planmaessig weiter. Luecken
fallen auf die Plandaten zurueck. Ohne die Option unveraendert -- die 43
Golden Tests laufen durch.
Der Sprung ist keine Rendite: eigene Brueckenposition actualsCorrection
in Vermoegens- und Cash-Bruecke, sonst ginge die Zerlegung nicht auf.
Matrix: Umschalter Plan/Effektiv, im Ist-Modus mit farbiger Abweichung
statt acht Zahlen je Zelle. Zeitachse: Marker je Jahr, juengster farbig.
Vier Analysewerkzeuge mit einheitlicher Leiste (nominal/real als
Einfachauswahl, Plan/Effektiv). MC: Zielbetrag dreht mit, Startjahr
abgeleitet statt eingebbar.
Neue Tabelle ActualsSet (gegen echtes Postgres verifiziert), Module
actuals.ts und dataview.ts. Spezifikation 0.21, 27 Tests (181 -> 208).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+179
-4
@@ -4,7 +4,7 @@
|
||||
| | |
|
||||
|---|---|
|
||||
| **Dokument** | Funktionale und Technische Spezifikation FPT |
|
||||
| **Version** | 0.20 |
|
||||
| **Version** | 0.21 |
|
||||
| **Datum** | 2026-07-18 |
|
||||
| **Status** | Lebendes Dokument |
|
||||
| **Codestand** | Arbeitsstand nach `1d046e9` inkl. zwei Monte-Carlo-Fragestellungen (Branch `main`) |
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
| Version | Datum | Autor | Änderung |
|
||||
|---|---|---|---|
|
||||
| 0.21 | 2026-07-20 | Claude (Opus 4.8) | **Effektive Werte / Plan-Ist-Vergleich** (Roadmap Nr. 5, neue Kapitel 3.9 und 9.29). Macht aus dem Planer ein Monitoring-Werkzeug. Neuer Knopf **«Effektive Werte»** auf Plan-Ebene: Liste der Erfassungen plus Wizard in zwei Schritten (Stichtag, dann alle Elemente **aller** Szenarien inkl. **Cash**, Einkommen und Ausgaben, vorbelegt mit dem Planwert für dieses Jahr). Ein Ist-Satz hängt am **Plan**, nicht am Szenario – die Wirklichkeit ist dieselbe, egal wogegen man sie hält; die Zuordnung läuft über die Herkunfts-Kette `sourceElementId`. Das exakte Datum steht in Liste und Zeitachse, für die Rechnung zählt nur die **Jahreszahl**. **Zweiter Rechenlauf:** `computePlan` nimmt neu `{ actuals }`; die Werte schnappen in **jedem** erfassten Jahr auf die Realität und laufen von dort planmässig weiter (Lücken fallen auf die Plandaten zurück). Ohne die Option verhält sich die Funktion exakt wie bisher – die 43 Golden Tests laufen unverändert. Der Sprung wird als eigene Brückenposition `actualsCorrection` geführt (Vermögens- **und** Cash-Brücke): Eine Planabweichung ist keine Rendite, und ohne diese Zeile ginge die Zerlegung im Ist-Jahr nicht mehr auf. **Matrix:** zweiter Umschalter «Plan» / «Effektiv»; im Ist-Modus steht neben dem Wert die **Abweichung** zum Plan, farbig – bewusst kein «beide», das wären mit nominal/real acht Zahlen je Zelle (Begründung 9.29). **Zeitachse:** Marker je erfasstem Jahr, der jüngste farbig, ältere blass. **Alle vier Analysewerkzeuge** erhalten eine einheitliche Leiste (nominal/real als **Einfach**auswahl, Plan/Effektiv); im Vermögensverlauf kommt die Planlinie **gestrichelt** als Referenz dazu, max. vier Serien. **Monte-Carlo:** Der Zielbetrag dreht mit real/nominal mit und wird entsprechend beschriftet; eine Zeile weist aus, ab welchem Jahr simuliert wird – die Jahre davor sind durch Ist-Werte belegt und werden nicht gewürfelt. Das Startjahr ist **abgeleitet, nicht eingebbar**: Ein frei gesetztes Jahr würde Jahre als sicher behandeln, die nie erfasst wurden. Ein Ist-Satz erzeugt **keine** Szenario-Version – er ist eine Beobachtung, keine Planänderung. Neue Tabelle `ActualsSet` (Migration gegen echtes Postgres verifiziert), neue Endpunkte unter `/api/plans/<id>/actuals`, neue Module `actuals.ts` und `dataview.ts`; 27 Tests ergänzt (181 → 208). |
|
||||
| 0.20 | 2026-07-19 | Claude (Opus 4.8) | **Raten über Lebensphasen übernehmen** (neues Kapitel 3.6.11) und **Rate in der Verlaufsgrafik**. (1) Ändert man ein **Ratenfeld**, fragt das Bearbeitungspanel neu nach der Reichweite: **nur diese Phase** (Vorgabe, bisheriges Verhalten), **diese + folgende** oder **alle Phasen**. Anlass war, dass eine geänderte Rendite bisher nur für die eine Phase galt und viermal eingetippt werden musste. Als Ratenfelder gelten `expectedReturn` (PK, 3a, Sonstiges Vermögen), `valueGrowth` und `interestRate` (Immobilie) sowie `teuerungsausgleich` (Einkommen, Ausgaben); AHV und Schulden haben keine. Die Rückfrage erscheint **inline und erst beim Speichern wirksam**, nicht als Modal – das Zahlenfeld löst bei jedem Tastendruck aus, ein Dialog erschiene bei «5.2» viermal. Sie erscheint nur bei **tatsächlich veränderten** Raten («nicht gesetzt» und 0 gelten als gleich). Beim Übertragen bleiben die **übrigen Werte der Zielphasen erhalten** – der Endpunkt ersetzt den ganzen Werte-Satz, ein blosses Kopieren des Entwurfs hätte dort Beträge, Sparraten und Bezüge gelöscht (durch Test abgesichert). Phasen, in denen der Wert schon stimmt, werden übersprungen. Kein neuer Schreibpfad: ein PUT je Zielphase über den bestehenden Endpunkt, alle in einer Bearbeitungssitzung und damit in **einer** Nebenversion. (2) `ElementYearPoint` führt neu ein Feld **`rate`** mit – additiv, es wird nur durchgereicht, was die Rechnung ohnehin benutzt; die 43 Golden Tests laufen unverändert. Die Verlaufsgrafik der Element-Detailansicht zeigt die Rate damit auf einer **zweiten Y-Achse rechts** in Prozent, als **Stufenlinie** (innerhalb einer Phase konstant, Sprung an der Phasengrenze). Neues Modul `ratefields.ts`; 17 Tests ergänzt (164 → 181). Keine DB- oder API-Änderung. |
|
||||
| 0.19 | 2026-07-19 | Claude (Opus 4.8) | **Versionierung und Änderungshistorie je Szenario** (neues Kapitel 3.8). Jedes Szenario trägt eine Version **A.B**: **B** entsteht automatisch, **A** manuell mit Pflichtkommentar. **Der zentrale Entwurfsentscheid:** FPT hat keinen Speichern-Knopf – jede Änderung schreibt sofort, ein Assistenten-Durchlauf macht ~14 Schreibvorgänge, ein Verteil-Klick einen je Zielelement. Eine Version je Schreibvorgang wäre ein Tastenprotokoll gewesen; stattdessen werden alle Schreibvorgänge innerhalb von **10 Minuten zu einer** Nebenversion zusammengefasst, inhaltlich unveränderte Stände erzeugen gar keine, und verschiedene Benutzer laufen nie in einer Version zusammen. Eine Version hält den **vollständigen** Zustand als JSON in der Form `PlanInput` – dadurch ist die **Versionsauswahl in allen vier Analysewerkzeugen** (Grafiken, Live-Simulation, Monte-Carlo, Einflussfaktoren) fast kostenlos; bei Monte-Carlo **je Szenario einzeln**, weil dort mehrere gleichzeitig laufen. **Wiederherstellen** ist ungefährlich gebaut: Es legt den zurückgesetzten Stand selbst als neue Version an («Wiederhergestellt aus A.B»), löscht also nichts, und **erhält die IDs** von Phasen und Elementen – sonst verlören alle Kind-Szenarien ihre Diff-Basis und zeigten schlagartig alles als «neu». Wo ein Bezug trotzdem bricht (der alte Stand kannte das Element noch nicht), **warnt der Dialog vorher namentlich**. Die destruktive Logik liegt als reine Funktion `planRestore` vor und ist dort getestet; `versioning-db.ts` führt sie nur aus. Ein **statischer Wächter-Test** liest alle Route-Dateien und verlangt, dass jeder schreibende Endpunkt eine Version auslöst – eine vergessene Stelle wäre eine stille Lücke. Neue Tabelle `ScenarioVersion` + `Scenario.currentMajor` (Migration gegen echtes Postgres verifiziert), neue Endpunkte unter `/api/scenarios/<id>/versions`. Neue Kapitel 3.8 und 9.28; 25 Tests ergänzt (139 → 164). |
|
||||
| 0.18 | 2026-07-19 | Claude (Opus 4.8) | **Live-Simulation** (Roadmap Nr. 22). Neuer Button und Dialog als Zweispalter: links Schieberegler, rechts eine wählbare Grafik, darüber eine Kennzahlenleiste. Dreht man an einem Regler, wird der Plan **sofort** neu gerechnet – ohne für jede Variante eine Szenario-Kopie anzulegen. **Keine eigene Rechenlogik:** Die Regler benutzen dieselben Transformationen wie der Tornado (`applyDriver`), können also gar nicht etwas anderes zeigen als die Einflussfaktoren-Analyse. Neu ist nur `applyElementDriver` – dieselbe Verschiebung auf ein **einzelnes** Element statt auf eine ganze Kategorie: Standardmässig gibt es einen Sammelregler «Rendite», ein Klick auf «Renditen einzeln aufschlüsseln» ersetzt ihn durch je einen Regler pro Anlage (der Sammelregler wird dabei **entfernt**, nicht ergänzt, sonst zählte eine Bewegung doppelt; ein Test sichert ab, dass beide Ansichten denselben Plan beschreiben). Der unveränderte Plan wird als **Referenzlinie** mitgezeichnet, und die Kennzahlenleiste weist Endvermögen nominal/real **mit Differenz zum Plan** aus sowie – als eigene Karte – ob das Kapital reicht; ein gekippter Plan ist einer Verlaufslinie sonst nicht anzusehen. Gemessene Laufzeit von `computePlan`: **0.2 ms** auf einem 60-Jahres-Plan mit 10 Elementen, also rund 1 % des 16-ms-Frame-Budgets – deshalb wird synchron gerechnet, **ohne Debounce und ohne Worker**. Anders als der Tornado haben die Regler **Standardbereiche** (Begründung des scheinbaren Widerspruchs zu 9.18: neues Kapitel 9.27), beide Enden editierbar. **Das Pensionsalter fehlt weiterhin** (9.18, eigener Roadmap-Punkt); «Als Szenario speichern» ist bewusst zurückgestellt, ersatzweise zeigt der Dialog die aktive Einstellung als lesbare Zeile. Die Vermögensaufteilung wurde als `AllocationChart` aus dem Dashboard herausgelöst, damit beide sie nutzen. Neue Kapitel 4.15 und 9.27; 15 Tests ergänzt (124 → 139). Keine API-, DB- oder Schreib-Änderung – das Feature liest ausschliesslich. Nebenbei dieselbe vom Umlaut-Sweep verstümmelte Hex-Farbe (`#7c3aed`) wie in 0.17, diesmal im Dashboard. |
|
||||
@@ -1357,6 +1358,126 @@ Referenz: `src/lib/versioning.ts` (reine Logik), `src/lib/versioning-db.ts` (Dat
|
||||
`src/components/VersionHistoryDialog.tsx`, `src/components/VersionMatrix.tsx`,
|
||||
`src/components/VersionPicker.tsx`.
|
||||
|
||||
## 3.9 Effektive Werte (Plan-/Ist-Vergleich)
|
||||
|
||||
Roadmap Nr. 5. Macht aus dem Planer ein **Monitoring-Werkzeug**: Was ist tatsächlich
|
||||
eingetreten, und was heisst das für den Rest der Planung?
|
||||
|
||||
Knopf **«Effektive Werte»** auf Plan-Ebene → Liste der bisherigen Erfassungen → Wizard in zwei
|
||||
Schritten.
|
||||
|
||||
### 3.9.1 Ein Ist-Satz gehört zum Plan, nicht zum Szenario
|
||||
|
||||
Das tatsächliche PK-Guthaben am 18.8.2026 ist **eine Zahl** – unabhängig davon, gegen welches
|
||||
Szenario man sie hält. Ein Ist-Satz hängt deshalb am `Plan` und wird über dieselbe
|
||||
Herkunfts-Kette (`sourceElementId`) auf die szenario-eigenen Element-IDs abgebildet, die auch
|
||||
der Diff ([3.2.6](#326-abweichungs-markierung-diff)) und die Monte-Carlo-Gruppierung benutzen.
|
||||
Erfasst wird also je **Wurzel-Element**.
|
||||
|
||||
### 3.9.2 Der Wizard
|
||||
|
||||
**Schritt 1 – Stichtag.** Exaktes Datum (z. B. 18. August 2026) plus optionale Notiz. Das
|
||||
Datum erscheint in der Liste und auf der Zeitachse; für die Rechnung zählt **nur die
|
||||
Jahreszahl**, weil der Rechenkern in ganzen Jahren ab Planbeginn arbeitet. Der Dialog sagt
|
||||
das ausdrücklich.
|
||||
|
||||
**Schritt 2 – Werte.** Alle Elemente **aller Szenarien** dieses Plans, zusammengefasst auf
|
||||
ihre Wurzel, dazu das **Cash-Konto**. Vorbelegt mit dem Stand, den der Plan für dieses Jahr
|
||||
vorsieht (aus dem Basisszenario; fehlt das Element dort, aus dem erstbesten Szenario, das es
|
||||
kennt). Der Nutzer überschreibt nur, was tatsächlich abweicht.
|
||||
|
||||
Zwei Arten von Werten, die sich verschieden verhalten:
|
||||
|
||||
| Art | Elemente | Wirkung |
|
||||
|---|---|---|
|
||||
| **Bestand** | PK, 3a, Sonstiges Vermögen, Schulden, Cash | ersetzt den laufenden Stand |
|
||||
| **Verkehrswert + Schuld** | Immobilie | zwei Felder: Wert und Resthypothek getrennt |
|
||||
| **Fluss** | Einkommen, Ausgaben | nominaler **Jahresbetrag**; ersetzt die Basis für alle Folgejahre |
|
||||
|
||||
**Die AHV erscheint nur, wenn die Rente zum Stichtag bereits läuft.** Vorher gibt es keinen
|
||||
Stand, den man ablesen könnte – die Rente folgt der amtlichen Formel aus der Beitragskarriere
|
||||
([4.4](#44-ahv-rente)).
|
||||
|
||||
**Ist-Werte erfassen Werte, keine Entscheide.** Wenn der Plan die Immobilie verkauft, du sie
|
||||
aber behalten hast, lässt sich das hier nicht ausdrücken – dafür ist ein Szenario da.
|
||||
|
||||
### 3.9.3 Die zweite Berechnung
|
||||
|
||||
Der Plan-Lauf bleibt **unangetastet**. Parallel läuft ein zweiter mit derselben Mechanik, aber
|
||||
korrigierter Ausgangsbasis: In jedem Jahr, für das ein Ist-Satz erfasst wurde, schnappen die
|
||||
Werte auf die Realität und laufen von dort planmässig weiter. **Alle** Sätze gehen ein, nicht
|
||||
nur der jüngste.
|
||||
|
||||
Beispiel aus der Anforderung: Fonds startet 2020 mit 100'000 bei 5 %. Ohne Ist-Daten steht
|
||||
2022 rechnerisch 115'763. Wird für 2022 ein Ist-Wert von 120'000 erfasst, rechnet die Ist-Sicht
|
||||
ab dort weiter und steht 2024 bei 132'300. Kommt für 2024 ein Wert von 140'000 dazu, springt
|
||||
sie erneut. Genau das ist als Test hinterlegt.
|
||||
|
||||
**Lücken fallen auf die Plandaten zurück.** Ein Element ohne erfassten Ist-Wert läuft
|
||||
unverändert auf seiner Planlinie weiter – man muss nicht alles wissen, um etwas zu erfassen.
|
||||
|
||||
Technisch: `computePlan(plan, sample?, { actuals })`. Ohne die Option verhält sich die
|
||||
Funktion exakt wie bisher; die 43 Golden Tests laufen unverändert.
|
||||
|
||||
**Der Sprung ist keine Rendite.** Die Differenz zwischen Plan und Wirklichkeit wird als eigene
|
||||
Brückenposition `actualsCorrection` geführt (Vermögens- **und** Cash-Brücke). Würde man sie den
|
||||
Kapitalerträgen zuschlagen, erschiene ein Planrückstand als Anlageverlust – und die Zerlegung
|
||||
ginge im Ist-Jahr nicht mehr auf ([3.6.8](#367-detailansichten-je-element-und-je-lebensphase)).
|
||||
|
||||
### 3.9.4 Anzeige in der Matrix
|
||||
|
||||
Ein zweiter Umschalter neben nominal/real/beide, aber mit nur **zwei** Möglichkeiten:
|
||||
|
||||
| Auswahl | Wirkung |
|
||||
|---|---|
|
||||
| **Plan** | wie bisher |
|
||||
| **Effektiv** | die Ist-Zahlen, jeweils mit der **Abweichung** zum Plan daneben |
|
||||
|
||||
Warum keine dritte Möglichkeit «beide»: Plan und Ist als Rohwerte nebeneinander wären bei
|
||||
zusätzlich aktivem nominal/real **acht Zahlen je Zelle**. Stattdessen zeigt die Ist-Ansicht den
|
||||
Wert und daneben klein die Differenz, grün oder rot ([9.29](#929-acht-zahlen-je-zelle--und-wie-wir-sie-vermeiden)).
|
||||
Der Umschalter erscheint nur, wenn überhaupt Ist-Werte erfasst sind.
|
||||
|
||||
**Nur die Abweichung trägt Farbe.** Die Beträge selbst bleiben neutral – sonst wird die Matrix
|
||||
zum Ampelteppich, in dem nichts mehr heraussticht.
|
||||
|
||||
### 3.9.5 Zeitachse
|
||||
|
||||
Je erfasstem Jahr ein Marker. Der **jüngste** ist farbig, ältere blass – sie sind überholt,
|
||||
aber nicht bedeutungslos. Ohne gesetztes Planstartjahr entfallen die Marker, weil es dann
|
||||
keinen Kalenderbezug gibt.
|
||||
|
||||
### 3.9.6 Die vier Analysewerkzeuge
|
||||
|
||||
Grafiken, Live-Simulation, Monte-Carlo und Einflussfaktoren erhalten dieselbe Leiste:
|
||||
**Werte** (nominal/real) und **Grundlage** (Plan/Effektiv), dazu die schon bestehende
|
||||
Versionswahl. «Effektiv» ist deaktiviert, solange nichts erfasst ist.
|
||||
|
||||
**Nominal/real ist in den Werkzeugen eine Einfachauswahl**, kein «beide» – anders als in der
|
||||
Matrix. Begründung siehe [9.29](#929-acht-zahlen-je-zelle--und-wie-wir-sie-vermeiden).
|
||||
|
||||
Besonderheiten:
|
||||
|
||||
- **Vermögensverlauf:** Im Ist-Modus kommt die reine Planlinie **gestrichelt** als Referenz
|
||||
dazu. Maximal vier Serien.
|
||||
- **Monte-Carlo:** Der Zielbetrag **dreht mit** der gewählten Grösse (real/nominal) und wird
|
||||
entsprechend beschriftet – sonst prüft man einen nominalen Zielbetrag gegen ein reales
|
||||
Endvermögen. Ausserdem eine Zeile: *Simuliert ab ‹Jahr›; die Jahre davor sind durch deine
|
||||
effektiven Werte belegt und werden nicht gewürfelt.* Das Startjahr ist **abgeleitet, nicht
|
||||
eingebbar** – ein frei gesetztes Jahr würde Jahre als sicher behandeln, die nie erfasst
|
||||
wurden.
|
||||
- **Einflussfaktoren:** Mit Ist-Werten wirken die Treiber nur noch auf die nicht belegten
|
||||
Jahre. Die Balken fallen dadurch zu Recht kürzer aus.
|
||||
|
||||
### 3.9.7 Verhältnis zur Versionierung
|
||||
|
||||
Ein Ist-Satz ist eine **Beobachtung, keine Planänderung**: Er erzeugt **keine** Szenario-Version
|
||||
([3.8](#38-versionierung-und-änderungshistorie)), und es gibt kein Wiederherstellen. Löschen
|
||||
entfernt ihn ersatzlos; der Plan bleibt unberührt. Die beiden Historien bleiben getrennt.
|
||||
|
||||
Referenz: `src/lib/actuals.ts`, `src/lib/dataview.ts`, `src/components/ActualsDialog.tsx`,
|
||||
`src/components/AnalysisControls.tsx`.
|
||||
|
||||
---
|
||||
|
||||
# 4. Berechnungsmodell
|
||||
@@ -2559,7 +2680,7 @@ Referenz: `src/lib/livesim.ts`, `src/lib/sensitivity.ts` (`applyElementDriver`,
|
||||
FPT/
|
||||
├── prisma/
|
||||
│ ├── schema.prisma Datenmodell
|
||||
│ └── migrations/ 13 Migrationen (chronologisch, siehe 5.4.6)
|
||||
│ └── migrations/ 14 Migrationen (chronologisch, siehe 5.4.6)
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── api/ Route Handlers (siehe Kapitel 6)
|
||||
@@ -2600,6 +2721,8 @@ PlanComputed ← an den Client geliefert
|
||||
| `constants.ts` | Schweizer Systemparameter |
|
||||
| `montecarlo.ts` | Monte-Carlo-Simulation (Sampler + Treiber), Szenario-Vergleich und Element-Gruppierung über die Herkunfts-Kette. Keine I/O, läuft im Browser. |
|
||||
| `sensitivity.ts` | Sensitivitätsanalyse / Tornado: Treiber-Katalog, Parameter-Transformationen, `computeTornado`; zusätzlich `applyElementDriver` / `tunableElements` für die einzeln regelbaren Element-Renditen. Rein, läuft im Browser. |
|
||||
| `actuals.ts` | Effektive Werte: Zuordnung auf die Szenario-Elemente über die Herkunfts-Kette, Einspielen in den Rechenkern, Bestand/Fluss. Rein. |
|
||||
| `dataview.ts` | Bündelt Plan-Sicht und Ist-Sicht für Matrix, Grafiken und Analysewerkzeuge. Rein. |
|
||||
| `ratefields.ts` | Ratenfelder je Kategorie, Reichweite der Übernahme über Lebensphasen, Aufbau der Schreibvorgänge (Kap. 3.6.11). Rein. |
|
||||
| `versioning.ts` | Versionierung: Nummerierung A.B, Zusammenfassung je Sitzung, Bauplan des Wiederherstellens, Auswirkung auf Kind-Szenarien. Rein, ohne I/O. |
|
||||
| `versioning-db.ts` | Datenbank-Anbindung der Versionierung: Snapshot festhalten, Hauptversion, Wiederherstellen. Führt den Bauplan aus `versioning.ts` nur aus. |
|
||||
@@ -2815,6 +2938,7 @@ sondern zu leeren Werten.
|
||||
| `20260718090000_plan_scenario_hierarchy` | **V6**: `Plan` → `Scenario` (IDs erhalten), neuer Behälter `Plan`, `planId` → `scenarioId`, Herkunfts-Verweise |
|
||||
| `20260718140000_scenario_start_year` | `Scenario.startYear` (Kalenderjahr des Planbeginns), bestehende auf das laufende Jahr gesetzt |
|
||||
| `20260719210000_scenario_versioning` | Tabelle `ScenarioVersion` (Snapshot als JSONB, A.B eindeutig je Szenario) und `Scenario.currentMajor` |
|
||||
| `20260720090000_actuals` | Tabelle `ActualsSet` (effektive Werte je Plan, Werte als JSONB, Cash separat) |
|
||||
|
||||
**Zur V6-Migration:** Sie benennt die bisherige `Plan`-Tabelle in `Scenario` um – dadurch
|
||||
bleiben alle IDs und damit sämtliche Kind-Fremdschlüssel gültig. Für jedes bisherige
|
||||
@@ -2968,7 +3092,23 @@ SINGLE=1 / COUPLE=2 Personen. Legt Plan **und Basisszenario** an.
|
||||
`{ name }` – der Plan trägt nur noch den Namen. → 200 `{ plan: { id, name } }`
|
||||
|
||||
### `DELETE /api/plans/<planId>`
|
||||
→ 200 `{ ok: true }`, Cascade über alle Szenarien.
|
||||
→ 200 `{ ok: true }`, Cascade über alle Szenarien (inkl. Versionen und Ist-Sätzen).
|
||||
|
||||
### `GET /api/plans/<planId>/actuals`
|
||||
Alle erfassten Ist-Sätze, neueste zuerst ([3.9](#39-effektive-werte-plan-ist-vergleich)):
|
||||
```json
|
||||
{ "sets": [ { "id", "recordedOn": "2026-08-18", "year": 2026, "comment",
|
||||
"cash", "values": { "<rootElementId>": { "value", "mortgage" } },
|
||||
"author", "createdAt" } ] }
|
||||
```
|
||||
|
||||
### `POST /api/plans/<planId>/actuals`
|
||||
`{ recordedOn: "JJJJ-MM-TT", comment?, cash?, values }` – `year` wird aus dem Datum abgeleitet.
|
||||
→ 201 `{ set: { id, year } }`
|
||||
|
||||
### `DELETE /api/plans/<planId>/actuals/<setId>`
|
||||
→ 200 `{ ok: true }`. Ein Ist-Satz ist eine Beobachtung – es gibt weder Versionierung noch
|
||||
Wiederherstellung.
|
||||
|
||||
## 6.3 Szenarien
|
||||
|
||||
@@ -3136,6 +3276,8 @@ Include `src/**/*.test.ts`). Es gibt **keine** Komponenten-, API- oder E2E-Tests
|
||||
| `explain.test.ts` | 12 | Verlaufswerte je Element, Vollständigkeit beider Wasserfall-Zerlegungen, Rechenweg-Protokoll, Gültigkeit der Spezifikations-Verweise |
|
||||
| `montecarlo.test.ts` | 18 | Determinismus, Volatilität/Vol-Drag, Böden, Reproduzierbarkeit; Element-Gruppierung, Szenario-Vergleich, Inflation je Szenario, plannedReturnOf; Schwellen-Ablesung (probabilityAtLeast), Monotonie über Schwellen, Fall 2 systematisch unter 50 % |
|
||||
| `distribution.test.ts` | 8 | Kapitaltopf und Quoten-Zerlegung gegen die Cash-Brücke; Entwurfswerte anwenden ohne Verlust bestehender Felder |
|
||||
| `actuals.test.ts` | 20 | Zuordnung über Kopie-Ketten, Sprung im Ist-Jahr, Weiterrechnen ab dem Ist-Wert, geschlossene Brücken, Fluss-Rückrechnung |
|
||||
| `dataview.test.ts` | 7 | beide Sichten in einem Zug, Rückfall ohne Ist-Werte, Abweichungsmessung |
|
||||
| `ratefields.test.ts` | 17 | Erkennung geänderter Raten, Reichweite (diese/folgende/alle), Erhalt der übrigen Werte in den Zielphasen |
|
||||
| `versioning.test.ts` | 22 | Nummerierung und Zusammenfassung je Sitzung, unveränderte Stände, Benutzertrennung, Bauplan des Wiederherstellens, Auswirkung auf Kind-Szenarien |
|
||||
| `versioning-coverage.test.ts` | 3 | statischer Wächter: jeder schreibende Endpunkt löst eine Version aus |
|
||||
@@ -3144,7 +3286,7 @@ Include `src/**/*.test.ts`). Es gibt **keine** Komponenten-, API- oder E2E-Tests
|
||||
| `bridges.test.ts` | 10 | Vermögens- und Cash-Brücke gehen über sieben Plankonstellationen ohne Restgrösse auf; Umbuchungen bleiben aus der Vermögensbrücke heraus |
|
||||
| `diff.test.ts` | 9 | Abweichungs-Erkennung gegen das Eltern-Szenario |
|
||||
| `migrations.test.ts` | 1 | spielt alle Migrationen gegen echtes PostgreSQL (PGlite) ein |
|
||||
| **Total** | **181** | |
|
||||
| **Total** | **208** | |
|
||||
|
||||
## 8.2 Testfälle
|
||||
|
||||
@@ -3639,6 +3781,39 @@ Benutzer werden nie in einer Version zusammengefasst).
|
||||
verschwindet seine Historie mit ihm (Cascade). Das ist gewollt: Eine Historie ohne das Objekt,
|
||||
das sie beschreibt, wäre nicht wiederherstellbar.
|
||||
|
||||
## 9.29 Acht Zahlen je Zelle – und wie wir sie vermeiden
|
||||
|
||||
Mit den effektiven Werten ([3.9](#39-effektive-werte-plan-ist-vergleich)) bekommt die Matrix
|
||||
eine zweite Achse. Naiv kombiniert ergibt das je Zelle: nominal **und** real, Plan **und** Ist,
|
||||
Phasenbeginn **und** Phasenende – **acht Zahlen**. Das ist keine Tabelle mehr, das ist ein
|
||||
Zahlenfeld.
|
||||
|
||||
Zwei Entscheide halten es lesbar, und sie fallen an den zwei Orten **verschieden** aus.
|
||||
|
||||
**In der Matrix: Wert und Abweichung statt zweier Rohwerte.** Es gibt nur «Plan» oder
|
||||
«Effektiv», kein «beide». Im Ist-Modus steht der Ist-Wert und daneben klein die Differenz zum
|
||||
Plan, grün oder rot. Das beantwortet auch die bessere Frage: nicht «wie lauteten die zwei
|
||||
Zahlen», sondern «wie weit bin ich weg». Nominal/real bleibt dort bei drei Möglichkeiten – es
|
||||
sind Zahlen in einer Zelle, keine Linien in einem Bild.
|
||||
|
||||
**Nur die Abweichung trägt Farbe.** Würde man die Beträge selbst einfärben, entstünde ein
|
||||
Ampelteppich, in dem die eigentliche Aussage untergeht.
|
||||
|
||||
**In den Grafiken: nominal/real wird zur Einfachauswahl.** Der Vermögensverlauf zeichnete
|
||||
bisher je Serie **zwei** Linien (nominal durchgezogen, real gestrichelt). Mit Plan/Ist wären es
|
||||
vier, bei zwei Szenarien acht. Das Stilbudget geht deshalb an die **wichtigere** Unterscheidung:
|
||||
Plan gestrichelt, Ist durchgezogen – genau die «Plan-Linie vs. Ist-Linie», die die Roadmap
|
||||
verlangt. Wer real sehen will, schaltet um, statt eine zweite Linie dazuzubekommen.
|
||||
|
||||
**Nicht jede Grafik verträgt beides.** «Plan und Ist gleichzeitig» gibt es nur beim
|
||||
Vermögensverlauf. Die Vermögensaufteilung zeigt schon Beginn **und** Ende je Phase als
|
||||
gestapelte Balken – Plan und Ist daneben vervierfachte sie. Und die Grafik «Einkommen vs.
|
||||
Ausgaben» lebt vom Band zwischen zwei Linien; ein zweites Paar darüber macht genau diese
|
||||
Aussage unkenntlich. Beide zeigen deshalb nur die gewählte Grundlage.
|
||||
|
||||
**Serienobergrenze vier.** Szenario mal Version mal Datenquelle wächst schnell; darüber hinaus
|
||||
hilft keine Farbpalette mehr.
|
||||
|
||||
---
|
||||
|
||||
# 10. Glossar
|
||||
|
||||
Reference in New Issue
Block a user