feat: add GET /jersey/player-info endpoint #148
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api!148
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "67-jersey-player-info-endpoint"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds
GET /jersey/player-info?token=...endpoint that returns the player's name and division given a parent registration token. Required by the westside-app jersey number picker to fetch taken numbers per division.Changes
src/basketball_api/routes/jersey.py-- addedJerseyPlayerInfoResponseschema and/player-infoendpoint that looks up parent by registration token and returns first player's name and divisiontests/test_jersey.py-- 4 new tests covering valid token, invalid token, no players, and player without divisionTest Plan
pytest tests/test_jersey.py::TestJerseyPlayerInfo -v-- all 4 passpytest tests/test_jersey.py-- full suite, all 46 passruff format --checkandruff check-- cleanReview Checklist
Related
plan-wkq-- Phase 11 (Girls Tryout)PR #148 Review
DOMAIN REVIEW
Tech stack: Python / FastAPI / SQLAlchemy / Pydantic -- applying Python/FastAPI domain checklist.
Endpoint implementation (
src/basketball_api/routes/jersey.pylines 100-125):JerseyPlayerInfoResponseis clean, with correctstr | Noneunion fordivision. PEP 484 compliant.joinedload(Parent.players)eager-loads the relationship in a single query -- correct SQLAlchemy pattern, avoids N+1./checkoutendpoint error handling in the same file.player.division.value if player.division else Nonecorrectly handles the nullable enum. Safe.Query(..., alias="token")-- thealias="token"is redundant since the parameter name is alreadytoken, but this matches the convention used in the existing/checkoutendpoint (line 169). Consistent, not a bug./checkout,/options,/sizes, and/taken-numbersin the same file. The registration token serves as a bearer secret.Input validation:
tokenparameter is required (...default) and typed asstr. FastAPI will reject requests without it (422). No SQL injection risk -- SQLAlchemy parameterizes the query.Test coverage (
tests/test_jersey.pylines 151-200):parent_with_playerfixture (line 56, same file) and create ad-hoc test data for edge cases.Ruff compliance: PR body states
ruff format --checkandruff checkare clean.BLOCKERS
None. All blocker criteria pass:
jersey.py(lines 109-113 and 215-219),checkout.py(line 112), andregister.py(line 576). However, this is a pre-existing pattern -- the new endpoint follows the exact same convention already established in this file's/checkoutendpoint. Extracting a shared helper would be good hygiene but is out of scope for this PR. Not a blocker.NITS
Pre-existing DRY opportunity (not introduced by this PR): The "lookup parent by token + eager-load players + validate exists" block (lines 109-119) is duplicated verbatim from the
/checkoutendpoint (lines 215-225). A shared dependency likeget_parent_or_404(token, db)would reduce this to one line per endpoint. Worth a follow-up issue.Multi-player ambiguity:
parent.players[0]silently picks the first player. If a parent has multiple players, this may not be the player the user expects. The existing/checkoutendpoint has the same behavior (line 228), so this is consistent -- but worth noting as a known limitation for future work (e.g., aplayer_idquery param).SOP COMPLIANCE
67-jersey-player-info-endpointreferences westside-app#67 (the dependent frontend issue). Basketball-api issue #147 is referenced in the PR body via "Closes #147". Acceptable cross-repo naming.plan-wkqPhase 11 referenced.Note on issue numbering: The user dispatch referenced parent issue #143, but the PR body says "Closes #147". Issue #147 ("feat: add GET /jersey/player-info endpoint for token-based division lookup") matches the PR scope exactly. This may be a dispatch routing discrepancy; the PR itself is correctly linked to #147.
PROCESS OBSERVATIONS
VERDICT: APPROVED