import { NextResponse } from "next/server"; import crypto from "crypto"; import { prisma } from "@/lib/prisma"; function safeCompareSecret(provided: string | null, expected: string | undefined): boolean { if (!provided || !expected) return false; const bufA = Buffer.from(provided); const bufB = Buffer.from(expected); if (bufA.length !== bufB.length) return false; return crypto.timingSafeEqual(bufA, bufB); } /** * Route pour le nettoyage automatique des comptes * À appeler via une tâche cron (ex: chaque nuit à minuit) * Supporte `Authorization: Bearer ` ou `?key=` */ export async function GET(request: Request) { const { searchParams } = new URL(request.url); const authHeader = request.headers.get("authorization"); const bearerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice("Bearer ".length).trim() : null; const key = bearerToken || searchParams.get("key"); if (!safeCompareSecret(key, process.env.CRON_SECRET)) { return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); } try { const now = new Date(); // 1. Trouver les utilisateurs dont le délai est passé const usersToDelete = await prisma.user.findMany({ where: { deletionScheduledAt: { lte: now } } }); if (usersToDelete.length === 0) { return NextResponse.json({ message: "Aucun compte à supprimer" }); } const userIds = usersToDelete.map(u => u.id); // 2. Préserver les avis rédigés en les dissociant du compte (deviennent anonymes / "Utilisateur supprimé") await prisma.rating.updateMany({ where: { userId: { in: userIds } }, data: { userId: null } }); // 3. Suppression définitive des comptes utilisateurs const deleteResult = await prisma.user.deleteMany({ where: { id: { in: userIds } } }); return NextResponse.json({ message: `${deleteResult.count} compte(s) supprimé(s) définitivement`, deletedIds: usersToDelete.map(u => u.id) }); } catch (error) { console.error("Cron Cleanup Error:", error); return NextResponse.json({ error: "Erreur lors du nettoyage" }, { status: 500 }); } }