Bug: Missing player photo returns 404 — uploads/photos storage gap #374
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#374
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Type
Bug
Lineage
Standalone — discovered during CRM monitoring session 2026-04-07. Observed in access logs from Marcus's iPhone browsing.
Repo
forgejo_admin/basketball-api(API-only fix — no cross-repo changes needed)What Broke
GET /uploads/photos/4685d046593942f48013a484bb3739e9.jpgreturns 404 Not Found. At least one player has a photo reference in the database that doesn't exist on disk. Another photo (d8de178c3ca94c738d561ec998196006.jpg) returned 304 (cached, exists).The storage infrastructure is sound — PVC is correctly wired at
/data/uploads/photoswith RWO access mode and Recreate deployment strategy. The issue is either an orphaned DB reference or a file that was lost.ImageStaticFilesinsrc/basketball_api/static.pyserves raw 404s for missing files with no fallback. The tryouts route (src/basketball_api/routes/tryouts.py:195-201) already has a silhouette SVG placeholder pattern, but player profile and admin views do not.7+ consumers of
photo_urlacross basketball-api and westside-app.Repro Steps
GET /uploads/photos/4685d046593942f48013a484bb3739e9.jpg 404Expected Behavior
All photos referenced in the database exist in the uploads directory. When a photo file is missing, the API returns a default placeholder image instead of 404.
Environment
basketball-api-6d89b9fc4f-ldjvcAcceptance Criteria
4685d046593942f48013a484bb3739e9.jpg)ImageStaticFilesreturns a default silhouette placeholder for missing photos instead of 404tryouts.py:195-201File Targets
src/basketball_api/static.py— add fallback placeholder for missing photossrc/basketball_api/routes/tryouts.py:195-201— reference implementation for silhouette patternDiscovered Scope (separate ticket)
src/basketball_api/routes/register.py:1069duplicatesupload.pyupload logic — DRY violation, track separatelyRelated
westside-basketball— project this affectsstory:WS-S24— "As a player, I want to view my profile with photo and team info"Scope Review: NEEDS_REFINEMENT
Review note:
review-879-2026-04-07Traceability is mostly solid (story:WS-S24 verified, Forgejo issue open), but arch note is missing and issue body template completeness could not be verified due to tooling gap.
Issues found:
[SCOPE]Architecture notearch-basketball-apidoes not exist in pal-e-docs -- needs to be created[BODY]Verify all template-issue-bug sections are present (Type, Lineage, Repo, What Broke, Repro Steps, Expected Behavior, Environment, AC, Related) -- reviewer could not read issue body[BODY]AC should explicitly state whether fix is API-only (ImageStaticFiles 404 override) or requires frontend changes in westside-app[BODY]File targets should list:static.py, test file for 404 fallback, possiblyupload.py[BODY]DRY concern:register.py:1069duplicatesupload.pylogic -- track as discovered scope, not in this bug's scopeCodebase findings:
ImageStaticFilesinstatic.pyhandles MIME types but has no 404 fallbacktryouts.py:195) already has silhouette SVG fallback -- player profile and admin views do notScope refinement (post review-879-2026-04-07):
static.py, reference pattern intryouts.py:195-201photo_urlregister.py:1069) as separate scopeScope Review: READY
Review note:
review-879-2026-04-07(updated from NEEDS_REFINEMENT to READY)Re-review after refinement. All 4 [BODY] recommendations from v1 addressed. File targets verified against codebase -- static.py is the fix target (override 404 to serve placeholder), tryouts.py silhouette pattern is the reference implementation.
Remaining [SCOPE]: Create architecture note
arch-basketball-api(organizational gap, not a ticket blocker -- carried forward).Ticket is ready for dispatch. Estimated agent time: under 5 minutes. No decomposition needed.