Wann du es brauchst
Eine neue Tabelle, ein Bucket oder ein externer Dienst enthält Daten eines Nutzers, zum Beispiel Tagebucheinträge, hochgeladene Dokumente oder ein Newsletter-Abo. "Delete account" in den Datenschutzeinstellungen muss auch diese entfernen.
Regeln
- Die Kontolöschung entfernt alles, was das Produkt für den Nutzer speichert,
und danach den Auth-Nutzer, wie
PRODUCT.mdes verspricht. - Nur die Edge Function
delete-accountlöscht, und zwar für den Nutzer des JWT, den sie geprüft hat.public.delete_my_accountbleibt nur fürservice_roleausführbar; nimm die Nutzer-ID nie aus dem Request-Body. - Dateien werden über die Storage API entfernt. Ein
delete from storage.objectsentfernt nur die Metadaten und lässt die Datei im Bucket. - Jeder fehlgeschlagene Schritt bricht mit einem Fehler ab, bevor der Auth-Nutzer gelöscht wird, damit der Nutzer es erneut versuchen kann.
- Migrationen sind append-only: Definiere die Funktion in einer neuen Migration neu.
Schritte
Gib jeder neuen Tabelle ein
user_id uuid not null references auth.users(id) on delete cascade(oder eine Referenz aufpublic.profiles(id)), damit ihre Zeilen das Konto nie überleben.Definiere
public.delete_my_accountin einer neuen Migration mitcreate or replace functionneu. Übernimm den Rumpf aus der letzten Migration, die sie definiert (derzeit202611020001_fix_account_deletion.sql), und ergänze die neue Tabelle, damit die Funktion die vollständige Liste dessen bleibt, was die Löschung entfernt:delete from public.journal_entries where user_id = p_user_id;Behalte die Signatur und
security definer set search_path = ''bei und wiederhole die Zeilenrevoke execute ... from public, anon, authenticatedundgrant execute ... to service_role.Lege Dateien unter
<user-id>/...ab, wie der Bucketavatars. Entferne sie insupabase/functions/delete-account/index.tswie die Avatare, vor dem RPC:list(user.id)liefert höchstens 100 Einträge und geht nicht in Unterordner, wiederhole alsolistundremove, bis die Liste leer ist, oder halte den Ordner flach.Für Daten in einem externen Dienst rufe dessen Lösch-API aus der Edge Function auf, mit einem Schlüssel aus den Secrets der Funktion, vor dem RPC. Schlägt der Aufruf fehl, antworte wie die anderen Schritte mit 500.
Erweitere
supabase/tests/database/delete_my_account.test.sql: Füge als Eigentümer des Tests Zeilen für zwei Nutzer ein, rufepublic.delete_my_accountfür den ersten auf und prüfe, dass nur seine Zeilen weg sind. Behalte die vorhandenen Prüfungen der Rechte.Führe
supabase db resetundsupabase test dbaus, lösche dann ein Testkonto in der App und prüfe im Dashboard, dass keine Zeilen oder Dateien übrig sind.Beschreibe die neuen Daten in
DATABASE.mdund ihre Aufbewahrung inPRODUCT.md.
Fertig, wenn
- die Prüfbefehle und
supabase test dbdurchlaufen; - das Löschen eines Testkontos keine Zeilen, Dateien oder externen Datensätze zurücklässt;
delete_my_accountweiterhin nicht vonanonoderauthenticatedausführbar ist;DATABASE.mdundPRODUCT.mddie neuen Daten beschreiben.
