karbe/src/app/admin/users/actions.ts

59 lines
2.3 KiB
TypeScript

"use server";
import { revalidatePath } from "next/cache";
import { auth } from "@/auth";
import { UserRole } from "@/generated/prisma/enums";
import { requireRole } from "@/lib/authorization";
import { prisma } from "@/lib/prisma";
import { recordAudit } from "@/lib/admin/audit";
const ROLE_VALUES = new Set<string>([
UserRole.OWNER,
UserRole.CE_MANAGER,
UserRole.CE_MEMBER,
UserRole.TOURIST,
UserRole.ADMIN,
]);
async function audit(event: string, target: string, actor: string | null, details: Record<string, unknown>) {
await recordAudit({ scope: "admin.users", event, target, actorEmail: actor, details });
}
export async function updateUserRoleAction(id: string, role: string) {
await requireRole([UserRole.ADMIN]);
if (!ROLE_VALUES.has(role)) {
return { ok: false as const, error: "Rôle invalide" };
}
const session = await auth();
if (role !== UserRole.ADMIN) {
const adminCount = await prisma.user.count({ where: { role: UserRole.ADMIN, isActive: true } });
const current = await prisma.user.findUnique({ where: { id }, select: { role: true } });
if (current?.role === UserRole.ADMIN && adminCount <= 1) {
return { ok: false as const, error: "Impossible de retirer le dernier admin actif." };
}
}
await prisma.user.update({ where: { id }, data: { role: role as UserRole } });
await audit("user.role.update", id, session?.user?.email ?? null, { role });
revalidatePath("/admin/users");
revalidatePath(`/admin/users/${id}`);
return { ok: true as const };
}
export async function toggleUserActiveAction(id: string, active: boolean) {
await requireRole([UserRole.ADMIN]);
const session = await auth();
if (!active) {
const target = await prisma.user.findUnique({ where: { id }, select: { role: true, isActive: true } });
if (target?.role === UserRole.ADMIN) {
const adminCount = await prisma.user.count({ where: { role: UserRole.ADMIN, isActive: true } });
if (adminCount <= 1) {
return { ok: false as const, error: "Impossible de désactiver le dernier admin." };
}
}
}
await prisma.user.update({ where: { id }, data: { isActive: active } });
await audit("user.active.update", id, session?.user?.email ?? null, { active });
revalidatePath("/admin/users");
revalidatePath(`/admin/users/${id}`);
return { ok: true as const };
}