Phase 1: Player registration form + data model #7

Closed
opened 2026-03-09 17:33:55 +00:00 by forgejo_admin · 0 comments

Lineage

plan-2026-03-08-tryout-prep → Phase 1 (Player registration form + data model)

Repo

forgejo_admin/basketball-api

User Story

As a parent/player
I want to fill out a profile form with my kid's photo, school, and details
So that coaches have a complete roster with faces and names for tryouts on March 13

Context

Tryouts are March 13, 6-8 PM at Kongo Gym, Farmington. 34 players have paid $30 via Stripe but we have NO profile data beyond what Stripe collects (name, height, graduating class, parent contact). Coaches need player profiles to learn names and faces before tryout day.

What already exists:

  • Models: Tenant, Parent, Player, Registration — multi-tenant, Postgres
  • Stripe webhook handler: checkout.session.completed → creates Parent/Player/Registration
  • Roster HTML view: authenticated (admin/coach), shows player list with payment status
  • Auth: pal-e-auth with role-based access (admin, coach)

Decisions made in planning:

  • Registration form served by basketball-api — simple HTML form, mobile-friendly, posts to API. No SvelteKit scaffold needed.
  • Build on basketball-api, not a new app — FastAPI + Postgres + auth + Stripe webhook already deployed and working.
  • Evaluation scoring is NOT in scope — March 13 goal is roster + profiles, not scoring.

File Targets

Files the agent should modify or create:

  • src/basketball_api/models.py — add new fields to Player model
  • alembic/versions/ — new migration for Player field additions
  • src/basketball_api/routes/register.py — new: GET /register (HTML form) + POST /register (save to DB)
  • src/basketball_api/routes/upload.py — new: POST /upload/photo (file upload, returns URL)

Files the agent should NOT touch:

  • src/basketball_api/routes/coach.py — that's Phase 2
  • src/basketball_api/services/email.py — that's Phase 3

Acceptance Criteria

  • Player model has new fields: photo_url (String), date_of_birth (Date), current_school (String), target_schools (JSON/Text — top 3), hometown (String), team_preference (String enum: local/travel/both), tryout_number (Integer, nullable), checked_in (Boolean)
  • Alembic migration runs cleanly against existing DB with 34 players
  • GET /register returns a mobile-friendly, branded HTML form collecting: player name, photo, height, position, graduating class, DOB, current school, top 3 target schools, hometown, local/travel/both preference, parent name, parent address, parent email, parent phone
  • POST /register saves data to Postgres. If player already exists (match by parent email), updates profile instead of creating duplicate
  • POST /upload/photo accepts image upload and returns a URL
  • After form submit: if player has not paid, redirect to Stripe $30 tryout payment link (https://buy.stripe.com/eVqaEZdsGgpa52i5jI0VO03). If already paid, show confirmation.
  • Backfill: script or endpoint to verify existing 34 Stripe checkout sessions are in DB (from webhook), and surface any missing

Test Expectations

  • Unit test: Player model fields exist with correct types
  • Unit test: Registration form POST creates/updates Player + Parent records
  • Unit test: Duplicate parent email updates existing player instead of creating new
  • Integration test: Full form submit → data in Postgres → correct redirect based on payment status
  • Run command: pytest tests/ -v

Constraints

  • Match existing route style in the codebase (check existing routes for patterns)
  • Photo storage: use whatever basketball-api already supports (local filesystem or S3). Don't introduce new dependencies unless necessary.
  • Form must look good on mobile — parents will use phones
  • All new fields nullable so existing 34 player records aren't broken by migration

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-westside-basketball — project this affects
  • Phase 2 (coach onboarding) runs in parallel but doesn't depend on this
  • Phase 3 (email blast) depends on this — form URL goes in the email
  • Phase 4 (tryout day interface) depends on this — roster view uses these fields
### Lineage `plan-2026-03-08-tryout-prep` → Phase 1 (Player registration form + data model) ### Repo `forgejo_admin/basketball-api` ### User Story As a parent/player I want to fill out a profile form with my kid's photo, school, and details So that coaches have a complete roster with faces and names for tryouts on March 13 ### Context Tryouts are March 13, 6-8 PM at Kongo Gym, Farmington. 34 players have paid $30 via Stripe but we have NO profile data beyond what Stripe collects (name, height, graduating class, parent contact). Coaches need player profiles to learn names and faces before tryout day. **What already exists:** - Models: Tenant, Parent, Player, Registration — multi-tenant, Postgres - Stripe webhook handler: checkout.session.completed → creates Parent/Player/Registration - Roster HTML view: authenticated (admin/coach), shows player list with payment status - Auth: pal-e-auth with role-based access (admin, coach) **Decisions made in planning:** - Registration form served by basketball-api — simple HTML form, mobile-friendly, posts to API. No SvelteKit scaffold needed. - Build on basketball-api, not a new app — FastAPI + Postgres + auth + Stripe webhook already deployed and working. - Evaluation scoring is NOT in scope — March 13 goal is roster + profiles, not scoring. ### File Targets Files the agent should modify or create: - `src/basketball_api/models.py` — add new fields to Player model - `alembic/versions/` — new migration for Player field additions - `src/basketball_api/routes/register.py` — new: GET /register (HTML form) + POST /register (save to DB) - `src/basketball_api/routes/upload.py` — new: POST /upload/photo (file upload, returns URL) Files the agent should NOT touch: - `src/basketball_api/routes/coach.py` — that's Phase 2 - `src/basketball_api/services/email.py` — that's Phase 3 ### Acceptance Criteria - [ ] Player model has new fields: photo_url (String), date_of_birth (Date), current_school (String), target_schools (JSON/Text — top 3), hometown (String), team_preference (String enum: local/travel/both), tryout_number (Integer, nullable), checked_in (Boolean) - [ ] Alembic migration runs cleanly against existing DB with 34 players - [ ] `GET /register` returns a mobile-friendly, branded HTML form collecting: player name, photo, height, position, graduating class, DOB, current school, top 3 target schools, hometown, local/travel/both preference, parent name, parent address, parent email, parent phone - [ ] `POST /register` saves data to Postgres. If player already exists (match by parent email), updates profile instead of creating duplicate - [ ] `POST /upload/photo` accepts image upload and returns a URL - [ ] After form submit: if player has not paid, redirect to Stripe $30 tryout payment link (`https://buy.stripe.com/eVqaEZdsGgpa52i5jI0VO03`). If already paid, show confirmation. - [ ] Backfill: script or endpoint to verify existing 34 Stripe checkout sessions are in DB (from webhook), and surface any missing ### Test Expectations - [ ] Unit test: Player model fields exist with correct types - [ ] Unit test: Registration form POST creates/updates Player + Parent records - [ ] Unit test: Duplicate parent email updates existing player instead of creating new - [ ] Integration test: Full form submit → data in Postgres → correct redirect based on payment status - Run command: `pytest tests/ -v` ### Constraints - Match existing route style in the codebase (check existing routes for patterns) - Photo storage: use whatever basketball-api already supports (local filesystem or S3). Don't introduce new dependencies unless necessary. - Form must look good on mobile — parents will use phones - All new fields nullable so existing 34 player records aren't broken by migration ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-westside-basketball` — project this affects - Phase 2 (coach onboarding) runs in parallel but doesn't depend on this - Phase 3 (email blast) depends on this — form URL goes in the email - Phase 4 (tryout day interface) depends on this — roster view uses these fields
forgejo_admin 2026-03-09 18:07:34 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/basketball-api#7
No description provided.