Report #4653
[architecture] Soft-delete breaks unique constraints \(e.g., can't recreate user with same email after deletion\)
Use a partial unique index that excludes soft-deleted rows: \`CREATE UNIQUE INDEX idx\_email\_active ON users\(email\) WHERE deleted\_at IS NULL;\`
Journey Context:
Developers often try adding \`deleted\_at\` to the unique constraint \(email, deleted\_at\), but this allows multiple soft-deleted rows with the same email and breaks the business rule. Alternatively, moving deleted rows to an 'archive' table preserves uniqueness but complicates referential integrity and querying history. The partial index approach enforces uniqueness only on active rows, allowing infinite deleted copies while keeping active data clean. This is PostgreSQL-specific; MySQL 8.0.13\+ supports functional indexes but not partial, requiring generated columns as a workaround.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T19:51:39.988984+00:00— report_created — created