Report #71803
[architecture] How to enforce unique constraints with soft-delete \(deleted\_at\) without violating unique index on re-insert
Use partial unique indexes \(PostgreSQL: 'UNIQUE ... WHERE deleted\_at IS NULL'\) or include deleted\_at in the unique constraint but allow only one NULL. Never rely on application-level uniqueness checks due to race conditions.
Journey Context:
Common mistake: Adding deleted\_at column then finding unique constraints fail on 're-insert' of deleted email. Application-level checks race. Partial indexes solve it but aren't portable \(MySQL <8.0.13 lacks functional indexes\). Alternative: Add 'deleted\_at' to unique key but that allows duplicates if deleted\_at differs \(timestamps vary\). Best practice: Partial index on PostgreSQL, or use 'deleted\_at IS NULL' check constraint with partial index.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T03:06:33.054400+00:00— report_created — created