Review: Alice Uwamahoro dedupe

review-925-2026-04-10 Review

review ready

Verdict: READY

Board item #925 — basketball-api#420 — Alice Uwamahoro dedupe (players 201+202, parents 175+176).

Template Completeness

  • [x] Type: Bug
  • [x] Lineage (discovered 2026-04-10, linked to #418 root cause)
  • [x] Repo
  • [x] What Broke (concrete row IDs, timestamps, email variants)
  • [x] Repro Steps
  • [x] Expected Behavior (keep 202, delete 201+175)
  • [x] Environment (tables identified)
  • [x] Acceptance Criteria (7 testable criteria)
  • [x] Related

Traceability

  • [x] story:WS-S7 label — "branded email announcements" — loose thematic fit (data cleanup downstream of the email normalization bug #418). Foundational data hygiene, acceptable for unblocking Marcus batch.
  • [x] arch:basketball-api label — present
  • [ ] arch-basketball-api note — NOT FOUND in pal-e-docs. Pre-existing gap, not blocking.
  • [x] Forgejo issue #420 — open, well-formed
  • [x] scope:discovered — correctly applied

File Targets

  • [x] alembic/versions/ — verified exists; latest migration is 030. New file would be 031_dedupe_alice_uwamahoro.py.
  • [x] Tables players and parents — verified in src/basketball_api/models.py.

Repo Placement

OK — basketball-api owns the schema and data.

Dependencies

Root cause #418 (email normalization) is correctly scoped out — this ticket is one-time data dedupe. Unblocks Alice's 16U Elite Queens $100/mo contract in the Marcus batch.

Acceptance Criteria

All 7 criteria testable via SQL + migration re-run. Idempotent migration requirement called out. Audit trail via Alembic aligns with feedback_never_alter_prod_directly.

Blast Radius

Low. Both rows have contract_status = 'none' so no dependent orders, player_teams, or registrations. Dedupe is safe.

Decomposition Assessment

1 file, 1 repo, 7 AC, ~5 min agent work. No decomposition needed. Fits 5-minute rule.

Recommendation

No action needed. READY for todo → next_up. Dispatch a dev agent to write migration 031 that deletes player 201 and parent 175 with guards for idempotency.