Files
talktime/features/PROJ-12-mitglieder-loeschfrist.md
patrickandClaude Sonnet 5 4cb2284ad9 docs: spec PROJ-12 — automatic retention-based deletion for left members (GDPR)
Configurable per-organization retention period, daily job, reuses the
existing hard-delete path from PROJ-3 instead of introducing a new one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0143yYvjesjHndBACoweyK67
2026-09-11 18:47:59 +02:00

4.2 KiB

PROJ-12: Automatische Löschfrist für ausgetretene Mitglieder (DSGVO)

Status: Planned Created: 2026-09-11

Summary

Mitglieder mit Status left (Austritt) werden aktuell unbegrenzt aufbewahrt — PROJ-3 sperrt nur den API-/Matrix-Zugriff, löscht aber keine Daten. Das verletzt den DSGVO-Grundsatz der Speicherbegrenzung (Art. 5 Abs. 1 lit. e, Art. 17): sobald kein Zweck mehr besteht (keine Mitgliedschaft, keine gesetzliche Aufbewahrungspflicht für reine Mitgliederdaten ohne Beitrags-/Buchhaltungsbezug — siehe PRD Non-Goals), müssen die Daten gelöscht werden. Dieses Feature führt eine vereinskonfigurierbare Aufbewahrungsfrist ein, nach der left-Mitglieder automatisch über den bestehenden DELETE /api/members/:memberId-Pfad (PROJ-3) hart gelöscht werden.

Dependencies

  • Requires: PROJ-3 (Mitgliederverwaltung) — nutzt den bestehenden harten Lösch-Pfad (Matrix-Erase, Cascade-Deletes, Audit-Log) 1:1, nur automatisch statt manuell ausgelöst
  • Requires: PROJ-2 (Verein anlegen) — Frist wird pro Organisation konfiguriert

User Stories

  1. Als Vereinsadmin will ich pro Verein festlegen, nach wie vielen Tagen ausgetretene Mitglieder automatisch gelöscht werden, damit ich die Satzung/Aufbewahrungspraxis meines Vereins abbilden kann.
  2. Als Vereinsadmin will ich einen sinnvollen Standardwert vorfinden, falls ich die Einstellung nicht bewusst ändere, damit DSGVO-Konformität nicht von mir vergessen werden kann.
  3. Als System will ich täglich prüfen, welche left-Mitglieder die Frist ihrer Organisation überschritten haben, und sie automatisch löschen.
  4. Als Vereinsadmin will ich im Audit-Log sehen, dass ein Mitglied automatisch (nicht manuell) gelöscht wurde, um den Vorgang nachvollziehen zu können.

Acceptance Criteria

  • organizations-Tabelle bekommt Feld memberRetentionDays (integer, not null, Default 90)
  • Neues UI-Feld in den Organisationseinstellungen zum Ändern der Frist (nur Org-Admin)
  • Täglicher Hintergrund-Job (analog startReconciliationWorker-Pattern in sync-worker.ts) prüft members mit status = 'left', deren updatedAt (Zeitpunkt des Status-Wechsels) älter ist als organizations.memberRetentionDays
  • Betroffene Mitglieder werden über denselben Pfad wie manuelles Löschen entfernt (Matrix-Erase, Cascade-Deletes für Team-Zuordnungen/Rollen/Eltern-Verknüpfungen)
  • Audit-Log-Eintrag action: "member.auto_deleted" mit actorUserId: null (System-Aktion, kein menschlicher Akteur), Metadata enthält die angewandte Frist
  • Keine Benachrichtigung an Admin vor der Löschung (bewusst still im Hintergrund)
  • Reaktivierung vor Fristablauf (Status zurück auf active) bricht die geplante Löschung ab — Job muss den aktuellen Status zum Ausführungszeitpunkt prüfen, nicht nur einmalig einplanen

Edge Cases

  • members.updatedAt existiert aktuell nicht im Schema (nur createdAt) — muss ergänzt werden, sonst kein verlässlicher Zeitpunkt für "seit wann left"
  • Mitglied wird mehrfach left→active→left — Frist zählt ab dem letzten Wechsel zu left, nicht kumulativ
  • Sehr kurze Frist (z.B. 0 oder negative Werte) — Validierung auf Minimum (z.B. ≥ 1 Tag) im Backend
  • Job läuft während laufender manueller Löschung desselben Mitglieds — DELETE-Route ist idempotent genug (member existiert nicht mehr → 404), Job sollte 404 vom eigenen internen Aufruf abfangen statt zu crashen
  • Synapse nicht erreichbar während Auto-Löschung — gleiches Verhalten wie beim manuellen Löschen: Matrix-Erase-Fehler wird geloggt, DB-Löschung läuft trotzdem durch (siehe bestehendes try/catch in PROJ-3)

Non-Goals (für dieses Feature)

  • Self-Service-Löschantrag durch das Mitglied selbst (Art. 17-Betroffenenrecht als eigener Flow) — separates Feature
  • Aufbewahrung von Beitrags-/Buchhaltungsdaten (10-Jahres-Frist nach §147 AO) — laut PRD Non-Goal (kein Buchhaltungsmodul), betrifft dieses Feature nicht
  • Anonymisierung statt Löschung als Alternative — MVP macht hartes Löschen, kein Soft-Anonymisieren

Notes

Direkt aus DSGVO-Rückfrage im Chat entstanden, kein formaler Requirements-Workshop nötig — Scope ist klar umrissen durch bestehenden Lösch-Pfad aus PROJ-3.