fix: enforce Literal validation on sort parameter in GET /api/v3/players (#66) #68
No reviewers
Labels
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-database#68
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "ai/major-domo-database-66"
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?
Closes #66
Summary
sort: Optional[str]tosort: Optional[Literal["cost-asc", "cost-desc", "name-asc", "name-desc"]]in theget_playersroute signature inapp/routers_v3/players.pyLiteralto thetypingimportsWhat was broken
The
sortparameter inGET /api/v3/playersaccepted any string value. Invalid values (e.g.sort=INVALID) were silently ignored and fell through to the defaultORDER BY idin_apply_player_sort. FastAPI had no way to reject them with a 422.What was fixed
FastAPI now validates the
sortparameter at binding time. Requests with an unrecognisedsortvalue receive a422 Unprocessable Entitybefore the handler runs.Files changed
app/routers_v3/players.py— 2-line change (import + parameter type)Notes
cost-asc,cost-desc,name-asc,name-desc) were derived from the_apply_player_sortimplementation inplayer_service.pydiscord-app-v2already usesort=cost-asc/sort=cost-desc, so no callers are broken by this changeReview: APPROVED ✅
Correct, minimal fix. Consistent with PR #36 which applied the same
Literalpattern toviews.py.Verification
Literal values match
_apply_player_sortexhaustively (player_service.py:294–301,316–325):cost-asc→ORDER BY wara ASCcost-desc→ORDER BY wara DESCname-asc→ORDER BY name ASCname-desc→ORDER BY name DESCORDER BY id(default fallback)With
Optional[Literal[...]], FastAPI rejects anything outside those 4 values with422 Unprocessable Entitybefore the handler runs.None(omitted param) remains valid — no regression for existing callers.Checks
Literaladded totypingimport in correct position (alphabetical)Optional[Literal[...]]preservesNoneas valid — no breaking changecost-asc/cost-desc— no callers brokenNo issues found. Ready to merge.
AI Code Review
Files Reviewed
app/routers_v3/players.py(modified)Findings
Correctness
Literaladded to thetypingimport correctly (alphabetically ordered with existing imports).cost-asc,cost-desc,name-asc,name-desc) exactly match the exhaustiveelifbranches in_apply_player_sort(player_service.py:294–301). No valid sort value is excluded.Optional[Literal[...]]correctly preserves theNonedefault — callers omittingsortstill get the defaultORDER BY idbehaviour.422 Unprocessable Entityat binding time, before the handler runs.Security
Style & Conventions
views.pysort_byLiteral fix). Consistent approach across the codebase.Suggestions
Verdict: APPROVED
2-line change is correct and complete. Literal values match the implementation,
Noneis preserved, and no callers are broken. Ready to merge.Automated review by Claude PR Reviewer
Checkout
From your project repository, check out a new branch and test the changes.