GDPR Art. 17 ("right to be forgotten") and CCPA §1798.105 both require that a user who asks for their account and personal data to be deleted actually gets it deleted — not hidden behind a deletedAt timestamp while the email, name, and history sit indefinitely in the database. CNIL fined Clearview AI €20M in 2022 in part for failing to act on erasure requests, and ICO enforcement routinely issues multi-million-pound penalties on the same grounds. Beyond regulatory exposure, the Apple App Store and Google Play Store have both mandated in-app account deletion since 2022: apps that gate deletion behind a support-email workflow get rejected at review. AI coding tools reliably scaffold signup, login, and password reset, then skip the deletion route entirely — because "how do I build auth" is a well-represented training pattern and "how do I build GDPR-compliant erasure" is not. The quiet failure mode is a live app that passes every happy-path test while accumulating unlawful retention exposure with every new user.
Critical because missing or stub-only deletion is a direct ongoing Art. 17 violation accruing exposure per active user per day, blocks App Store and Play Store approval outright, and cannot be patched retroactively against users who already asked and were ignored.
Ship an authenticated DELETE route (e.g. app/api/account/route.ts) that either hard-deletes the user row with cascades to related PII-bearing tables, or anonymizes in place (email = null, name = 'Deleted user', pii_purged = true). If you soft-delete first, add a scheduled purge job that runs after a documented 14–30 day grace period and removes the underlying data across every table, object-storage bucket, and third-party processor that holds it.
Deeper remediation guidance and cross-reference coverage for this check lives in the gdpr-readiness and ccpa-readiness Pro audits — run those after applying this fix for a more exhaustive pass on the same topic.
project-snapshot.legal.account-deletion-codedcriticalpackage.json (next-auth, @clerk/*, @supabase/supabase-js, lucia, auth0, firebase/auth, better-auth), OR auth routes (/auth/*, /signup, /login), OR User/Account model in prisma/schema.prisma or users table in migrations. If no accounts, skip. If accounts exist, enumerate: (a) a DELETE handler at app/api/user/*, app/api/account/*, app/api/me/*, pages/api/user/*, or a server action matching /^(delete|anonymize|purge)(Account|User|Me)$/i; AND (b) the handler must actually remove or anonymize PII — prisma.user.delete(...), supabase.auth.admin.deleteUser(...), DELETE FROM users, or UPDATE users SET email = null / pii_purged = true / name = 'Deleted'.deletedAt / isDeleted with no paired purge job (no route under app/api/cron/* or supabase/functions/* that purges past-grace-period rows). Soft-delete without a scheduled follow-up is not erasure."No auth library, auth routes, or user model — project has no user accounts"."Deletion handler at <path>; mechanism: hard-delete | anonymize | soft-delete+cron at <cron-path>"."next-auth present, /login route exists, but no DELETE endpoint under app/api/user/, account/, or me/" or "app/api/account/route.ts only runs prisma.user.update({ data: { deletedAt: new Date() } }) — no purge cron".app/api/account/route.ts that hard-deletes (with cascades), anonymizes-in-place (email = null, name = 'Deleted user', pii_purged = true), OR soft-deletes paired with a scheduled purge after a 14–30 day grace period across every table, storage bucket, and third-party processor. Deeper coverage: gdpr-readiness, ccpa-readiness.