import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { prisma } from "@/lib/db"; import { getOwnedPlan } from "@/lib/queries"; import { getCurrentUserId } from "@/lib/session"; const scenarioSchema = z.object({ name: z.string().min(1).max(120), branchFromPhaseId: z.string().min(1), }); // Erstellt ein Szenario als Deep-Copy eines Plans bis zur Verzweigungsphase (inkl.). export async function POST( request: NextRequest, { params }: { params: Promise<{ planId: string }> } ) { const userId = await getCurrentUserId(); if (!userId) return NextResponse.json({ error: "Nicht authentifiziert." }, { status: 401 }); const { planId } = await params; const body = await request.json(); const parsed = scenarioSchema.safeParse(body); if (!parsed.success) return NextResponse.json({ error: "Ungueltige Eingabe." }, { status: 400 }); const source = await getOwnedPlan(planId, userId); if (!source) return NextResponse.json({ error: "Ursprungsplan nicht gefunden." }, { status: 404 }); const branchPhase = source.phases.find((p) => p.id === parsed.data.branchFromPhaseId); if (!branchPhase) return NextResponse.json({ error: "Verzweigungsphase nicht gefunden." }, { status: 404 }); const copiedPhases = source.phases .filter((p) => p.sequenceNumber <= branchPhase.sequenceNumber) .sort((a, b) => a.sequenceNumber - b.sequenceNumber); const copiedPhaseIds = new Set(copiedPhases.map((p) => p.id)); const newPlanId = await prisma.$transaction(async (tx) => { const newPlan = await tx.plan.create({ data: { userId, name: parsed.data.name, householdType: source.householdType, inflationRateDefault: source.inflationRateDefault, initialCash: source.initialCash, parentPlanId: source.id, persons: { create: source.persons.map((p) => ({ role: p.role, name: p.name, age: p.age, retirementAge: p.retirementAge })), }, }, }); // Phasen kopieren (alte -> neue Id). const phaseIdMap = new Map(); let lastNewPhaseId = ""; for (const phase of copiedPhases) { const created = await tx.phase.create({ data: { planId: newPlan.id, sequenceNumber: phase.sequenceNumber, name: phase.name, durationYears: phase.durationYears, }, }); phaseIdMap.set(phase.id, created.id); lastNewPhaseId = created.id; } // Elemente + deren Phasen-/Uebergangswerte kopieren. for (const el of source.elements) { const newEl = await tx.financialElement.create({ data: { planId: newPlan.id, category: el.category, name: el.name, ownerRole: el.ownerRole, orderIndex: el.orderIndex, }, }); for (const pv of el.phaseValues) { const newPhaseId = phaseIdMap.get(pv.phaseId); if (!newPhaseId) continue; await tx.elementPhaseValue.create({ data: { elementId: newEl.id, phaseId: newPhaseId, data: pv.data as object }, }); } for (const tv of el.transitionValues) { if (!copiedPhaseIds.has(tv.fromPhaseId)) continue; const newFromId = phaseIdMap.get(tv.fromPhaseId); if (!newFromId) continue; await tx.elementTransitionValue.create({ data: { elementId: newEl.id, fromPhaseId: newFromId, data: tv.data as object }, }); } } await tx.plan.update({ where: { id: newPlan.id }, data: { branchFromPhaseId: lastNewPhaseId } }); return newPlan.id; }); return NextResponse.json({ planId: newPlanId }, { status: 201 }); }