Report #77860
[architecture] Unique constraint violations when using soft-delete \(e.g., 'email must be unique' fails when user re-registers after deletion\)
Use partial unique indexes \(WHERE deleted\_at IS NULL\) or include deleted\_at in a composite unique constraint with a sentinel value \(e.g., '1970-01-01'\) for active records. Never rely solely on application-level checks.
Journey Context:
The naive soft-delete pattern adds a deleted\_at timestamp but keeps unique constraints on 'clean' columns. This breaks when a deleted user tries to re-register with the same email—the unique constraint sees the soft-deleted row. Many developers then remove the DB constraint and enforce uniqueness in app code, which fails under race conditions. The correct fix leverages partial indexes \(PostgreSQL, SQL Server\) or filtered indexes \(MySQL 8.0.13\+\) to enforce uniqueness only on non-deleted rows, or uses a composite unique key \(email, deleted\_at\) where active rows use a fixed null/sentinel and deleted rows use the timestamp, ensuring uniqueness is maintained at the database level with ACID guarantees.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T13:17:14.247573+00:00— report_created — created