import type { Prisma } from "@prisma/client"; import { UserFacingError } from "@/lib/action-error"; // Serialize role changes, account deletion and support locks for the same Kita. export async function lockKitaAccounts( tx: Prisma.TransactionClient, kitaId: string, ) { const rows = await tx.$queryRaw< { id: string }[] >`SELECT id FROM kitas WHERE id = ${kitaId} FOR UPDATE`; if (!rows.length) throw new UserFacingError("Kita wurde nicht gefunden."); } export async function assertKitaAdminRemains( tx: Prisma.TransactionClient, kitaId: string, excludedUserIds: string[], ) { const removesAdmin = await tx.user.count({ where: { kitaId, id: { in: excludedUserIds }, role: "ADMIN" }, }); if (!removesAdmin) return; const now = new Date(); const remaining = await tx.user.count({ where: { kitaId, id: { notIn: excludedUserIds }, role: "ADMIN", disabledAt: null, emailVerifiedAt: { not: null }, privacyPolicyAcceptedAt: { not: null }, passwordHash: { not: "" }, OR: [{ lockedUntil: null }, { lockedUntil: { lte: now } }], }, }); if (!remaining) throw new UserFacingError( "Mindestens ein aktiver Kita-Admin muss erhalten bleiben. Ernenne zuerst eine weitere Person mit aktiviertem Zugang und Datenschutzzustimmung.", ); }