Review: Stripe ↔ DB data reconciliation: parent names, tournament status, orphan charges (v2)
Verdict: APPROVED
Re-review after refinement. Previous review (
review-1670-2026-06-30) returned NEEDS_REFINEMENT with two findings. Both addressed.Previous Findings Resolution
- [x]
[LABEL]story:WS-S12 → story:WS-S9 — FIXED. Board item labels updated. Issue body Related section now referencesstory:WS-S9. Story aligns directly with ticket purpose: "As an admin, I want to track payment status per player so that I know who owes what." - [x]
[SCOPE]arch-rails note missing — Acknowledged as platform-wide gap. Thearch:railslabel is used across multiple board items but noarch-railsnote exists in pal-e-docs. Not blocking for this individual ticket; tracked as cross-cutting documentation debt.
Template Completeness
- [x] Type — Feature
- [x] Lineage — Standalone, discovered during manual audit
- [x] Repo — ldraney/westside-basketball
- [x] User Story — proper As/I want/So that format
- [x] Context — detailed, 5 categories of data inconsistency documented with tables
- [x] File Targets — 2 modify/create, 2 do-not-touch boundaries
- [x] Feature Flag — none (appropriate for rake task)
- [x] Acceptance Criteria — 5 items, all verifiable
- [x] Test Expectations — present with run command
- [x] Constraints — 5 constraints including idempotency and secret handling
- [x] Checklist — present
- [x] Related — present, references story:WS-S9
- [x] Validation Queries — bonus section with concrete reproduction commands
Traceability
- [x] story:WS-S9 label — "As an admin, I want to track payment status per player so that I know who owes what"
- [x] story note verified — WS-S9 found in project-westside-basketball user-stories section under Admin (Marcus)
- [x] arch:rails label — present on board item
- [~] arch note MISSING —
search_notes("arch-rails")returned empty. Platform-wide gap, not blocking. [INFO] Create architecture note arch-rails when addressing cross-cutting documentation debt. - [x] Forgejo issue — #131, open, valid
File Targets
- [x]
lib/tasks/stripe_reconciliation.rake— NEW file. Directorylib/tasks/exists with 2 existing rake files (seed_tournament_attendance.rake,tournament_email.rake). Correct location for new rake task. - [x]
app/models/player_tournament.rb— EXISTS (337 bytes). Model definesPAYMENT_STATUSES = %w[pending paid_stripe paid_cash paid_venmo waived]. Thepaid_stripestatus is a valid enum value. Schema hasamount_cents(integer, nullable) andpayment_status(string, default "pending"). - [x] Do-not-touch boundaries verified —
app/views/admin/**andapp/controllers/**correctly excluded. - [x]
app/services/stripe_client.rb— EXISTS (7.8k). Provides Stripe API access patterns the rake task can reuse.
Repo Placement
OK — issue filed on ldraney/westside-basketball, all code changes are in the same repo. Single-repo ticket.
Dependencies
- No blocking in_progress issues. In-progress items are phases (15, 14, 11) — none conflict.
- Phase 14 (Billing Tiers & Contracts) is the parent phase and is in_progress — correct context.
- Board item #1660 (missing env vars for Stripe) is in backlog. Not a hard blocker — existing Stripe integration (
webhooks_controller.rb,stripe_client.rb) is working, confirming the key is available. - Upstream
seed_tournament_attendance.rake(PR #125) already merged — creates the PlayerTournament records this task reconciles. - Todo items are iOS/app-store related, unrelated to this ticket.
Acceptance Criteria
- 5 criteria, all testable by an agent.
- AC #1 (rake task runs audit): Clear — run
bin/rails stripe:reconcileand verify output. - AC #2 (markdown report): Clear — output covers payment gaps, orphan charges, data quirks.
- AC #3 (idempotent): Clear — re-run produces same result without duplication.
- AC #4 (orphan charge email matching): Clear — orphans with known parent emails are flagged.
- AC #5 (exclude test charges): Clear — $1 test charges from Lucas filtered out.
- Validation queries section provides concrete reproduction commands.
Blast Radius
- Low blast radius. Creates 1 new rake task file, modifies no existing files structurally.
- Data writes confined to
player_tournaments.payment_statuscolumn updates (pending → paid_stripe). - No schema migrations, no controller changes, no view changes.
- Existing
StripeClientservice provides reusable Stripe API patterns. - Admin dashboard display changes explicitly out of scope (separate ticket).
Decomposition Assessment
- 2 file targets in 1 repo — under threshold.
- 5 acceptance criteria — at threshold, not over.
- Estimated agent work: <5 minutes. Single rake task creation, no schema changes, clear patterns from existing rake tasks and StripeClient.
- No decomposition needed.
Recommendation
No action needed. Both previous findings resolved. Ticket is ready for implementation.
[INFO] The
arch-rails note gap is tracked as platform-wide documentation debt and does not block this ticket.