feat: add jersey fields to AdminPlayerItem response #250
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
ldraney/basketball-api!250
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "248-admin-jersey-fields"
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
Expose
jersey_option,jersey_size,jersey_number, andjersey_order_statusin theGET /admin/playersendpoint so the admin CRM view can display jersey selection data inline without a separate API call.Changes
src/basketball_api/routes/admin.py— Added 4 fields toAdminPlayerItemPydantic model and populated them from the Player ORM model in the list comprehension. Enum values are serialized as strings; nullable enums returnnull.tests/test_admin_spa.py— Added jersey enum imports, set jersey data on theplayer1fixture, addedtest_jersey_fields_populatedcovering both populated and default/null cases, updatedtest_response_fieldsandtest_includes_player_detailsto assert the new fields.Test Plan
pytest tests/test_admin_spa.py -v— 9/9 passruff formatandruff checkcleanReview Checklist
JerseyOption,JerseySize,JerseyOrderStatus) already exist on the Player model — no migration neededjersey_numberis a plain string field on Player — no enum conversion needednull,jersey_order_statusdefaults to"none"via server_defaultis_publicfield from prior PR)Related Notes
Related
QA Review -- PR #250
Scope Check
AdminPlayerItem:jersey_option,jersey_size,jersey_number,jersey_order_status. All 4 are present in the diff. No scope creep, no missing fields.Model Review
jersey_option: str | None-- correct.JerseyOptionis nullable on the Player model, serialized as.valuestring.jersey_size: str | None-- correct.JerseySizeis nullable on the Player model, serialized as.valuestring.jersey_number: str | None-- correct. PlainString(2)column, passed through directly.jersey_order_status: str-- correct. Non-nullable withserver_default="none", serialized as.valuestring.Serialization Review
player.jersey_option.value if player.jersey_option else Nonepattern, consistent with existingdivisionfield handling in the same function.jersey_order_statusalways has a value (server_default), so.valueis safe without a null guard.jersey_numberis a plain string, no enum conversion needed.Test Review
test_jersey_fields_populated: Covers both the populated case (Jordan with all 4 fields set) and the null/default case (Alex withNone/"none"). Good coverage.test_includes_player_details: Extended with 4 new assertions for Jordan's jersey data.test_response_fields: Expected fields list updated with all 4 new fields.populated_db:player1now has jersey data (reversible,YL,"23",paid),player2has no jersey data (tests the default path).SOP Compliance
248-admin-jersey-fields-- correct format.Findings
No issues found.
VERDICT: APPROVED
PR #250 Review
DOMAIN REVIEW
Tech stack: Python / FastAPI / SQLAlchemy / Pydantic
Model alignment verified:
jersey_optionon Player isMapped[JerseyOption | None](nullable enum) -- Pydantic fieldstr | Noneis correct. Serialization uses.value if player.jersey_option else None, matching the existingdivisionpattern on line 352.jersey_sizeon Player isMapped[JerseySize | None](nullable enum) -- same pattern, correct.jersey_numberon Player isMapped[str | None](plain string) -- passed directly without.value, correct.jersey_order_statuson Player isMapped[JerseyOrderStatus](non-nullable,server_default="none") -- Pydantic fieldstr(non-nullable) is correct. Uses.valuedirectly (no null guard needed), matching thesubscription_status/contract_statuspattern.Enum values confirmed:
JerseyOption(reversible/jersey_warmup/opt_out),JerseySize(YS/YM/YL/YXL/AS/AM/AL/AXL),JerseyOrderStatus(none/pending/paid/shipped) -- all serialize as strings via.value.PEP compliance: Type hints use
str | None(PEP 604), consistent with the rest of the model. No issues.Ruff: PR body states
ruff formatandruff checkclean.BLOCKERS
None.
NITS
None. The change is minimal, follows existing patterns exactly, and the test coverage is thorough.
SOP COMPLIANCE
248-admin-jersey-fieldstest_jersey_fields_populatedcovers both populated and null/default cases;test_includes_player_detailsandtest_response_fieldsupdated for new fieldsadmin.py,test_admin_spa.py), +50/-0 linesAdminPlayerItem, no extrasPROCESS OBSERVATIONS
Clean, scoped change. The 50-line additive footprint matches the ticket estimate exactly. Test coverage includes both the happy path (player with jersey data) and the default path (player without jersey data returning null/none), which is the right pattern for nullable fields. No deployment risk -- additive-only response model change, fully backward compatible for any existing consumers.
VERDICT: APPROVED