Thumbnail URL fix + archive daemon fix + batched initial loads #37
Reference in New Issue
Block a user
Delete Branch "dev"
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
Three UX-impacting fixes from 2026-05-30 afternoon. All "efficiency that hurt UX" reversals per the operator's standing principle.
adeee64+1eefed9— Showcase + gallery initial loads now batch into 5-item chunks (12×5 for showcase, 10×5 for gallery) instead of one big 60/50 request. Total preserved. Items render progressively as each batch lands; combined with MasonryGrid'sanimateFromIndex, the showcase cascades batches in as they arrive instead of one big pop-in.44bb12a— Thumbnail URL derived from storedthumbnail_pathinstead of re-deriving from(sha256, mime). The MIME-based extension predicate disagreed with the thumbnailer's transparency-based predicate (.pngifalphaelse.jpg) → every PNG-without-alpha and every WebP-with-alpha 404'd despite the file existing. Backfill was never the bug — it checks the correct on-disk path; the URL construction was the broken side. All 8 callers updated. No DB migration or backfill rerun needed.810baf6— Archive probe (safe_probe.probe_archive) switched frommultiprocessing.Processtosubprocess.run. The MP version crashed everyimport_archive_filein 49ms withAssertionError: daemonic processes are not allowed to have children(Celery prefork pool runs tasks in daemon processes; Python's multiprocessing forbids daemons from spawning children). Same crash isolation via subprocess; no daemon restriction. Layer-3 isolation added 2026-05-28 in [poison-pill resilience] was effectively a hard-blocker on the import path it was meant to protect.No alembic migrations. New backend surface:
backend/app/utils/_archive_probe_runner.py(subprocess entrypoint).Test plan
After
:latestrebuilds and compose restart:/api/showcase?limit=5calls instead of onelimit=60.<img>srcis the storedthumbnail_pathand the file 200s.AssertionErrorin 49ms; theimport_archive_filetask either succeeds or fails for a legitimate reason (bomb-guard, integrity, member-level).🤖 Generated with Claude Code