# 27-Apr-2026 — cascade-delete mail list audit rows on bulk delete + GDPR orphan sweep [ref #18](https://github.com/nbarrett/ngx-ramblers/issues/18)

## [build 627](https://github.com/nbarrett/ngx-ramblers/actions/runs/24994004980) — [commit 3d9039e](https://github.com/nbarrett/ngx-ramblers/commit/3d9039efac9745461c5f923f9ca925ed52106aa1)

_____

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.