You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is no automatic expiration or cleanup engine for any data category. While several tables have expiresAt fields, enforcement happens at the read layer only (filtering expired records from queries), with no periodic deletion of expired data.
Current State
Tables with expiresAt but no automated cleanup:
pulse_summaries (6-hour TTL) — indexed but never cleaned
page_versions (30-day default, subscription-tier based) — filtered at query time only
sessions, verification_tokens, socket_tokens, email_unsubscribe_tokens — no cleanup
drive_backups, drive_backup_permissions, page_permissions — no cleanup
What does get cleaned up:
device_tokens — hourly cron marks as revoked (but doesn't hard-delete)
Redis JTIs — auto-expired by Redis TTL
Notable: A retention_policies table was created in migration 0025 but dropped in migration 0071, suggesting the feature was abandoned.
Impact
Database grows unbounded with expired but never-deleted records
No compliance with data minimization principles (GDPR Art. 5(1)(e))
Problem
There is no automatic expiration or cleanup engine for any data category. While several tables have
expiresAtfields, enforcement happens at the read layer only (filtering expired records from queries), with no periodic deletion of expired data.Current State
Tables with
expiresAtbut no automated cleanup:pulse_summaries(6-hour TTL) — indexed but never cleanedpage_versions(30-day default, subscription-tier based) — filtered at query time onlysessions,verification_tokens,socket_tokens,email_unsubscribe_tokens— no cleanupdrive_backups,drive_backup_permissions,page_permissions— no cleanupWhat does get cleaned up:
device_tokens— hourly cron marks as revoked (but doesn't hard-delete)Notable: A
retention_policiestable was created in migration 0025 but dropped in migration 0071, suggesting the feature was abandoned.Impact
Proposed Solution
Build a retention policy engine that:
expiresAtacross all relevant tablescleanup-tokens)Effort: Medium
References
docker/cron/crontabapps/web/src/app/api/cron/cleanup-tokens/route.tsapps/web/src/services/api/rollback-service.ts(getUserRetentionDays())