27-Apr-2026 — cascade-delete mail list audit rows on bulk delete + GDPR orphan sweep ref #18

build 627commit 3d9039e


When members are bulk-deleted we previously left their entries in the mailListAudit collection behind. That meant unsubscribe/audit history kept showing the bare Mongo ObjectId in the Brevo Unsubscribes view (no name, no email — just the deleted member's ID), and more importantly it left identifiable records hanging around past the point where the member record itself was gone. Not appropriate for a Ramblers endorsed project.

Three pieces:

  1. Cascade — MemberBulkDeleteService now calls a new server endpoint (POST /api/database/mail-list-audit/delete-by-members) immediately after deleting members. Audit rows for those member IDs are removed in a single deleteMany. Errors here log but don't fail the whole bulk-delete operation, so the member deletion is never left half done.

  2. Orphan sweep — same flow then calls POST /api/database/mail-list-audit/delete-orphans which removes any audit row whose memberId no longer matches an existing member. Backstop for any data that drifts in via other delete pathways or direct database edits.

  3. One-off migration — 20260427100000-purge-orphan-mail-list-audit.ts does the same orphan sweep once on next deploy so historical pre-cascade orphans are cleaned up before the new cascade goes live. Idempotent — safe to re-run.

MongoDB doesn't enforce foreign keys, so this is application-level cascade rather than DB-level. The migration is the necessary cleanup of pre-existing orphans before activating the new behaviour.