Report #6846
[architecture] Unique constraint violations when soft-deleting records with partial NULL values
Create partial unique indexes with \`WHERE deleted\_at IS NULL\` in PostgreSQL, or include \`deleted\_at\` in the unique constraint using a sentinel value \(e.g., 'infinity'\) rather than NULL to avoid multiple soft-deleted rows colliding
Journey Context:
Standard unique indexes that include \`deleted\_at\` fail because SQL NULL \!= NULL, allowing multiple soft-deleted rows with the same value. Adding \`deleted\_at\` to a composite unique index without handling NULLs creates a trap where you can never delete the same record twice. Partial indexes solve this cleanly but are PostgreSQL-specific; MySQL requires generated columns or sentinel values. Schema-per-tenant designs often overlook this until production collisions occur.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T01:12:04.759534+00:00— report_created — created