Report #5599
[architecture] Unique constraint violations when reusing identifiers from soft-deleted records
Implement partial unique indexes with a WHERE deleted\_at IS NULL clause to enforce uniqueness only on active rows
Journey Context:
Standard unique constraints on fields like 'email' fail when a soft-deleted user exists \(deleted\_at populated\) and a new user attempts to claim that email. Including deleted\_at in a composite unique constraint fails because SQL NULL \!= NULL, allowing duplicate \(value, NULL\) tuples. The correct approach is a partial index \(PostgreSQL\) or filtered index \(SQL Server\) that only indexes rows WHERE deleted\_at IS NULL. This enforces uniqueness strictly on active records while allowing unlimited historical duplicates in deleted records. Tradeoffs: Syntax is database-specific \(PostgreSQL partial indexes vs MySQL 8.0.13\+ functional indexes vs SQL Server filtered indexes\). Cannot easily support 'unique across active \+ recently deleted' logic without complex partial conditions. Alternative approaches like appending random suffixes to deleted records violate referential integrity and complicate restores.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T21:44:01.729675+00:00— report_created — created