Initial commit: FPT Financial Planning Tool
Deploy App / deploy (push) Successful in 3m3s

This commit is contained in:
2026-07-08 19:19:39 +02:00
commit 4f990c9686
60 changed files with 12436 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
import { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/db";
import type { HouseholdInput, PlanInput } from "@/lib/types";
export const phaseInclude = {
incomeEntries: true,
expenseEntries: true,
securities: true,
realEstates: true,
oneTimeEvents: true,
retirementInfos: true,
} satisfies Prisma.PhaseInclude;
export const planInclude = {
phases: {
include: phaseInclude,
orderBy: { sequenceNumber: "asc" },
},
} satisfies Prisma.PlanInclude;
export type PlanWithRelations = Prisma.PlanGetPayload<{ include: typeof planInclude }>;
export type PhaseWithRelations = Prisma.PhaseGetPayload<{ include: typeof phaseInclude }>;
export type HouseholdWithPersons = Prisma.HouseholdGetPayload<{ include: { persons: true } }>;
export function toHouseholdInput(household: HouseholdWithPersons): HouseholdInput {
return {
id: household.id,
householdType: household.householdType,
inflationRateDefault: household.inflationRateDefault,
persons: household.persons.map((p) => ({
id: p.id,
role: p.role,
age: p.age,
retirementAge: p.retirementAge,
})),
};
}
export function toPlanInput(plan: PlanWithRelations): PlanInput {
return {
id: plan.id,
name: plan.name,
parentPlanId: plan.parentPlanId,
branchFromPhaseId: plan.branchFromPhaseId,
phases: plan.phases.map((phase) => ({
id: phase.id,
sequenceNumber: phase.sequenceNumber,
name: phase.name,
durationYears: phase.durationYears,
inflationRate: phase.inflationRate,
incomeMode: phase.incomeMode,
incomeEntries: phase.incomeEntries.map((e) => ({
id: e.id,
personId: e.personId,
label: e.label,
amount: e.amount,
})),
expenseEntries: phase.expenseEntries.map((e) => ({
id: e.id,
label: e.label,
amount: e.amount,
})),
securities: phase.securities.map((s) => ({
id: s.id,
name: s.name,
startValue: s.startValue,
expectedReturn: s.expectedReturn,
annualContribution: s.annualContribution,
ownerTag: s.ownerTag,
saleTaxRate: s.saleTaxRate,
})),
realEstates: phase.realEstates.map((re) => ({
id: re.id,
name: re.name,
marketValue: re.marketValue,
mortgage: re.mortgage,
valueGrowth: re.valueGrowth,
amortization: re.amortization,
salePrice: re.salePrice,
saleTaxRate: re.saleTaxRate,
})),
oneTimeEvents: phase.oneTimeEvents.map((e) => ({
id: e.id,
type: e.type,
amount: e.amount,
description: e.description,
})),
retirementInfos: phase.retirementInfos.map((r) => ({
id: r.id,
personId: r.personId,
ahvAmount: r.ahvAmount,
pkPensionAmount: r.pkPensionAmount,
lumpSumAmount: r.lumpSumAmount,
lumpSumTaxRate: r.lumpSumTaxRate,
})),
})),
};
}
export async function getHouseholdOrNull(): Promise<HouseholdWithPersons | null> {
return prisma.household.findFirst({ include: { persons: true } });
}