Add alembic migration for ondelete=CASCADE on organization child FKs #96
Labels
No labels
agentic-osint
audit
blocked:commit-ready-failed
blocked:gate-fetch
blocked:gate-fetch
blocked:gate-lint
blocked:gate-plan
blocked:gate-research
blocked:needs-decision
blocked:needs-human
blocked:no-changes
blocked:preflight
blocked:verify-failed
bug
chore
deferred
enhancement
feature-request
in-progress
lint-baseline
lint-cleanup
needs-decompose
needs-triage
performance
quickfix
security/medium
triage-approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/osint-hub#96
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
d0723c9added ondelete=CASCADE to OrganizationEmail/Phone/Domain org_id foreign keys in app/models.py, but only the SQLModel metadata changed — no alembic migration was generated, so an existing Postgres database still has the old FK without ON DELETE CASCADE. Deleting an organization in production will raise a foreign-key violation on child rows instead of cascading. Generate and commit a migration (e.g. drop/recreate the three FKs with ondelete=CASCADE).Related fix landed in
9a07880: alembic had TWO heads (d1e2f3a4b5c6 and a2b3c4d5e8f0 both branched from b5f6a7c8d9e0 with no merge), soalembic upgrade headfailed outright with "Multiple head revisions are present" on any fresh database. Added merge migration a25b7f06b9f1 so migrations can actually run. Note: the broader migration story is still inconsistent — alembic migrations assume the base schema exists via SQLModel.metadata.create_all (entrypoint.sh runs create_all first), so migrations are additive patches rather than a complete chain. Generating the ondelete=CASCADE migration for organization_email/phone/domain from this issue remains valid work on top of the merge fix.Migration implemented in PR #103 (#103).
c9e3721d770edrops and recreates the three org_id foreign keys (organization_email_org_id_fkey,organization_phone_org_id_fkey,organization_domain_org_id_fkey) withON DELETE CASCADE. Verified on scratch Postgres 16: upgrade on fresh + pre-seeded DBs applies cleanly,DELETE FROM organizationcascades to child rows,downgrade -1restores NO ACTION FKs. Full psql evidence pasted in the PR body.Closed via watcher recovery: kilo-gsd runner reached Phase 8/9 commit but the synthesized salvage commit on
fix/101-fk-cascadeincluded a stray off-scope migration (3f4a5b6c7d8e_add_investigation_completeness_metrics.py— leftover from a prior run, not part of #96). The runner's--ff-onlymerge of that branch intomainthen failed becauseorigin/mainhad moved (lint-cleanup PRs landed between dispatch and commit), and the Forgejo API close attempt on top of the failed push errored.Watcher recovery applied:
maintoorigin/main(93791d4).7f747efontomain(now8a891e7) — drops the bad synthesized commit.ruff check backend/alembic/versions/b2c3d4e5f6a8_add_ondelete_cascade_org_child_fks.py→ PASSruff format --check ...→ PASSpytest backend/tests/unit/test_organization_crud.py::TestOrganizationRelatedEntities::test_delete_organization_cascade_to_emails→ PASS (1/1)pytest backend/tests/unit/test_organization_crud.py→ PASS (42/42)pytest backend/tests/integration/test_api_entities.py::TestOrganizationAPI::test_delete_organization→ PASS (1/1)git push origin main→ 93791d4..8a891e7 main -> main (clean fast-forward).The landed migration (
b2c3d4e5f6a8_add_ondelete_cascade_org_child_fks.py, 173 lines) mirrors the provenf101c4scd0a1_add_ondelete_cascade_case_membership_fkpattern from #101 with an_fk_has_cascadeguard making it a safe no-op on rerun or fresh schemas. Down_revision =f101c4scd0a1.The existing PRs #103 (
fix/96-org-fk-cascade, migrationc9e3721d770e) and #108 (fix/96-ondelete-cascade-migration, migrationb53942abd63a) are now superseded by the landed commit onmain. Closing them as superseded to avoid drift.