Review: Add dual-auth dependency for jersey and checkout routes

review-basketball-api-255-dual-auth Doc

review ready

Verdict: APPROVED

Issue forgejo_admin/basketball-api#255 is well-scoped, template-complete, and ready for agent dispatch.

Template Completeness

Section Status Notes
Type PASS Feature
Lineage PASS References westside-landing#196 (parent spike) and WS-S18
Repo PASS <code>forgejo_admin/basketball-api</code>
User Story PASS As a logged-in parent / I want dual auth / So that I can order from profile
Context PASS Thorough: explains current token-only auth, references account.py pattern, confirms zero blast radius on register.py/tryouts.py
File Targets PASS 4 targets with line numbers + 2 do-not-touch files with rationale
Acceptance Criteria PASS 5 concrete When/Then criteria covering both auth paths, both endpoints, and the no-change guard
Test Expectations PASS 5 unit/integration tests + run command
Constraints PASS 3 constraints: backwards compat, DI pattern, eager loading
Checklist PASS Standard 3-item checklist
Related PASS Project + parent spike linked

File Target Verification

  • src/basketball_api/auth.py -- EXISTS. Confirmed get_current_user dependency at line 77. Agent will add get_parent_dual_auth following this pattern.
  • src/basketball_api/routes/jersey.py -- EXISTS. Lines 109-122 (jersey_player_info) confirmed: inline Parent.registration_token lookup with joinedload(Parent.players). Lines 227-235 (jersey_checkout) confirmed: identical inline token lookup pattern.
  • src/basketball_api/routes/checkout.py -- EXISTS. Lines 115-122 (create_checkout_session) confirmed: same inline token lookup pattern.
  • tests/ -- EXISTS. test_checkout.py already present. Agent will add new test file for dual_auth.
  • routes/register.py (do-not-touch) -- Verified: uses registration_token at lines 590 and 880 in completely separate code paths. No shared helper. Zero blast radius confirmed.
  • routes/tryouts.py (do-not-touch) -- Verified: uses registration_token at lines 457, 529, 798-799. Separate context (admin export). Zero blast radius confirmed.

Traceability

  • Board item #693 -- exists in backlog on board-westside-basketball
  • Labels -- type:feature,story:WS-S18,arch:basketball-api (all three traceability axes present)
  • Story note WS-S18 -- NOT FOUND in pal-e-docs. The story text is in the issue body ("As a parent, I want to receive a branded email with jersey ordering link..."). Minor gap: story note should be created for traceability, but does not block dispatch.

Dependency Check

  • Sibling WS-S18 board items: #694 (player_id param, #256), #695 (jersey card, westside-landing#197), #696 (session auth pages, westside-landing#198)
  • This ticket (#693/#255) is the foundational one -- the other three depend on the dual-auth dependency existing. No upstream blockers.
  • The account.py pattern it references (line 57, Parent.email.ilike(user.email)) is already merged and stable.

Decomposition Assessment

  • 3 discrete changes: (1) new dependency in auth.py, (2) swap 2 routes in jersey.py, (3) swap 1 route in checkout.py + add tests
  • Fits the 3-change / 5-minute agent rule
  • All changes are in one repo, one domain (auth + routes), tightly coupled
  • Estimated: well within single-agent scope

Recommendations

  • Minor: Create a WS-S18 story note in pal-e-docs for full traceability. Not blocking.
  • After this merges, unblock #694, #695, #696 in sequence.