import { serverSupabaseServiceRole } from "../../utils/useSupabase"; import { deleteUserUrgeLogs } from "../../db/urge"; import { deleteUserSosSessions } from "../../db/sosSession"; import { deleteUserStreaks } from "../../db/streak"; import { deleteUserPosts } from "../../db/community"; import { deleteAllUserCustomDomains } from "../../db/domains"; import { deleteUserTrustedContacts, deleteUserCoachSessions, } from "../../db/user"; import { deleteProfile } from "../../db/profile"; import { deleteAllMailConnections, deleteUserMailClassificationSamples, } from "../../db/mail"; import { writeConsentRevoke } from "../../db/consent"; import { usePrisma } from "../../utils/prisma"; export default defineEventHandler(async (event) => { const user = await requireUser(event); const supabase = serverSupabaseServiceRole(event); const userId = user.id; // DSGVO Art. 9: Consent-Widerruf für alle MailConnections vor Löschung // (append-only — consent_logs-Rows bleiben für Beweiszwecke erhalten) const db = usePrisma(); const mailConnections = await db.mailConnection.findMany({ where: { userId }, select: { id: true, consentVersion: true, authMethod: true }, }); const now = new Date(); for (const conn of mailConnections) { // Widerruf-Log schreiben — fire-and-forget, kein throw wenn es fehlschlägt writeConsentRevoke({ userId, consentType: "art9-mail", consentVersion: conn.consentVersion ?? "none", revokedAt: now, revokeReason: "account_deleted", mailConnectionId: conn.id, }).catch(() => {}); // TODO (mo — Mail-Stack): OAuth Token-Revoke bei MS bevor Row gelöscht wird. // Wenn conn.authMethod === 'oauth2_microsoft': Token-Revoke best-effort. // Tracking: consent-gap-plan.md TODO #2 } // Delete all user data (DSGVO Art. 17) // Reihenfolge: Samples VOR Connections löschen (oder parallel — FK-Reihenfolge // egal weil wir nach userId filtern). Samples haben keine userId-FK-Cascade // im Schema (connectionId ist nullable), daher manuelles Cleanup zwingend. await Promise.all([ deleteUserUrgeLogs(userId), deleteUserSosSessions(userId), deleteUserStreaks(userId), deleteUserPosts(userId), deleteAllUserCustomDomains(userId), deleteUserTrustedContacts(userId), deleteUserCoachSessions(userId), deleteUserMailClassificationSamples(userId), deleteAllMailConnections(userId), ]); // Profil zuletzt löschen (FK-Abhängigkeiten sind bereits entfernt) await deleteProfile(userId).catch(() => {}); // Auth-User löschen (bleibt Supabase) await supabase.auth.admin.deleteUser(userId); return { success: true }; });