Skip to main content
May 25, 20261.11.1v1.11.1RSS

v1.11.1 — [Database] Add 3 foreign-key delete-rule mismatches

Release Notes

<!-- db-audit:kind=fk_on_delete_mismatch -->

The database audit found 3 foreign-key delete-rule mismatches that need to be reconciled between the code and the database.

  • Foreign key ai_conversations.permission_profile_idpermission_profiles declares ON DELETE no action in the code, but the database is set to set null.

Fix: apply an ALTER TABLE ... DROP CONSTRAINT / ADD CONSTRAINT migration that brings the live database to ON DELETE no action so the code's declared intent is enforced at the DB layer.

Sanity-check first: before shipping, verify the code's no action is actually right for this parent→child relationship. CASCADE on a value-carrying child silently loses data on parent delete. The decision tree: • child is ephemeral state (logs, acks, in-flight handshakes, derived counters) → CASCADE is safe • child is value-carrying (refs the parent but should outlive it) → SET NULL is safer than CASCADE • child carries audit/compliance value (SOC2, GDPR record-keeping) → keep RESTRICT and SET NULL the FK on deletion paths If the code's declared no action is wrong, fix the code first, then ship the aligning migration.

  • Foreign key batch_jobs.org_idorganizations declares ON DELETE no action in the code, but the database is set to cascade.

Fix: apply an ALTER TABLE ... DROP CONSTRAINT / ADD CONSTRAINT migration that brings the live database to ON DELETE no action so the code's declared intent is enforced at the DB layer.

Sanity-check first: before shipping, verify the code's no action is actually right for this parent→child relationship. CASCADE on a value-carrying child silently loses data on parent delete. The decision tree: • child is ephemeral state (logs, acks, in-flight handshakes, derived counters) → CASCADE is safe • child is value-carrying (refs the parent but should outlive it) → SET NULL is safer than CASCADE • child carries audit/compliance value (SOC2, GDPR record-keeping) → keep RESTRICT and SET NULL the FK on deletion paths If the code's declared no action is wrong, fix the code first, then ship the aligning migration.

  • Foreign key pending_payments.org_idorganizations declares ON DELETE no action in the code, but the database is set to cascade.

Fix: apply an ALTER TABLE ... DROP CONSTRAINT / ADD CONSTRAINT migration that brings the live database to ON DELETE no action so the code's declared intent is enforced at the DB layer.

Sanity-check first: before shipping, verify the code's no action is actually right for this parent→child relationship. CASCADE on a value-carrying child silently loses data on parent delete. The decision tree: • child is ephemeral state (logs, acks, in-flight handshakes, derived counters) → CASCADE is safe • child is value-carrying (refs the parent but should outlive it) → SET NULL is safer than CASCADE • child carries audit/compliance value (SOC2, GDPR record-keeping) → keep RESTRICT and SET NULL the FK on deletion paths If the code's declared no action is wrong, fix the code first, then ship the aligning migration.