Deletion does not corrupt aggregate analytics
Why it matters
GDPR Article 17(3) explicitly permits retention of data necessary for the purposes of archiving in the public interest, scientific or historical research, or statistical purposes — precisely because deleting event rows that underpin aggregate metrics corrupts the historical record without serving the data subject's interests. CWE-459 (Incomplete Cleanup) describes the other side: cleanup that removes more than necessary. Hard-deleting email event rows during erasure can silently corrupt dashboard metrics (open rates, click rates, send volume charts) by removing the denominator rows their calculations depend on, while the PII attached to those rows is what actually needed to go.
Severity rationale
Low because aggregate corruption from over-deletion is a product reliability issue that becomes a compliance complication only when the corrupted metrics are relied on in regulatory or financial reporting.
Remediation
Anonymize event records instead of deleting them. Null out the PII fields while leaving the row intact so aggregate counts remain accurate:
// src/lib/compliance/deletion.ts — anonymize, do not delete, event rows
await db.emailEvent.updateMany({
where: { contactId },
data: {
email: null,
ipAddress: null,
userAgent: null,
// contactId: null — only if FK allows null; otherwise use a sentinel 'erased' UUID
}
})
After anonymization, a query like SELECT COUNT(*) FROM email_events WHERE occurred_at BETWEEN ... still returns the correct count, but the row carries no PII. Document this choice in src/lib/compliance/deletion.ts with a comment explaining why anonymization is used instead of deletion — future engineers must not refactor it to deleteMany.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Compliance & Consent Engine Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- gdpr · Art. 17(3) — Right to erasure — exceptions for statistical/public interest purposes
- cwe · CWE-459 — Incomplete cleanup — hard-delete corrupts aggregates instead of anonymising
- iso-25010:2011 · functional-suitability.functional-correctness — Functional correctness — aggregate metrics remain accurate after erasure
Taxons
History
- 2026-04-18·v1.0.0·Initial import from compliance-consent-engine·automated