Skip to content

fix(billing): pending_checkouts ON DELETE CASCADE (mig 069) — unblock team reap#272

Merged
mastermanas805 merged 1 commit into
masterfrom
fix/pending-checkouts-cascade-069
Jun 7, 2026
Merged

fix(billing): pending_checkouts ON DELETE CASCADE (mig 069) — unblock team reap#272
mastermanas805 merged 1 commit into
masterfrom
fix/pending-checkouts-cascade-069

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Found by the live test-card payment run

Driving the real free→Pro test-card flow surfaced a reap failure: the e2e-account reap 503'd (db_failed) and the cohort team leaked.

pq: update or delete on table "teams" violates foreign key constraint
"pending_checkouts_team_id_fkey" on table "pending_checkouts"

Root cause

053_pending_checkouts created team_id UUID NOT NULL REFERENCES teams(id) with no ON DELETE CASCADE — the only team-child table missing it (deployments, stacks, api_keys, audit_log, vault, custom_domains, pending_deletions, pending_propagations, … all cascade). DeleteTeamHard (e2e reap) and the worker team_deletion_executor both DELETE FROM teams and rely on children cascading. Arming test-cohort checkout exposed it: a cohort Pro upgrade creates a pending_checkouts row → reap fails → rule-24 "cohort data is always reaped" broken.

Fix

Migration 069 aligns the FK with every other team-child table (ON DELETE CASCADE), idempotent (DROP IF EXISTS + re-ADD). Already applied live (verified confdeltype=c + reap now 200 for a team with a pending_checkouts row); this migration codifies it so it survives a fresh DB.

Test

TestDeleteTeamHard_CascadesPendingCheckouts seeds a pending_checkouts row and asserts DeleteTeamHard cascades it instead of erroring on the FK.

🤖 Generated with Claude Code

… team reap

053_pending_checkouts created the team_id FK without ON DELETE CASCADE — the ONLY
team-child table missing it. DeleteTeamHard (the e2e-account reap) and the worker
team_deletion_executor delete a team with a bare DELETE FROM teams and rely on
children cascading, so a team that ever started a checkout (→ a pending_checkouts
row) failed:
  pq: ... violates foreign key constraint "pending_checkouts_team_id_fkey"

This surfaced live the moment test-cohort checkout was armed: a cohort Pro upgrade
creates a pending_checkouts row, so the reap 503'd (db_failed) and the cohort team
LEAKED — breaking the rule-24 'cohort data is always reaped' guarantee. Found by
the real test-card payment run.

Migration 069 aligns the FK with every other team-child table (ON DELETE CASCADE),
idempotent (DROP IF EXISTS + re-ADD). Already applied live; this codifies it.

Test: TestDeleteTeamHard_CascadesPendingCheckouts seeds a pending_checkouts row
and asserts DeleteTeamHard cascades it instead of erroring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 merged commit e04782e into master Jun 7, 2026
18 checks passed
@mastermanas805 mastermanas805 deleted the fix/pending-checkouts-cascade-069 branch June 7, 2026 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants