Report #96710
[architecture] Soft-delete pattern breaks unique constraints \(e.g., unique email allows deleted user to block new signup\)
Use partial unique indexes \(PostgreSQL\) or filtered unique constraints \(SQL Server\) that exclude soft-deleted rows: CREATE UNIQUE INDEX idx\_unique\_email ON users\(email\) WHERE deleted\_at IS NULL. Never rely on application-level checks for uniqueness.
Journey Context:
Standard soft-delete implementations add deleted\_at timestamp and forget that UNIQUE constraints in SQL are table-wide. This creates the 'zombie block' bug where a deleted user's email permanently blocks new registrations. Application-level uniqueness checks race and fail under concurrent load. Partial indexes solve this at the database level with no performance penalty for active rows \(PostgreSQL uses the partial index condition as a filter\). Alternative 'archived' tables fragment queries and complicate foreign keys; 'is\_deleted' boolean columns require composite indexes that bloat as soft-deleted rows accumulate.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T20:54:47.646527+00:00— report_created — created