Files
RFP_Finanzen/src/app/api/settings/route.ts
2026-04-12 20:09:46 +02:00

66 lines
2.0 KiB
TypeScript

import { NextResponse } from "next/server";
import { z } from "zod";
import { getAppSettings, toApprovalThresholdNumber } from "@/lib/app-settings";
import { snapshotAppSettings } from "@/lib/audit-snapshots";
import { createAuditLog } from "@/lib/audit-log";
import { canManageUsers } from "@/lib/domain";
import prisma from "@/lib/prisma";
import { getCurrentViewer } from "@/lib/session";
const settingsSchema = z.object({
approvalThreshold: z.coerce.number().min(0).max(100000)
});
export async function PATCH(request: Request) {
const viewer = await getCurrentViewer();
if (!viewer) {
return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 });
}
if (!canManageUsers(viewer.role)) {
return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Einstellungen aendern." }, { status: 403 });
}
const body = await request.json().catch(() => null);
const parsed = settingsSchema.safeParse(body);
if (!parsed.success) {
return NextResponse.json({ error: "Bitte eine gueltige Freigabe-Schwelle eingeben." }, { status: 400 });
}
const existingSettings = await getAppSettings();
const previousSnapshot = snapshotAppSettings(existingSettings);
const appSettings = await prisma.appSettings.update({
where: {
id: existingSettings.id
},
data: {
approvalThreshold: parsed.data.approvalThreshold
}
});
await createAuditLog(prisma, {
actorId: viewer.id,
action: "settings.update",
entityType: "settings",
entityId: appSettings.id,
entityLabel: "Freigabe-Schwelle",
summary: `Freigabe-Schwelle wurde auf ${toApprovalThresholdNumber(appSettings.approvalThreshold).toFixed(2)} EUR gesetzt.`,
metadata: {
approvalThreshold: toApprovalThresholdNumber(appSettings.approvalThreshold),
rollback: {
kind: "settings.update",
previous: previousSnapshot
}
}
});
return NextResponse.json({
ok: true,
approvalThreshold: toApprovalThresholdNumber(appSettings.approvalThreshold)
});
}