From a16f418e7100a6297e333b24945dc0147f513b4c Mon Sep 17 00:00:00 2001 From: Hardik Date: Thu, 28 May 2026 23:20:18 +0530 Subject: [PATCH] fix(admin): guard user deletion against all FK constraints The delete action was only checking for submitted POs, leaving POAction (actorId) and ItemConsumption (recordedById) to throw FK constraint errors at the DB level. Now returns a clear error for each case and also cleans up SuperUserRequest rows (requester + resolver) inside the transaction before deleting. Co-Authored-By: Claude Sonnet 4.6 --- App/app/(portal)/admin/users/actions.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/App/app/(portal)/admin/users/actions.ts b/App/app/(portal)/admin/users/actions.ts index 19e6d8d..52c7de0 100644 --- a/App/app/(portal)/admin/users/actions.ts +++ b/App/app/(portal)/admin/users/actions.ts @@ -109,11 +109,20 @@ export async function deleteUser(id: string): Promise { if (!session?.user || !hasPermission(session.user.role, "manage_users")) return { error: "Unauthorized" }; if (id === session.user.id) return { error: "Cannot delete your own account." }; - const inUse = await db.purchaseOrder.findFirst({ where: { submitterId: id } }); - if (inUse) return { error: "Cannot delete: user has submitted purchase orders. Deactivate them instead." }; + const hasPos = await db.purchaseOrder.findFirst({ where: { submitterId: id } }); + if (hasPos) return { error: "Cannot delete: user has submitted purchase orders. Deactivate them instead." }; + + const hasActions = await db.pOAction.findFirst({ where: { actorId: id } }); + if (hasActions) return { error: "Cannot delete: user has purchase order activity on record. Deactivate them instead." }; + + const hasConsumption = await db.itemConsumption.findFirst({ where: { recordedById: id } }); + if (hasConsumption) return { error: "Cannot delete: user has inventory consumption records. Deactivate them instead." }; await db.$transaction(async (tx) => { await tx.notification.deleteMany({ where: { userId: id } }); + await tx.superUserRequest.deleteMany({ + where: { OR: [{ userId: id }, { resolvedById: id }] }, + }); await tx.user.delete({ where: { id } }); });