Files
FPT/src/lib/types.ts
T

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[];
}