Fundament: Element-Stammdaten, Fixpunkte, Horizont in Jahren, PK-Bezugsalter

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 22:06:04 +02:00
parent cc61a120ee
commit 2f762175d2
17 changed files with 515 additions and 146 deletions
@@ -0,0 +1,19 @@
-- Umbau 0.36: Bestandsaufnahme vor der Zeitachse, Assistent als Herzstueck.
--
-- (1) `FinancialElement.baseData` haelt den Bestand bei PLANBEGINN und die Ausgangs-Annahmen.
-- Bisher lagen diese Werte in `ElementPhaseValue` der ersten Phase. Das war schon immer
-- schief -- ein Startwert ist nicht "phase-1-spezifisch", sondern der Stand am Anfang --
-- und es machte den ersten Schritt des Assistenten unmoeglich: Eine Bestandsaufnahme
-- braucht noch keine Lebensphasen. Zugleich ist es die Wurzel der Feld-Vererbung.
--
-- (2) `Scenario.planningHorizonYears` fuehrt den Horizont in JAHREN statt als Endalter je
-- Person. Eine Zahl statt zweier, die bei einem Paar auseinanderlaufen koennten; die
-- Endalter werden abgeleitet. Ersetzt `Person.planningHorizonAge` aus 0.35.
--
-- (3) `Scenario.assistantProgress` haelt die sieben Haken des FPT-Assistenten.
--
-- Bewusst OHNE Datenmigration (Plaene wurden vorgaengig geloescht).
ALTER TABLE "FinancialElement" ADD COLUMN "baseData" JSONB;
ALTER TABLE "Scenario" ADD COLUMN "planningHorizonYears" INTEGER;
ALTER TABLE "Scenario" ADD COLUMN "assistantProgress" JSONB;
ALTER TABLE "Person" DROP COLUMN IF EXISTS "planningHorizonAge";
+18 -4
View File
@@ -76,11 +76,9 @@ model Person {
scenarioId String
scenario Scenario @relation(fields: [scenarioId], references: [id], onDelete: Cascade)
role PersonRole
// Alter, in dem die Person die Erwerbstaetigkeit aufgibt. Wird bei der Plan-Anlage nicht
// mehr abgefragt (Default 65) -- die Pensionsplanung im Assistenten legt es fest.
retirementAge Int
// Bis zu welchem Alter gerechnet wird. Bisher ergab sich das Planende stillschweigend aus
// der Summe der Phasendauern -- zwei Szenarien konnten dadurch unbemerkt verschieden weit
// rechnen und waren nicht vergleichbar.
planningHorizonAge Int?
@@unique([scenarioId, role])
}
@@ -224,6 +222,14 @@ model Scenario {
inflationRateDefault Float
initialCash Float @default(0)
// Wie viele Jahre die Planung umfasst. Bewusst in JAHREN und nicht als Endalter je Person:
// eine Zahl statt zweier, die bei einem Paar auseinanderlaufen koennten. Die Endalter
// werden daraus abgeleitet. NULL = wie bisher aus der Summe der Phasendauern.
planningHorizonYears Int?
// Fortschritt des FPT-Assistenten (sieben Schritte, vom Benutzer abgehakt).
assistantProgress Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -309,6 +315,14 @@ model FinancialElement {
// er jede Verschiebung der Zeitachse. Siehe src/lib/retirement-decision.ts.
retirementDecision Json?
// Stammdaten des Elements: der Bestand bei PLANBEGINN und die Ausgangs-Annahmen (Rendite,
// Wertsteigerung, Zins). Zwei Gruende dafuer, dass das nicht in Phase 1 liegt:
// 1. Ein Startwert ist nicht "phase-1-spezifisch", sondern schlicht der Stand am Anfang.
// 2. Elemente lassen sich damit erfassen, BEVOR es Lebensphasen gibt -- der erste Schritt
// des Assistenten ist eine Bestandsaufnahme und braucht noch keine Zeitachse.
// Zugleich die Wurzel der Feld-Vererbung: Phase 1 erbt von hier.
baseData Json?
phaseValues ElementPhaseValue[]
transitionValues ElementTransitionValue[]
}