9907fda6f4
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
89 lines
3.3 KiB
TypeScript
89 lines
3.3 KiB
TypeScript
// Domain-Typen für Berechnungslogik und API-Payloads. Entkoppelt von den generierten
|
|
// Prisma-Typen, damit die Berechnung unabhängig testbar bleibt.
|
|
//
|
|
// V3-Rework: Das Grundprofil (Haushaltsform, Personen, Inflation) liegt neu direkt am Plan.
|
|
|
|
import type { CashTransitionData, ElementCategory, OwnerRole, PhaseData, TransitionData } from "@/lib/elements";
|
|
import type { RetirementDecision } from "@/lib/retirement-decision";
|
|
|
|
export type HouseholdType = "SINGLE" | "COUPLE";
|
|
export type PersonRole = "PERSON_A" | "PERSON_B";
|
|
|
|
export interface PersonInput {
|
|
id: string;
|
|
role: PersonRole;
|
|
name: string | null;
|
|
age: number;
|
|
retirementAge: number;
|
|
// Bis zu welchem Alter gerechnet wird. Fehlt der Wert, ergibt sich das Planende wie bisher
|
|
// aus der Summe der Phasendauern -- deshalb optional und nicht mit Default belegt.
|
|
planningHorizonAge?: number | null;
|
|
}
|
|
|
|
export interface PhaseInput {
|
|
id: string;
|
|
sequenceNumber: number;
|
|
name: string;
|
|
durationYears: number;
|
|
// Cash-Entscheid beim Übergang NACH dieser Phase (einmalige Sonderein-/ausgaben).
|
|
cashTransition: CashTransitionData;
|
|
// Gegenstück im Eltern-Szenario (Diff-Grundlage); null im Basisszenario.
|
|
sourcePhaseId?: string | null;
|
|
}
|
|
|
|
export interface ElementInput {
|
|
id: string;
|
|
category: ElementCategory;
|
|
name: string;
|
|
ownerRole: OwnerRole | null;
|
|
orderIndex: number;
|
|
// Werte je Phase (Key = phaseId) bzw. je Übergang (Key = fromPhaseId).
|
|
phaseValues: Record<string, PhaseData>;
|
|
transitionValues: Record<string, TransitionData>;
|
|
// Pensionierungs-Entscheid (nur AHV, PENSION_FUND, PILLAR_3A). Bewusst OHNE Phasenbezug --
|
|
// er gilt für die Pensionierung des Besitzers, wo immer die gerade liegt.
|
|
retirementDecision?: RetirementDecision | null;
|
|
// Gegenstück im Eltern-Szenario (Diff-Grundlage); null im Basisszenario.
|
|
sourceElementId?: string | null;
|
|
}
|
|
|
|
// Kopf-Daten eines Szenarios (für Baum und Auswahl in der Seitenleiste).
|
|
export interface ScenarioMeta {
|
|
id: string;
|
|
planId: string;
|
|
name: string;
|
|
isBase: boolean;
|
|
parentScenarioId: string | null;
|
|
}
|
|
|
|
// Ein Plan ist der Behälter; er trägt nur den Namen und seine Szenarien.
|
|
export interface PlanListItem {
|
|
id: string;
|
|
name: string;
|
|
createdAt?: string;
|
|
scenarios: ScenarioMeta[];
|
|
// Seit V7 am Plan (für die Übersichtskarten). Optional, weil ältere Aufrufer sie nicht laden.
|
|
householdType?: "SINGLE" | "COUPLE";
|
|
startYear?: number | null;
|
|
persons?: { role: PersonRole; name: string | null; age: number }[];
|
|
_count?: { actuals: number; analyses: number };
|
|
}
|
|
|
|
// Die berechenbare Einheit (fachlich: ein SZENARIO). Sie ist selbsttragend und trägt ihr
|
|
// eigenes Grundprofil (Haushaltsform, Personen, Inflation, Cash) plus Phasen und Elemente.
|
|
// Der Name `PlanInput` ist historisch und bleibt, weil die ganze Berechnungsschicht darauf
|
|
// aufsetzt (computePlan, Monte Carlo, Tests).
|
|
export interface PlanInput {
|
|
id: string;
|
|
name: string;
|
|
householdType: HouseholdType;
|
|
inflationRateDefault: number;
|
|
initialCash: number; // Anfangswert des Cash-Kontos in der ersten Lebensphase
|
|
// Kalenderjahr des Planbeginns (Jahr 1) -- nur für die Darstellung, nicht für die
|
|
// Berechnung. Optional, damit Berechnungs-Fixtures es nicht setzen müssen.
|
|
startYear?: number | null;
|
|
persons: PersonInput[];
|
|
phases: PhaseInput[];
|
|
elements: ElementInput[];
|
|
}
|