Initial commit

This commit is contained in:
Jan
2026-04-08 16:30:44 +02:00
commit f9b17e9964
65 changed files with 7574 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
import { NextResponse } from "next/server";
import { snapshotUser } 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";
type Context = {
params: {
id: string;
};
};
export async function DELETE(_: Request, { params }: Context) {
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 Nutzer loeschen." }, { status: 403 });
}
if (viewer.id === params.id) {
return NextResponse.json({ error: "Du kannst dein eigenes Konto hier nicht loeschen." }, { status: 400 });
}
const user = await prisma.user.findUnique({
where: { id: params.id },
include: {
_count: {
select: {
approvals: true,
createdExpenses: true
}
}
}
});
if (!user) {
return NextResponse.json({ error: "Nutzer nicht gefunden." }, { status: 404 });
}
if (user._count.approvals > 0 || user._count.createdExpenses > 0) {
return NextResponse.json(
{ error: "Nutzer mit Freigaben oder Ausgaben koennen nicht geloescht werden." },
{ status: 400 }
);
}
if (user.role === "ADMIN") {
const adminCount = await prisma.user.count({
where: { role: "ADMIN" }
});
if (adminCount <= 1) {
return NextResponse.json({ error: "Mindestens ein Admin muss erhalten bleiben." }, { status: 400 });
}
}
await prisma.user.delete({
where: { id: params.id }
});
await createAuditLog(prisma, {
actorId: viewer.id,
action: "user.delete",
entityType: "user",
entityId: user.id,
entityLabel: user.username,
summary: `Nutzer ${user.username} wurde geloescht.`,
metadata: {
rollback: {
kind: "user.delete",
deleted: snapshotUser(user)
}
}
});
return NextResponse.json({ ok: true });
}