Validation: basketball-api#430 — POST /api/jersey-public-orders endpoint
Validation: basketball-api#430 — POST /api/jersey-public-orders endpoint
Verdict: PASS — 2026-04-11. PR #450 merged via squash. T3 of System B production rollout.
Acceptance criteria
- ✅ New file
src/basketball_api/routes/jersey_public.py(160 lines) with inline Pydantic v2 schemas + POST endpoint - ✅ Auth:
user: User = Depends(get_current_user)frombasketball_api.auth(NOT a fictionalkeycloak_user) - ✅ Inline Pydantic — NO
schemas/directory created - ✅ Pydantic v2 syntax (
Field(..., pattern=...)) - ✅
submitter_keycloak_sub = user.substamped on inserted row - ✅
player_name+emailfrom request body, NOT overridden by JWT (parent-on-behalf-of-child use case preserved, dedicated test verifies) - ✅ CHECK constraint patterns enforced for kq, tier, sizes, preferred numbers (regex
^(0|00|[1-9][0-9]?)$) - ✅
submission_ippopulated from X-Forwarded-For (first entry) or request.client.host, parsed viaipaddress.ip_address() - ✅ Returns 201 with
{id, status, created_at} - ✅
main.pychange is exactly 2 lines (import +include_routerwith/api/jersey-public-ordersprefix) - ✅ CORS allowlist includes
westsidekingsandqueens.tail5b443a.ts.net - ✅ Files NOT touched:
routes/checkout.py,routes/jersey.py,routes/__init__.py,models.py,auth.py,alembic/versions/* - ✅ 24 unit tests pass in 2.75s (unauth/happy/row-check/all validation paths/body-not-overridden/XFF)
- ✅ Tests mock
get_current_uservia FastAPIdependency_overrides— no real Keycloak in CI - ✅ Ruff format + check clean
Production verification still needed
After basketball-api ArgoCD reconciles (image build → Harbor push → kustomize tag bump → ArgoCD sync → pod restart), verify:
POST /api/jersey-public-orderswith valid JWT returns 201 + row injersey_public_ordersPOSTwithout auth returns 401- End-to-end test from
westsidekingsandqueens.tail5b443a.ts.net/jersey-publicform → backend insert
Cosmetic nits captured for plan Epilogue per `feedback_nits_to_epilogue.md`
- Whitespace-only player_name/team edge case
- Optional
EmailStrupgrade (wasstr+ pattern) - Tighten 422 assertion specificity in tests
Process flag (raised by QA)
Per
feedback_qa_ci_blockers.md: PR body left "CI: full test suite runs with service-container Postgres" unchecked. inet/UUID/CHECK constraint coverage is not real on SQLite. The next CI pipeline run on basketball-api should be checked to confirm tests pass against real Postgres before this validation note can move to pass with full confidence. (Marked PASS provisionally based on dev agent report; will update if CI flags issues.)What this unblocks
- T4 (#431) Gmail notification — depends on T3's POST handler existing (now does)
- T5 (#432) GET admin endpoint — modifies the same
routes/jersey_public.pyfile T3 just created - End-to-end System B flow — frontend (T1) can now successfully POST and get 201
Related
arch-jersey-intakestory:WS-S31validation-429-2026-04-11— sister validation for the migration this endpoint writes to