Feature: Unauthenticated photo upload for registration flow #108

Closed
opened 2026-03-18 23:21:56 +00:00 by forgejo_admin · 0 comments

Type

Feature

Lineage

plan-wkq → Phase 11 (Girls Tryout — March 24)

Repo

forgejo_admin/basketball-api

User Story

As a parent registering my player for tryouts
I want to upload a player photo during registration
So that the player profile is complete before tryout day

Context

The existing POST /upload/photo requires Keycloak authentication, but during registration the user doesn't have an account yet. The SPA registration form has a photo upload UI but can't actually send photos to the API. We need an unauthenticated upload endpoint specifically for the registration flow. The POST /api/register JSON endpoint (PR #107) already accepts photo_url — we just need the upload mechanism.

File Targets

Files to modify:

  • src/basketball_api/routes/register.py — add POST /api/register/upload-photo endpoint
  • tests/test_register_upload.py — new test file for upload tests

Files NOT to touch:

  • src/basketball_api/routes/upload.py — existing auth-required upload stays as-is (import constants from it)
  • src/basketball_api/routes/admin.py — no admin changes

Acceptance Criteria

  • POST /api/register/upload-photo accepts multipart file upload without auth
  • Valid image (JPG/PNG/WebP, ≤5MB) → 200 {"photo_url": "/uploads/photos/<uuid>.<ext>"}
  • Invalid extension → 400 error
  • File too large (>5MB) → 400 error
  • Non-image content type → 400 error
  • POST /api/register with photo_url field saves to Player.photo_url

Test Expectations

  • Unit test: valid photo upload returns photo_url
  • Unit test: invalid extension returns 400
  • Unit test: oversized file returns 400
  • Unit test: non-image content type returns 400
  • Integration test: register with photo_url saves to player record
  • Test various image sizes (small, medium, near 5MB limit)
  • Run command: pytest tests/ -x -v

Constraints

  • Reuse ALLOWED_EXTENSIONS, MAX_FILE_SIZE, UPLOAD_DIR from routes/upload.py
  • UUID-based filenames to prevent path traversal
  • No auth required (public endpoint for registration)
  • UPLOAD_DIR is /data/uploads/photos in prod (PVC mount)

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • westside-basketball — project
  • forgejo_admin/basketball-api #106 — promo code endpoint (this builds on it)
  • forgejo_admin/westside-app #47 — SPA fix (will consume this endpoint)
  • plan-wkq Phase 11 — Girls Tryout March 24
### Type Feature ### Lineage `plan-wkq` → Phase 11 (Girls Tryout — March 24) ### Repo `forgejo_admin/basketball-api` ### User Story As a parent registering my player for tryouts I want to upload a player photo during registration So that the player profile is complete before tryout day ### Context The existing `POST /upload/photo` requires Keycloak authentication, but during registration the user doesn't have an account yet. The SPA registration form has a photo upload UI but can't actually send photos to the API. We need an unauthenticated upload endpoint specifically for the registration flow. The `POST /api/register` JSON endpoint (PR #107) already accepts `photo_url` — we just need the upload mechanism. ### File Targets Files to modify: - `src/basketball_api/routes/register.py` — add `POST /api/register/upload-photo` endpoint - `tests/test_register_upload.py` — new test file for upload tests Files NOT to touch: - `src/basketball_api/routes/upload.py` — existing auth-required upload stays as-is (import constants from it) - `src/basketball_api/routes/admin.py` — no admin changes ### Acceptance Criteria - [ ] `POST /api/register/upload-photo` accepts multipart file upload without auth - [ ] Valid image (JPG/PNG/WebP, ≤5MB) → 200 `{"photo_url": "/uploads/photos/<uuid>.<ext>"}` - [ ] Invalid extension → 400 error - [ ] File too large (>5MB) → 400 error - [ ] Non-image content type → 400 error - [ ] `POST /api/register` with `photo_url` field saves to `Player.photo_url` ### Test Expectations - [ ] Unit test: valid photo upload returns photo_url - [ ] Unit test: invalid extension returns 400 - [ ] Unit test: oversized file returns 400 - [ ] Unit test: non-image content type returns 400 - [ ] Integration test: register with photo_url saves to player record - [ ] Test various image sizes (small, medium, near 5MB limit) - Run command: `pytest tests/ -x -v` ### Constraints - Reuse `ALLOWED_EXTENSIONS`, `MAX_FILE_SIZE`, `UPLOAD_DIR` from `routes/upload.py` - UUID-based filenames to prevent path traversal - No auth required (public endpoint for registration) - UPLOAD_DIR is `/data/uploads/photos` in prod (PVC mount) ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `westside-basketball` — project - `forgejo_admin/basketball-api #106` — promo code endpoint (this builds on it) - `forgejo_admin/westside-app #47` — SPA fix (will consume this endpoint) - `plan-wkq` Phase 11 — Girls Tryout March 24
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#108
No description provided.