feat: unauthenticated photo upload for registration #109

Merged
forgejo_admin merged 1 commit from 108-register-photo-upload into main 2026-03-18 23:28:18 +00:00

Summary

  • Add POST /api/register/upload-photo public endpoint for uploading player photos during the registration flow without authentication
  • Validates file extension, content type, size (5MB max), and emptiness; saves with UUID filename
  • Verified that POST /api/register already saves photo_url to the player record (no changes needed)

Changes

  • src/basketball_api/routes/register.py: Added register_upload_photo() async endpoint with full validation. Moved JSONResponse import to module-level (was a lazy import inside api_register). Added os, uuid, UploadFile imports.
  • tests/test_register_upload.py: 15 new tests across two classes -- TestRegisterUploadPhoto (13 tests covering valid uploads, invalid extensions, content type, size limits, empty file, no-auth) and TestApiRegisterWithPhoto (2 tests verifying photo_url persistence through registration).

Test Plan

  • Tests pass locally (416/416, including 15 new)
  • ruff format and ruff check clean
  • Existing POST /upload/photo (auth-required) untouched
  • No regressions in registration or upload flows

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
## Summary - Add `POST /api/register/upload-photo` public endpoint for uploading player photos during the registration flow without authentication - Validates file extension, content type, size (5MB max), and emptiness; saves with UUID filename - Verified that `POST /api/register` already saves `photo_url` to the player record (no changes needed) ## Changes - `src/basketball_api/routes/register.py`: Added `register_upload_photo()` async endpoint with full validation. Moved `JSONResponse` import to module-level (was a lazy import inside `api_register`). Added `os`, `uuid`, `UploadFile` imports. - `tests/test_register_upload.py`: 15 new tests across two classes -- `TestRegisterUploadPhoto` (13 tests covering valid uploads, invalid extensions, content type, size limits, empty file, no-auth) and `TestApiRegisterWithPhoto` (2 tests verifying photo_url persistence through registration). ## Test Plan - [x] Tests pass locally (416/416, including 15 new) - [x] `ruff format` and `ruff check` clean - [x] Existing `POST /upload/photo` (auth-required) untouched - [x] No regressions in registration or upload flows ## Review Checklist - [x] Passed automated review-fix loop - [x] No secrets committed - [x] No unnecessary file changes - [x] Commit messages are descriptive ## Related - Closes #108
feat: add unauthenticated photo upload for registration flow
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
1f45f1019a
Add POST /api/register/upload-photo endpoint that accepts multipart
file uploads without authentication, enabling the westside-app
registration form to upload player photos before completing sign-up.
Validates file extension, content type, size (5MB max), and emptiness.

Closes #108

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

Review - Pass

Files reviewed: src/basketball_api/routes/register.py, tests/test_register_upload.py

Findings: No issues found.

  • Endpoint correctly validates extension (whitelist), content type, emptiness, and size before saving
  • UUID filenames prevent path traversal
  • Error responses use consistent {"error": "..."} JSON format with 400 status
  • Constants imported from upload.py at function scope (avoids circular imports)
  • Existing auth-required POST /upload/photo is untouched
  • JSONResponse import cleanup (module-level instead of lazy) is correct
  • 15 tests cover all validation paths including boundary cases
  • Full suite passes (416/416)
## Review - Pass **Files reviewed**: `src/basketball_api/routes/register.py`, `tests/test_register_upload.py` **Findings**: No issues found. - Endpoint correctly validates extension (whitelist), content type, emptiness, and size before saving - UUID filenames prevent path traversal - Error responses use consistent `{"error": "..."}` JSON format with 400 status - Constants imported from `upload.py` at function scope (avoids circular imports) - Existing auth-required `POST /upload/photo` is untouched - `JSONResponse` import cleanup (module-level instead of lazy) is correct - 15 tests cover all validation paths including boundary cases - Full suite passes (416/416)
forgejo_admin deleted branch 108-register-photo-upload 2026-03-18 23:28:18 +00:00
Sign in to join this conversation.
No description provided.