AHV einkommensabhaengig + Warnhinweis bei Aenderungen in frueheren Phasen
Deploy App / deploy (push) Successful in 59s
Deploy App / deploy (push) Successful in 59s
Roadmap Nr. 3: Die AHV-Rente folgt neu der amtlichen Rentenformel (Skala 44) ueber das massgebende durchschnittliche Jahreseinkommen statt pauschal der Maximalrente. - Formel aus den amtlichen Randbedingungen hergeleitet und gegen die Tabelle 318.117.1 verifiziert: 51/51 Zeilen exakt. Schwellen sind Vielfache von R0=1'260 (12/36/72 x R0 = 15'120 / 45'360 / 90'720). Stuetzstellen als Golden Tests. - Alles REAL gerechnet: die AHV wertet vergangene Einkommen auf UND indexiert die Schwellen -- real hebt sich das auf. Nominal wuerde die Rente systematisch zu hoch ausfallen (Beispiel: faelschlich Maximalrente, ~41'600 ueber 25 Rentenjahre). - Pruefung der Beitragskarriere am Pensions-Uebergang; Zusatzfelder fuer die Jahre vor Planbeginn nur, wenn der Plan nicht bis Alter 21 zurueckreicht. - Sonderfall "bei Planbeginn bereits pensioniert": Felder in der Phasenzelle. - Ohne Pruefung gilt der geplante Durchschnitt (nicht 0) -- sonst waere die Rente still viel zu tief. - 13. Altersrente: Jahresbetrag = Monatsrente x 13. Roadmap Nr. 4: Warnhinweis in Phasenzellen und Phasen-Detail, wenn Folgephasen existieren -- Werte schreiben sich fort und wirken bis ans Planende durch. Verhaltensaenderung fuer bestehende Plaene: siehe SPEZIFIKATION 9.10. Zwoelf Regressionstests (18 -> 30). Spezifikation auf v0.4. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+212
-21
@@ -4,10 +4,10 @@
|
||||
| | |
|
||||
|---|---|
|
||||
| **Dokument** | Funktionale und Technische Spezifikation FPT |
|
||||
| **Version** | 0.3 |
|
||||
| **Datum** | 2026-07-16 |
|
||||
| **Version** | 0.4 |
|
||||
| **Datum** | 2026-07-17 |
|
||||
| **Status** | Lebendes Dokument |
|
||||
| **Codestand** | Arbeitsstand nach `87e6a5f` inkl. einmaliger Sonderein-/ausgaben am Cash-Übergang (Branch `main`) |
|
||||
| **Codestand** | Arbeitsstand nach `9f5bd75` inkl. einkommensabhängiger AHV und Fortschreibungs-Warnhinweis (Branch `main`) |
|
||||
| **Ersetzt** | `FDD_TDD_FPT.docx` (v1–v5) im Ordner `Info Dateien` – diese sind ab Version 0.1 dieses Dokuments obsolet |
|
||||
| **Geltungsbereich** | Gesamter Code im Verzeichnis `FPT` |
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
| Version | Datum | Autor | Änderung |
|
||||
|---|---|---|---|
|
||||
| 0.4 | 2026-07-17 | Claude (Opus 4.8) | **AHV-Rente einkommensabhängig** (Roadmap Nr. 3) und **Fortschreibungs-Warnhinweis** (Roadmap Nr. 4). Die AHV-Rente folgt neu der amtlichen Rentenformel (Skala 44) über das massgebende durchschnittliche Jahreseinkommen statt pauschal der Maximalrente; verifiziert gegen die amtliche Tabelle 318.117.1 (51/51 Zeilen). Prüfung der Beitragskarriere am Pensions-Übergang, mit Zusatzfeldern für die Jahre vor Planbeginn (ab Alter 21). Alles **real** gerechnet. Neue Konstanten `AHV_MIN_MONTHLY_FULL`, `AHV_PENSION_MONTHS`, `AHV_CONTRIBUTION_START_AGE`; `AHV_MAX_ANNUAL_SINGLE` neu abgeleitet. Warnhinweis in Phasenzellen und Phasen-Detail, wenn Folgephasen existieren. Neue Kapitel 3.5.6, 4.4; Abschnitt 9 um zwei Punkte ergänzt. Zwölf Regressionstests (18 → 30). **Verhaltensänderung:** siehe 9.10. |
|
||||
| 0.3 | 2026-07-16 | Claude (Opus 4.8) | **Einmalige Sonderein-/ausgaben** umgesetzt (Roadmap Nr. 1). Der Cash-Übergang zwischen zwei Phasen ist neu ein eigener Entscheid: 1:1 übernehmen · einmaliger Zufluss · einmalige Kosten · beides. Beträge gehen direkt aufs Cash-Konto. Zufluss wird nominal erfasst (real angezeigt) mit optionalem Steuersatz (Default 0 %), Kosten werden real erfasst (nominal angezeigt); beide bleiben aus der Sparquote heraus. Der Entscheid startet unbeantwortet und zählt im „offen"-Badge mit. Neue Spalte `Phase.cashTransition` (JSON) + Migration, neue Route `PUT /api/phases/<id>/cash-transition`, eigene Kennzahlen im Phasenkopf. Fünf Regressionstests ergänzt (13 → 18). Neue Kapitel 3.5.5, 4.9.6; Abschnitt 9 um zwei Grenzen ergänzt. |
|
||||
| 0.2 | 2026-07-16 | Claude (Opus 4.8) | Drei Fixes umgesetzt und dokumentiert: **(1)** `Phase.inflationRate` ersatzlos entfernt (DB-Migration, API, Typen, UI) – die Inflation liegt seit V5 plan-weit; das Feld war wirkungslos. **(2)** Amortisation und Tilgung stoppen neu, sobald Hypothek bzw. Schuld abbezahlt sind – sie belasten danach weder Cash noch Sparquote (Kap. 4.6.5, 4.6.7, 4.7, 4.8). **(3)** Kapitalbezugssteuer greift neu auch bei PK-/3a-Vorbezügen vor der Pensionierung, inkl. Steuerfeld und Netto-Vorschau im UI (Kap. 3.5.2, 4.9.1, 4.9.2). Kennzahl `plannedSaveRate` ist neu die Rate des **ersten** Phasenjahres. Drei Regressionstests ergänzt (10 → 13). Abschnitt 9 neu nummeriert (erledigte Punkte entfernt, „Sparraten werden nicht indexiert" ergänzt). |
|
||||
| 0.1 | 2026-07-16 | Claude (Opus 4.8) | Erstfassung. Vollständige Neuerstellung aus dem Code (Stand `f768e01`). Ersetzt die bisherigen FDD/TDD-Dokumente v1–v5 vollständig. |
|
||||
@@ -575,6 +576,59 @@ neu angelegte Phase erzeugt damit automatisch einen offenen Cash-Entscheid am ne
|
||||
Referenz: `src/components/ElementDetail.tsx` (`CashTransitionFields`), `src/components/PlanView.tsx`
|
||||
(`CashTransitionDialog`).
|
||||
|
||||
### 3.5.6 AHV-Prüfung am Pensions-Übergang
|
||||
|
||||
Die AHV-Rente hängt vom **massgebenden durchschnittlichen Jahreseinkommen (mdJE)** über die
|
||||
ganze Beitragsdauer ab. Diese Grösse kann das Tool nicht allein aus dem Plan bestimmen: Die
|
||||
Beitragspflicht beginnt mit 21, der Plan aber erst beim heutigen Alter. Bei einer 45-jährigen
|
||||
Person liegen 24 Beitragsjahre vor dem Planbeginn.
|
||||
|
||||
Deshalb ist die Beitragskarriere **am Pensions-Übergang** zu prüfen – dort, wo bereits die
|
||||
PK-Bezugsart und der 3a-Bezug entschieden werden. Der Dialog zeigt:
|
||||
|
||||
| Feld | Art |
|
||||
|---|---|
|
||||
| Geplantes Durchschnittseinkommen (aus dem Plan) | read-only, real |
|
||||
| Beitragsjahre im Plan | read-only |
|
||||
| Durchschnittseinkommen vor Planbeginn (real) | Eingabe – **nur wenn Alter bei Planbeginn > 21** |
|
||||
| Ausfalljahre vor Planbeginn | Eingabe – **nur wenn Alter bei Planbeginn > 21** |
|
||||
| Massgebendes durchschnittliches Jahreseinkommen | read-only, live berechnet |
|
||||
| Resultierende AHV-Rente pro Jahr | read-only, live berechnet |
|
||||
|
||||
Die beiden Eingabefelder erscheinen also nur, wenn sie fachlich gebraucht werden. Die Zelle
|
||||
zeigt `Geprueft` bzw. `?`; der Entscheid zählt im „offen"-Badge mit. An allen **anderen**
|
||||
Übergängen ist die AHV-Zelle inaktiv (`–`).
|
||||
|
||||
**Wichtig zum Feld „vor Planbeginn":** Der Wert ist **real** (heutige Kaufkraft). Der
|
||||
AHV-Kontoauszug listet Einkommen historisch-nominal – ein Lohn von 2008 steht dort mit dem
|
||||
Betrag von 2008 und wäre zu tief. Die Zahl stammt idealerweise aus der **Rentenvorausberechnung**,
|
||||
dort ist die Aufwertung bereits enthalten. Der Hilfetext im Feld sagt das.
|
||||
|
||||
**Sonderfall „bei Planbeginn bereits pensioniert":** Dann gibt es keinen Pensions-Übergang. Die
|
||||
gleichen Felder erscheinen stattdessen in der **AHV-Phasenzelle der ersten Phase**, zusammen mit
|
||||
der resultierenden Rente als Live-Vorschau.
|
||||
|
||||
Referenz: `src/components/ElementDetail.tsx` (`AhvReviewFields`), Formeln in
|
||||
`src/lib/calculations.ts` (`ahvMdje`, `ahvAnnualPension`).
|
||||
|
||||
### 3.5.7 Warnhinweis bei Änderungen in früheren Phasen
|
||||
|
||||
Seit dem V3-Rework werden Werte **live fortgeschrieben** (Endwert = Startwert der Folgephase).
|
||||
Eine Änderung in einer frühen Phase wirkt damit bis ans Planende durch – oft unbemerkt. Seit
|
||||
Roadmap Nr. 3 gilt das verschärft: Ein geändertes Einkommen in Phase 1 verschiebt über das mdJE
|
||||
auch die AHV-Rente in Phase 5.
|
||||
|
||||
Beim Bearbeiten einer Phase, der noch Phasen folgen, erscheint deshalb ein rot abgesetzter
|
||||
Warnhinweis mit der Anzahl betroffener Folgephasen. Er erscheint in:
|
||||
|
||||
- **Phasenzellen** (Werte eines Elements in einer Phase)
|
||||
- **Phasen-Detail** (Bezeichnung/Dauer – eine geänderte Dauer verschiebt alle Folgephasen)
|
||||
|
||||
Nicht in Übergangs-Dialogen (dort ist die Wirkung auf die Folgephase offensichtlich) und nicht
|
||||
beim Anlegen eines Elements (dort gibt es noch nichts zu überschreiben).
|
||||
|
||||
Referenz: `src/components/ElementDetail.tsx` (`CarryWarning`).
|
||||
|
||||
## 3.6 Auswertung und Visualisierung
|
||||
|
||||
### 3.6.1 Anzeigemodus nominal / beide / real
|
||||
@@ -780,29 +834,104 @@ gezählt** – es gibt keine Kalenderdaten im Modell, nur „Jahre ab Planbeginn
|
||||
|
||||
## 4.4 AHV-Rente
|
||||
|
||||
Zwei Durchgänge pro Phase über alle AHV-Elemente:
|
||||
Die Rente hängt an zwei Achsen: der **Beitragsdauer** (Rentenskala 44) und dem **massgebenden
|
||||
durchschnittlichen Jahreseinkommen** (mdJE).
|
||||
|
||||
**1. Ausfalljahre kumulieren** – für Elemente, deren Besitzer in dieser Phase **erwerbstätig** ist:
|
||||
### 4.4.1 Die amtliche Rentenformel (Skala 44)
|
||||
|
||||
Alle Schwellen sind Vielfache von `R0`, dem Mindestbetrag der vollen Monatsrente
|
||||
(`AHV_MIN_MONTHLY_FULL = 1'260`). Mit `x = mdJE / (12 × R0)`:
|
||||
|
||||
```
|
||||
gapYearsByPerson[owner] += max(0, round(phaseData.gapYears))
|
||||
mdJE ≤ 12 × R0 (= 15'120) → Rente = R0 (Mindestrente 1'260)
|
||||
12 × R0 < mdJE ≤ 36 × R0 → Rente = R0 × (0.74 + 0.26 × x) Formel 1
|
||||
36 × R0 < mdJE < 72 × R0 → Rente = R0 × (1.04 + 0.16 × x) Formel 2
|
||||
mdJE ≥ 72 × R0 (= 90'720) → Rente = 2 × R0 (Maximalrente 2'520)
|
||||
```
|
||||
|
||||
Die Ausfalljahre akkumulieren also über alle Erwerbsphasen hinweg.
|
||||
Der Wendepunkt liegt bei `36 × R0 = 45'360` → 1'915/Monat; beide Formelteile sind dort stetig.
|
||||
|
||||
**2. Rente berechnen** – für Elemente, deren Besitzer in dieser Phase **pensioniert** ist:
|
||||
**Quelle und Verifikation:** BSV/MAS „Berechnungsvorschriften der AHV/IV-Renten", gültig ab
|
||||
1.1.2026 (liefert die Schwellenstruktur `12/36/72 × R0`), und die amtliche Tabelle
|
||||
`318.117.1 – Monatliche Vollrenten, Skala 44`. Die implementierte Formel reproduziert **alle 51
|
||||
Zeilen dieser Tabelle exakt**; Stützstellen sind als Golden Tests hinterlegt (Kap. 8.2).
|
||||
|
||||
Die Funktion `ahvMonthlyFullPension(mdJE)` rechnet bewusst **stetig**. Amtlich wird das mdJE auf
|
||||
Vielfache von `1.2 × R0` gestuft (daher die 51 Tabellenzeilen); für eine Planung ist der stetige
|
||||
Wert näher an der Wahrheit, die Abweichung liegt unter 20/Monat.
|
||||
|
||||
### 4.4.2 Beitragskarriere und mdJE
|
||||
|
||||
Pro Person wird über die Phasen hinweg akkumuliert (`AhvCareer`):
|
||||
|
||||
| Feld | Bedeutung |
|
||||
|---|---|
|
||||
| `plannedAvgIncome` | reales Durchschnittseinkommen der Beitragsjahre **im Plan** |
|
||||
| `planYears` | Beitragsjahre im Plan = Σ (Phasendauer − Ausfalljahre der Phase) |
|
||||
| `yearsBeforePlan` | `max(0, Alter bei Planbeginn − 21)` |
|
||||
| `gapYearsInPlan` | Summe der Ausfalljahre im Plan |
|
||||
|
||||
Das mdJE ist der **gewichtete Mittelwert über alle Beitragsjahre**:
|
||||
|
||||
```
|
||||
factor = max(0, (44 − gapYears) / 44)
|
||||
rente = round(32'760 × factor)
|
||||
yearsBefore = max(0, yearsBeforePlan − gapYearsBefore)
|
||||
mdJE = (avgIncomeBefore × yearsBefore + plannedAvgIncome × planYears)
|
||||
/ (yearsBefore + planYears)
|
||||
```
|
||||
|
||||
- `AHV_MAX_ANNUAL_SINGLE = 32'760` – maximale einfache Altersrente pro Jahr inkl. 13. Rente
|
||||
(2'520/Monat × 13), Stand 2026, Quelle BSV.
|
||||
- `AHV_FULL_CONTRIBUTION_YEARS = 44` – volle Beitragsdauer (Rentenskala 44).
|
||||
Ausfalljahre reduzieren die **Gewichtung** (und die Skala), nicht das Durchschnittseinkommen –
|
||||
genau wie in der echten AHV: Wer zwei Jahre aussetzt, hat deswegen kein tieferes
|
||||
Durchschnittseinkommen, aber weniger Beitragsjahre.
|
||||
|
||||
**3. Ehepaar-Plafonierung** – nur bei `householdType = COUPLE` **und** wenn für **beide**
|
||||
Personen eine Rente vorliegt:
|
||||
### 4.4.3 Warum real gerechnet wird
|
||||
|
||||
Sämtliche Einkommen gehen **real** (Kaufkraft bei Planbeginn) in das mdJE ein, und die
|
||||
Schwellen sind heutige Werte. Das ist kein Vereinfachungs-, sondern ein Genauigkeitsentscheid:
|
||||
Die echte AHV **wertet vergangene Einkommen auf** (Lohnindex) **und indexiert die Schwellen**
|
||||
(Mischindex). Beide Bewegungen heben sich in realer Betrachtung weitgehend auf – wer nominal
|
||||
mittelt und gegen heutige Schwellen hält, vergleicht Franken von 2046 mit Schwellen von 2026 und
|
||||
überschätzt die Rente systematisch.
|
||||
|
||||
> **Grössenordnung:** 45-jährig, 85'000 Lohn, +1.5 %/Jahr bei 2 % Inflation, 20 Erwerbsjahre.
|
||||
> Nominal gemittelt: mdJE 98'276 → Maximalrente 32'760. Real gemittelt: mdJE 81'156 → 31'096.
|
||||
> Differenz 1'664/Jahr, über 25 Rentenjahre rund 41'600 – und der Fehler geht immer nach oben.
|
||||
|
||||
Die reale Berechnung eines Phasen-Durchschnitts erfolgt analytisch (`avgRealFlow`) als
|
||||
geometrische Reihe mit `q = (1 + Lohnerhöhung) / (1 + Inflation)`.
|
||||
|
||||
**Bekannte Unschärfe:** Die Schwellen folgen dem Mischindex, die Aufwertung dem Lohnindex. Da
|
||||
Löhne langfristig schneller steigen als Preise, ist die Deflationierung mit der Preisinflation
|
||||
leicht **konservativ**. Bewusst in Kauf genommen, statt eine dritte Indexannahme einzuführen.
|
||||
|
||||
### 4.4.4 Woher die Karriere-Werte kommen
|
||||
|
||||
| Situation | Quelle |
|
||||
|---|---|
|
||||
| Person retires innerhalb des Plans | `transitionValues` des AHV-Elements am Pensions-Übergang |
|
||||
| Person bei Planbeginn bereits pensioniert | `phaseValues` des AHV-Elements in der ersten Phase |
|
||||
| Prüfung noch nicht erfolgt | Fallback: `avgIncomeBefore = plannedAvgIncome` |
|
||||
|
||||
Der Fallback ist bewusst gewählt: Ohne erfassten Wert gilt der geplante Durchschnitt als
|
||||
Schätzung für die Jahre davor – exakt der Wert, den der Dialog vorbelegt. Ein Fallback auf 0
|
||||
würde die Rente still und massiv zu tief rechnen (bei einer 45-jährigen Person auf rund 45 %).
|
||||
|
||||
Einkommen wird einer Person nur zugerechnet, wenn das `INCOME`-Element ihr zugeordnet ist. Bei
|
||||
einem **Einzelplan** zählt „Gemeinsam" (`HOUSEHOLD`) zur Person A; bei einem **Paar-Plan** nicht
|
||||
(siehe [9.9](#99-gemeinsames-einkommen-zählt-bei-paaren-nicht-für-die-ahv)).
|
||||
|
||||
### 4.4.5 Jahresrente, Skala und Plafonierung
|
||||
|
||||
```
|
||||
factor = max(0, (44 − Ausfalljahre total) / 44) // Rentenskala 44
|
||||
rente = round(ahvMonthlyFullPension(mdJE) × 13 × factor)
|
||||
```
|
||||
|
||||
`AHV_PENSION_MONTHS = 13` – seit 1.1.2026 gibt es die **13. Altersrente** (Art. 34bis AHVG).
|
||||
Die Formel liefert Monatsrenten; der Jahresbetrag ist deshalb `× 13`, nicht `× 12`.
|
||||
`AHV_MAX_ANNUAL_SINGLE` ist neu abgeleitet: `2 × R0 × 13 = 32'760`.
|
||||
|
||||
**Ehepaar-Plafonierung** – nur bei `householdType = COUPLE` **und** wenn für **beide** Personen
|
||||
eine Rente vorliegt:
|
||||
|
||||
```
|
||||
cap = 32'760 × 1.5 = 49'140
|
||||
@@ -811,9 +940,11 @@ falls (renteA + renteB) > cap:
|
||||
```
|
||||
|
||||
Die Rente ist danach **nominal fix** – sie wird über die Phasen hinweg nicht indexiert und
|
||||
verliert damit real an Kaufkraft. Sie fliesst in `renteTotal` und wird im Einkommen mitgeführt.
|
||||
verliert damit real an Kaufkraft (siehe [9.11](#911-ahv-rente-wird-nach-der-pensionierung-nicht-indexiert)).
|
||||
Sie fliesst in `renteTotal` und wird im Einkommen mitgeführt.
|
||||
|
||||
Referenz: `src/lib/calculations.ts` Zeilen 180–202, `src/lib/constants.ts`.
|
||||
Referenz: `src/lib/calculations.ts` (`ahvMonthlyFullPension`, `ahvMdje`, `ahvAnnualPension`),
|
||||
`src/lib/constants.ts`.
|
||||
|
||||
## 4.5 Nominal, real und die Deflatoren
|
||||
|
||||
@@ -1158,7 +1289,10 @@ Zentral in `src/lib/constants.ts` geführt, weil sie sich periodisch durch Bunde
|
||||
|
||||
| Konstante | Wert | Bedeutung |
|
||||
|---|---|---|
|
||||
| `AHV_MAX_ANNUAL_SINGLE` | 32'760 | Max. einfache AHV-Altersrente/Jahr inkl. 13. Rente (2026) |
|
||||
| `AHV_MIN_MONTHLY_FULL` | 1'260 | **R0** – Mindestbetrag der vollen Monatsrente (Skala 44). Alle Schwellen der Rentenformel sind Vielfache davon |
|
||||
| `AHV_PENSION_MONTHS` | 13 | Rentenzahlungen pro Jahr – 13. Altersrente ab 1.1.2026 |
|
||||
| `AHV_CONTRIBUTION_START_AGE` | 21 | Beitragspflicht ab 1. Januar nach dem 20. Geburtstag |
|
||||
| `AHV_MAX_ANNUAL_SINGLE` | 32'760 | **abgeleitet**: `2 × R0 × 13` |
|
||||
| `AHV_COUPLE_CAP_FACTOR` | 1.5 | Ehepaar-Plafonierung: 150 % der Einzel-Maximalrente |
|
||||
| `AHV_FULL_CONTRIBUTION_YEARS` | 44 | Volle Beitragsdauer (Rentenskala 44) |
|
||||
| `PILLAR_3A_MAX_ANNUAL` | 7'258 | Max. 3a-Beitrag/Jahr für PK-Versicherte (2026) |
|
||||
@@ -1358,6 +1492,8 @@ Referenz: `prisma/schema.prisma` Zeilen 4–6, `src/lib/elements.ts` Zeilen 48
|
||||
| `amount` | INCOME, EXPENSE | ≥ 0 |
|
||||
| `teuerungsausgleich` | INCOME, EXPENSE | −20 bis 50 |
|
||||
| `gapYears` | AHV | Integer ≥ 0 |
|
||||
| `avgIncomeBefore` | AHV – nur wenn bei Planbeginn **bereits pensioniert** | ≥ 0, **real** |
|
||||
| `gapYearsBefore` | AHV – dito | Integer 0–50 |
|
||||
| `currentValue` | PENSION_FUND, PILLAR_3A | ≥ 0 |
|
||||
| `startValue` | OTHER_ASSET, OTHER_DEBT | ≥ 0 |
|
||||
| `expectedReturn` | PK, 3a, OTHER_ASSET | −50 bis 100 |
|
||||
@@ -1373,6 +1509,9 @@ Referenz: `prisma/schema.prisma` Zeilen 4–6, `src/lib/elements.ts` Zeilen 48
|
||||
|
||||
| Feld | Kategorien | Zod-Regel |
|
||||
|---|---|---|
|
||||
| `reviewed` | AHV (Pensions-Übergang) – Beitragskarriere geprüft | Boolean |
|
||||
| `avgIncomeBefore` | AHV (Pensions-Übergang) | ≥ 0, **real** |
|
||||
| `gapYearsBefore` | AHV (Pensions-Übergang) | Integer 0–50 |
|
||||
| `withdrawalMode` | PK, 3a (normal) | `NONE` \| `AMOUNT` |
|
||||
| `withdrawal` | PK, 3a (normal) | ≥ 0, **brutto** |
|
||||
| `payoutMode` | PK (Pensionierung) | `CAPITAL` \| `PENSION` \| `COMBI` |
|
||||
@@ -1661,7 +1800,8 @@ Zielumgebung: Hetzner CX23, Traefik als Reverse Proxy, Domain `fpt.aicds.ch`, Gi
|
||||
## 8.1 Teststrategie
|
||||
|
||||
Getestet wird ausschliesslich der Berechnungskern – bewusst, da dort die Fachlogik und das
|
||||
Regressionsrisiko liegen. `src/lib/calculations.test.ts` enthält 18 Tests („V5 Golden Tests"),
|
||||
Regressionsrisiko liegen. `src/lib/calculations.test.ts` enthält 30 Tests (AHV-Rentenformel,
|
||||
AHV einkommensabhängig, „V5 Golden Tests"),
|
||||
ausgeführt mit Vitest in der Node-Umgebung (`vitest.config.ts`, Include `src/**/*.test.ts`).
|
||||
Es gibt **keine** Komponenten-, API- oder E2E-Tests.
|
||||
|
||||
@@ -1669,6 +1809,15 @@ Es gibt **keine** Komponenten-, API- oder E2E-Tests.
|
||||
|
||||
| Test | Prüft |
|
||||
|---|---|
|
||||
| **Amtliche Tabelle 318.117.1** | `ahvMonthlyFullPension` reproduziert 11 Stützstellen der amtlichen Rentenskala exakt (Mindestrente, Formel 1, Wendepunkt 45'360 → 1'915, Formel 2, Maximalrente) |
|
||||
| **Kappung / Stetigkeit** | unter 15'120 → 1'260, über 90'720 → 2'520; kein Sprung am Wendepunkt |
|
||||
| **AHV volle Karriere** | mdJE 100'000 → Maximalrente 32'760 |
|
||||
| **AHV abgestuft / Mindestrente** | mdJE 60'000 → Formel 2; mdJE 10'000 → 1'260 × 13 |
|
||||
| **AHV Vorgeschichte dominiert** | 39 Jahre à 40'000 + 5 Jahre à 200'000 → mdJE 58'182 |
|
||||
| **AHV Ausfalljahre** | 4 Ausfalljahre → `32'760 × 40/44`; Ausfalljahre im Plan senken nur die Skala, nicht das mdJE |
|
||||
| **AHV ohne Prüfung** | ohne erfassten Wert gilt der geplante Durchschnitt (nicht 0) |
|
||||
| **AHV bereits pensioniert** | Karriere aus der Phasenzelle der ersten Phase |
|
||||
| **AHV Plafonierung** | zwei Maximalrenten im Paar-Plan → gekappt auf `32'760 × 1.5` |
|
||||
| Test 1 – Ansparen | Einkommen +2 % nominal, Ausgaben real flach: Endvermögen 761'654 nominal / 565'928 real (±1 %), kein negatives Cash |
|
||||
| Test 2 – Verzehr/Ruin | Rente nominal fix 60k, Ausgaben real 100k, Vermögen 900k @3 %: `ruinAge === 94` |
|
||||
| Test 3 – Cash-Ausgleich | Sparrate 6'364: `cashEnd === 5472`, nie negativ |
|
||||
@@ -1766,12 +1915,51 @@ Ein Ereignis kann nur an einem Phasenübergang liegen. Ein Poolbau in Jahr 3 ein
|
||||
Phase ist nur abbildbar, wenn dort eine Phasengrenze gezogen wird. Nach der letzten Phase gibt
|
||||
es keinen Übergang – ein dort erfasster Betrag bleibt wirkungslos (durch Test abgedeckt).
|
||||
|
||||
## 9.9 `PILLAR_3A_MAX_ANNUAL` wird nur im UI erzwungen
|
||||
## 9.9 Gemeinsames Einkommen zählt bei Paaren nicht für die AHV
|
||||
|
||||
Das mdJE ist eine **personenbezogene** Grösse. Einkommen wird deshalb nur einer Person
|
||||
zugerechnet, wenn das `INCOME`-Element ihr zugeordnet ist (`PERSON_A`/`PERSON_B`). Bei einem
|
||||
**Einzelplan** zählt `HOUSEHOLD` zur Person A – es gibt ja nur eine. Bei einem **Paar-Plan**
|
||||
bleibt `HOUSEHOLD`-Einkommen für die AHV unberücksichtigt.
|
||||
|
||||
Wer in einem Paar-Plan den Lohn als „Gemeinsam" erfasst, sieht deshalb im Prüf-Dialog ein
|
||||
geplantes Durchschnittseinkommen von 0 und bekäme die Mindestrente. Der Dialog zeigt den Wert
|
||||
prominent an, sodass der Fehler auffällt – aber es gibt keine aktive Warnung. Erwerbseinkommen
|
||||
sollte in Paar-Plänen immer personenscharf erfasst werden.
|
||||
|
||||
Ebenfalls nicht modelliert: das **Einkommenssplitting** verheirateter Paare (während der Ehe
|
||||
werden die Einkommen hälftig geteilt) sowie Erziehungs- und Betreuungsgutschriften. Beides würde
|
||||
das mdJE real beeinflussen und wäre der nächste Ausbauschritt.
|
||||
|
||||
## 9.10 Verhaltensänderung: AHV-Rente bestehender Pläne
|
||||
|
||||
Bis Version 0.3 erhielt jede AHV-Position pauschal die **Maximalrente** (32'760), gekürzt nur um
|
||||
Ausfalljahre – unabhängig vom Einkommen. Seit 0.4 folgt sie der Rentenformel. Bestehende Pläne
|
||||
zeigen dadurch eine **andere, in der Regel tiefere** AHV-Rente, sobald das geplante
|
||||
Durchschnittseinkommen unter 90'720 liegt. Das ist keine Regression, sondern die Korrektur einer
|
||||
zu optimistischen Pauschale.
|
||||
|
||||
Zwei Fälle brauchen Aufmerksamkeit:
|
||||
|
||||
- **Bereits pensionierte Personen** (bei Planbeginn): Ohne erfasstes Durchschnittseinkommen
|
||||
ergibt das mdJE 0 → **Mindestrente**. Vorher war es die Maximalrente. Die Felder stehen in der
|
||||
AHV-Phasenzelle der ersten Phase; solange sie leer sind, ist die Rente bewusst konservativ.
|
||||
- **Paar-Pläne mit `HOUSEHOLD`-Einkommen**: siehe 9.9.
|
||||
|
||||
## 9.11 AHV-Rente wird nach der Pensionierung nicht indexiert
|
||||
|
||||
Die Rente wird zum Pensionierungszeitpunkt in heutigem Geld berechnet und danach **nominal
|
||||
eingefroren**. Die echte AHV wird alle zwei Jahre an den Mischindex angepasst. Über 25
|
||||
Rentenjahre verliert die modellierte Rente damit real spürbar an Wert – das Modell ist an dieser
|
||||
Stelle deutlich konservativ. Bewusster Alt-Entscheid, unabhängig von der Rentenformel; der
|
||||
grösste verbliebene Hebel im AHV-Modell.
|
||||
|
||||
## 9.12 `PILLAR_3A_MAX_ANNUAL` wird nur im UI erzwungen
|
||||
|
||||
Das Feld ist per `max`-Prop hart geklammert. Das Zod-Schema kennt für `annualContribution` nur
|
||||
`≥ 0` – ein direkter API-Aufruf kann die Obergrenze überschreiten.
|
||||
|
||||
## 9.10 Kleinere Beobachtungen
|
||||
## 9.13 Kleinere Beobachtungen
|
||||
|
||||
- `planToCsv(plan, computed)` erhält den `plan`-Parameter, verwendet ihn aber nicht.
|
||||
- Der Typ `Selection` in `PlanView` hat nur eine Variante (`{ type: "phase" }`) – ein Rest der
|
||||
@@ -1810,6 +1998,9 @@ Das Feld ist per `max`-Prop hart geklammert. Das Zod-Schema kennt für `annualCo
|
||||
| **Real** | Kaufkraftbereinigt auf den Planbeginn (`nominal / Deflator`) |
|
||||
| **Deflator** | Kumulierte Inflation seit Planbeginn |
|
||||
| **Ausfalljahr** | Jahr ohne AHV-Beiträge; kürzt die Rente um 1/44 |
|
||||
| **mdJE** | Massgebendes durchschnittliches Jahreseinkommen – Mittel der Beitragsjahre, bestimmt die Rentenhöhe |
|
||||
| **R0** | Mindestbetrag der vollen AHV-Monatsrente (1'260); alle Schwellen sind Vielfache davon |
|
||||
| **Wendepunkt** | mdJE = 36 × R0 = 45'360; dort wechselt die Rentenformel von Teil 1 auf Teil 2 |
|
||||
| **Plafonierung** | Deckelung der Ehepaar-AHV auf 150 % der Einzel-Maximalrente |
|
||||
| **Umwandlungssatz** | Prozentsatz zur Verrentung des PK-Kapitals |
|
||||
| **Ruin(alter)** | Alter von Person A, in dem das Gesamtvermögen erstmals unter 0 fällt |
|
||||
|
||||
Reference in New Issue
Block a user