feat: add JSON /api/register with promo code support #107
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!107
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "106-promo-code-registration"
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
POST /api/registerJSON endpoint for programmatic registration from the westside-app SPAChanges
src/basketball_api/config.py: Addedtryout_promo_codessetting (comma-separated, env:BASKETBALL_TRYOUT_PROMO_CODES)src/basketball_api/routes/register.py: AddedAPIRegistrationRequestPydantic model andPOST /api/registerendpoint with promo/cash/card payment paths, Keycloak auto-creation for paid registrationssrc/basketball_api/routes/jersey.py: Fixed pre-existing E402 lint violation (moved import to top of file)tests/test_promo_registration.py: 16 tests covering valid/invalid promo codes, cash/card paths, missing required fields, and DB record creationTest Plan
POST /registerHTML endpoint unchanged)Review Checklist
Related
QA Review -- PR #107
What was reviewed
src/basketball_api/config.py-- newtryout_promo_codessettingsrc/basketball_api/routes/register.py-- newPOST /api/registerJSON endpointsrc/basketball_api/routes/jersey.py-- E402 lint fix (import moved to top)tests/test_promo_registration.py-- 16 new testsFindings
No blockers found. Implementation is correct and well-tested.
Nits (non-blocking):
from typing import Optionalvsstr | None-- The project targets Python 3.12+ andmodels.pyusesstr | Nonethroughout. The Pydantic model usesOptional[str]instead. Both work, butstr | Nonewould be more consistent with the codebase style. Not worth a fix cycle.JSONResponseimported inside conditional (line ~1078) -- The import could live at the top with the otherfastapi.responsesimports. Functional but slightly unconventional. Minor.signature_nameis validated but not persisted -- The field is required in the request body and validated as non-empty, but its value is never stored. The waiver_signed fields on Parent capture the fact that the waiver was accepted, but the actual typed signature name is discarded. This may be intentional (matching HTML form behavior where only a checkbox is used), but worth confirming with the issue author if the signature name should be stored somewhere.No email format validation --
parent_emailis a plainstr(EmailStr was removed becauseemail-validatoris not installed). The endpoint will accept any string as an email. The existing HTML form also has no server-side email validation, so this is consistent, but worth noting.Code duplication with
submit_registration()-- The issue says to "REUSE" logic. The new endpoint duplicates the parent/player/registration creation flow rather than extracting a shared helper. However, the existing function is tightly coupled to HTML form handling (FormData parsing, photo upload, HTMLResponse rendering, token-based flows), so extracting shared logic would require refactoring the existing endpoint and risk breaking it. The pragmatic duplication is defensible for this scope.Test coverage
All 4 required test scenarios from the issue are covered:
Plus additional coverage for case-insensitive matching, card redirect, parent deduplication, and record creation verification.
VERDICT: APPROVE