Review: Remove opt-out from jersey ordering options (#263)
Verdict: APPROVED
Issue
Board item #718 on
forgejo_admin/basketball-api#263 -- "Remove opt-out from jersey ordering options"Board item #718 on
board-westside-basketball, column: backlog -> todoTemplate Completeness
| Field | Present | Notes |
|---|---|---|
| Type | Yes | Bug |
| Lineage | Yes | Standalone, discovered during jersey ordering validation 2026-03-30 |
| Repo | Yes | <code>forgejo_admin/basketball-api</code> |
| What Broke | Yes | Specific: opt-out still offered, player Zion Odejinmi (id=113) already selected it |
| Repro Steps | Yes | 3 concrete steps with observable outcome |
| Expected Behavior | Yes | Only reversible ($90) and jersey+warmup ($130) should appear |
| Environment | Yes | prod namespace, commit <code>4cd0e1b5</code>, affected player identified |
| Acceptance Criteria | Yes | 4 checkboxes, all concrete and verifiable |
| Related | Yes | <code>project-westside-basketball</code>, <code>story:WS-S18</code> |
All 9 template fields present and complete. No gaps.
File Target Verification
src/basketball_api/routes/jersey.py--JERSEY_OPTIONSlist at lines 25-41 contains opt_out entry (lines 37-40). GET/jersey/optionsat line 137 returns all options unfiltered. POST/jersey/checkoutat lines 202, 269-276 has opt_out handling path. All confirmed in codebase.src/basketball_api/routes/checkout.py-- POST/checkout/create-sessionat lines 168-192 handles opt_out viaProductType.opt_outcheck. Confirmed.src/basketball_api/models.py--JerseyOption.opt_outat line 83,ProductType.opt_outat line 120. Enum values exist. Note: these enum values should NOT be removed from the model (data preservation for existing records), only from the API surface.tests/test_jersey.py-- 6 opt_out test cases that will need updatingtests/test_checkout.py-- 3 opt_out test cases that will need updating
All file targets verified. Agent will find exactly what it needs.
Traceability
- Board item #718 labels:
type:bug,arch:basketball-api,story:WS-S18-- correct - Issue body references:
story:WS-S18-- matches board item - Story WS-S18 is defined in
project-westside-basketballunder Parent stories
Traceability triangle complete.
Dependency Check
- #260 (QA nits from jersey PRs) -- related but not blocking, different scope
- #262 (extract _resolve_player helper) -- refactor, independent
- #264 (Stripe webhook sync) -- independent bug
- No blockers identified. This bug can be fixed independently.
Decomposition Assessment
3 discrete changes required:
- Remove opt_out from
JERSEY_OPTIONSlist injersey.py+ add validation to reject opt_out in POST/jersey/checkout - Add rejection in
checkout.py/create-sessionfor opt_out ProductType - Update tests in
test_jersey.pyandtest_checkout.py(convert opt_out tests to rejection tests)
Exactly 3 changes. Well within single-agent scope. Estimated ~5 min.
Important Implementation Note
The enum values
JerseyOption.opt_out and ProductType.opt_out must NOT be removed from models.py. Existing database records (e.g., Zion id=113) reference these values. The acceptance criteria explicitly state "Existing opt-out records are not deleted (data preservation)." The fix is API-surface only: remove from the options list, reject in validation.Recommendation
APPROVED for todo. Ready for agent dispatch. Clean scope, verified file targets, no blockers.