fix(#101): complete case-deletion dependent-row cleanup under FK enforcement #104
No reviewers
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!104
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/101-fk-cascade"
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?
Fixes #101.
Complete dependent-row cleanup for DELETE /api/cases/{id} so the endpoint succeeds under FK enforcement (PRAGMA foreign_keys=ON in the test engine, always-on in prod Postgres). Built on the FK dependency audit (kanban t_6c11c9fc); opened from originating kanban card t_db33ba19.
Repro (from issue #101)
d0723c9(FK enforcement), e.g. origin/mainb81dc67.pytest tests/integration/test_integration_concurrent.py::TestConcurrentDeletion::test_delete_while_reading— FAILS 3/3 solo and in combined run:PendingRollbackErrorwrappingsqlite3.IntegrityError: FOREIGN KEY constraint failedonDELETE FROM "case".d9bbe4d— passes.DELETE /api/cases/{id}returns HTTP 500. Expected 200/204.Root cause
d0723c9enabled FK enforcement (and added CASCADE on the org_email/phone/domain -> organization FKs) but the case-delete path still violated case_membership.case_id -> case.id, which had no ON DELETE CASCADE. POST /api/cases/ inserts a membership row via CaseAccessService.ensure_membership, and the delete router never removed case_membership rows, so under FK enforcement the case delete was blocked (500). Prod Postgres always enforces FKs, so the endpoint was likely broken in prod too — masked before only by the FK-off test engine.Changes
Test evidence
CI note
This PR's own changes introduce zero new CI failures:
ruff check app/reports an identical 331 pre-existing errors on both this branch and origin/main (all in files untouched by this PR), and the PR touches no frontend files. The failing CI jobs (Backend Lint & Format, Frontend Lint, Performance Regression Detection) fail identically on origin/main — they are pre-existing baseline debt tracked separately (lint-cleanup #97 / PR #98, #99), not regressions from this change.Add ON DELETE CASCADE to case_membership.case_id -> case.id (the minimal FK that blocked DELETE /api/cases/{id} onced0723c9enabled FK enforcement), plus Case.memberships/CaseMembership.case relationships and a data-preserving alembic migration (f101c4scd0a1). Expand the case-delete path to remove every dependent row the original path omitted (FK audit t_6c11c9fc, 3b): run-level children (ModuleExecution, InvestigationQueue, InvestigationTask, EntityActionQueue, EvidenceSource via source_run_id), evidence-level children (EvidenceReviewDecision, EntityHighlight, EvidenceSource via evidence_id), and case-level rows (InvestigationSchedule, EnrichmentRun, CaseMembership) before DELETE FROM case. Add focused integration tests (email/phone/domain + the full dependent surface). test_delete_while_reading now passes under PRAGMA foreign_keys=ON; 152 relevant tests pass; no new FK or lint errors introduced.fix(#101): complete case-deletion dependent-row cleanup under FK enforcementto fix(#101): complete case-deletion dependent-row cleanup under FK enforcement [rebased]fix(#101): complete case-deletion dependent-row cleanup under FK enforcement [rebased]to fix(#101): complete case-deletion dependent-row cleanup under FK enforcementAuto-rebase by fixup lane:
53f18ef)69ce3126actions/checkout@v4step (network/runner issue, not a code issue — same failure on origin/main)Ready to merge — no further code action needed on this lane.