BUG-HUNT: [foreign-key] Missing ondelete actions in initial schema migration causes referential integrity issues #7283

Open
opened 2026-04-10 14:59:36 +00:00 by HAL9000 · 4 comments
Owner

Metadata

  • Branch: bugfix/m2-foreign-key-missing-ondelete-initial-schema
  • Commit Message: fix(alembic): add explicit ondelete actions to all foreign key constraints in initial schema migration
  • Milestone: v3.2.0
  • Parent Epic: #1020

Background and Context

The initial schema migration (alembic/versions/001_initial_schema.py) creates foreign key constraints without specifying ondelete actions. This violates the migration safety requirements from the project specification, which mandates that all foreign key constraints include proper referential integrity actions. The absence of explicit ondelete behaviour means the database falls back to engine-specific defaults, which can cause constraint violations or silent data integrity issues during normal operations involving parent-record deletions.

Current Behavior

Foreign key constraints in the upgrade() function are created without ondelete specifications at lines 43–46, 65–68, and 87–90:

sa.ForeignKeyConstraint(
    ["project_id"],
    ["projects.id"],
),  # Missing ondelete action

sa.ForeignKeyConstraint(
    ["plan_id"],
    ["plans.id"],
),  # Missing ondelete action

This defaults to database-specific behaviour (typically RESTRICT or NO ACTION) and can cause constraint violations during normal operations when parent records are deleted.

Expected Behavior

According to the specification, all foreign key constraints must include explicit ondelete actions to handle referential integrity deterministically (e.g., CASCADE, SET NULL, RESTRICT). Example:

sa.ForeignKeyConstraint(
    ["project_id"],
    ["projects.id"],
    ondelete="CASCADE",
),

Acceptance Criteria

  • All foreign key constraints in alembic/versions/001_initial_schema.py include explicit ondelete actions
  • The chosen ondelete action for each FK is appropriate to the relationship semantics (e.g., CASCADE for child records that should be removed with the parent)
  • A new Alembic migration is not required — the fix is applied directly to the initial schema migration file (it has not been applied to any production database)
  • All existing tests pass after the fix
  • A TDD issue (Type/Testing) is created and merged before this fix is implemented, per the mandatory Bug Fix Workflow

Supporting Information

  • File: alembic/versions/001_initial_schema.py
  • Function: upgrade()
  • Lines: 43–46, 65–68, 87–90
  • Impact: Data integrity violations, potential cascading deletion failures, database constraint violations during normal operations
  • Likelihood: High — any deletion operation on a parent table (projects, plans) will trigger constraint violations or undefined behaviour
  • Related issues: #2418 (risky migration patterns), #6655 (downgrade symmetry), #6656 (docstring lineage)

TDD Note: After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it. This bug issue depends on the TDD issue (TDD issue must be merged first).

Subtasks

  • Audit all sa.ForeignKeyConstraint calls in alembic/versions/001_initial_schema.py and identify missing ondelete actions
  • Determine the correct ondelete action for each FK based on relationship semantics (plans.project_id, contexts.plan_id, changes.plan_id)
  • Add explicit ondelete actions to all identified FK constraints
  • Verify the migration runs cleanly on a fresh database (alembic upgrade head)
  • Verify the migration downgrades cleanly (alembic downgrade base)
  • Remove @tdd_expected_fail tag from the TDD test scenario (leaving @tdd_issue and @tdd_issue_<N>)
  • Confirm all nox stages pass

Definition of Done

  • All sa.ForeignKeyConstraint calls in 001_initial_schema.py include explicit ondelete actions
  • ondelete values are semantically correct for each relationship
  • alembic upgrade head and alembic downgrade base succeed on a clean database
  • TDD test scenario (tagged @tdd_issue, @tdd_issue_<N>) passes without @tdd_expected_fail
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: Bug Hunter | Agent: new-issue-creator

## Metadata - **Branch**: `bugfix/m2-foreign-key-missing-ondelete-initial-schema` - **Commit Message**: `fix(alembic): add explicit ondelete actions to all foreign key constraints in initial schema migration` - **Milestone**: v3.2.0 - **Parent Epic**: #1020 ## Background and Context The initial schema migration (`alembic/versions/001_initial_schema.py`) creates foreign key constraints without specifying `ondelete` actions. This violates the migration safety requirements from the project specification, which mandates that all foreign key constraints include proper referential integrity actions. The absence of explicit `ondelete` behaviour means the database falls back to engine-specific defaults, which can cause constraint violations or silent data integrity issues during normal operations involving parent-record deletions. ## Current Behavior Foreign key constraints in the `upgrade()` function are created without `ondelete` specifications at lines 43–46, 65–68, and 87–90: ```python sa.ForeignKeyConstraint( ["project_id"], ["projects.id"], ), # Missing ondelete action sa.ForeignKeyConstraint( ["plan_id"], ["plans.id"], ), # Missing ondelete action ``` This defaults to database-specific behaviour (typically `RESTRICT` or `NO ACTION`) and can cause constraint violations during normal operations when parent records are deleted. ## Expected Behavior According to the specification, all foreign key constraints must include explicit `ondelete` actions to handle referential integrity deterministically (e.g., `CASCADE`, `SET NULL`, `RESTRICT`). Example: ```python sa.ForeignKeyConstraint( ["project_id"], ["projects.id"], ondelete="CASCADE", ), ``` ## Acceptance Criteria - All foreign key constraints in `alembic/versions/001_initial_schema.py` include explicit `ondelete` actions - The chosen `ondelete` action for each FK is appropriate to the relationship semantics (e.g., `CASCADE` for child records that should be removed with the parent) - A new Alembic migration is **not** required — the fix is applied directly to the initial schema migration file (it has not been applied to any production database) - All existing tests pass after the fix - A TDD issue (`Type/Testing`) is created and merged before this fix is implemented, per the mandatory Bug Fix Workflow ## Supporting Information - **File**: `alembic/versions/001_initial_schema.py` - **Function**: `upgrade()` - **Lines**: 43–46, 65–68, 87–90 - **Impact**: Data integrity violations, potential cascading deletion failures, database constraint violations during normal operations - **Likelihood**: High — any deletion operation on a parent table (`projects`, `plans`) will trigger constraint violations or undefined behaviour - **Related issues**: #2418 (risky migration patterns), #6655 (downgrade symmetry), #6656 (docstring lineage) > **TDD Note:** After this bug issue is verified, a corresponding `Type/Testing` issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. This bug issue **depends on** the TDD issue (TDD issue must be merged first). ## Subtasks - [ ] Audit all `sa.ForeignKeyConstraint` calls in `alembic/versions/001_initial_schema.py` and identify missing `ondelete` actions - [ ] Determine the correct `ondelete` action for each FK based on relationship semantics (`plans.project_id`, `contexts.plan_id`, `changes.plan_id`) - [ ] Add explicit `ondelete` actions to all identified FK constraints - [ ] Verify the migration runs cleanly on a fresh database (`alembic upgrade head`) - [ ] Verify the migration downgrades cleanly (`alembic downgrade base`) - [ ] Remove `@tdd_expected_fail` tag from the TDD test scenario (leaving `@tdd_issue` and `@tdd_issue_<N>`) - [ ] Confirm all `nox` stages pass ## Definition of Done - [ ] All `sa.ForeignKeyConstraint` calls in `001_initial_schema.py` include explicit `ondelete` actions - [ ] `ondelete` values are semantically correct for each relationship - [ ] `alembic upgrade head` and `alembic downgrade base` succeed on a clean database - [ ] TDD test scenario (tagged `@tdd_issue`, `@tdd_issue_<N>`) passes without `@tdd_expected_fail` - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: Bug Hunter | Agent: new-issue-creator
HAL9000 added this to the v3.2.0 milestone 2026-04-10 14:59:42 +00:00
Author
Owner

⚠️ Label Application Required

This issue was created by automation. The label management API endpoint is currently restricted by policy rules in this environment. The following labels must be applied manually by a maintainer:

Label Reason
State/Unverified Initial state for all new issues
Type/Bug This is a bug report
Priority/Critical Per CONTRIBUTING.md Bug Fix Workflow: "Bug issues and TDD counterparts are always Priority/Critical"

Do NOT apply MoSCoW/ labels — those are project owner exclusive.

Compliance Status

  • Issue body follows CONTRIBUTING.md format (Metadata, Subtasks, Definition of Done)
  • Milestone assigned: v3.2.0
  • Parent Epic dependency created: this issue blocks #1020
  • ⚠️ Labels pending manual application (see above)

Automated by CleverAgents Bot
Supervisor: Bug Hunter | Agent: new-issue-creator

## ⚠️ Label Application Required This issue was created by automation. The label management API endpoint is currently restricted by policy rules in this environment. The following labels **must** be applied manually by a maintainer: | Label | Reason | |---|---| | `State/Unverified` | Initial state for all new issues | | `Type/Bug` | This is a bug report | | `Priority/Critical` | Per CONTRIBUTING.md Bug Fix Workflow: *"Bug issues and TDD counterparts are always Priority/Critical"* | **Do NOT apply `MoSCoW/` labels** — those are project owner exclusive. ### Compliance Status - ✅ Issue body follows CONTRIBUTING.md format (Metadata, Subtasks, Definition of Done) - ✅ Milestone assigned: **v3.2.0** - ✅ Parent Epic dependency created: this issue **blocks** #1020 - ⚠️ Labels pending manual application (see above) --- **Automated by CleverAgents Bot** Supervisor: Bug Hunter | Agent: new-issue-creator
Author
Owner

Verified — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Data integrity bug: missing ondelete actions in schema migration. MoSCoW: Must-have. Priority: High. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
Reference
cleveragents/cleveragents-core#7283
No description provided.