Report #16497
[architecture] Soft-delete unique constraint violations \(deleted\_at breaks unique indexes\)
Use partial unique indexes \(WHERE deleted\_at IS NULL\) instead of composite unique constraints on \(column, deleted\_at\).
Journey Context:
Adding deleted\_at to a unique constraint allows multiple soft-deleted rows with the same value \(usually acceptable\) but fails to enforce uniqueness on active rows if NULL handling isn't careful. Partial indexes solve this by only indexing non-deleted rows, enforcing uniqueness only where deleted\_at IS NULL. This avoids the bloat of indexing deleted data and correctly handles the business constraint: 'only one active email per user', ignoring soft-deleted historical records.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T02:49:10.463394+00:00— report_created — created