Three bugs fixed:
1. Vision failure was marking memories as 'failed', triggering orphan
cleanup that permanently deleted them. Vision is optional — on error,
now marks 'ready' so the image stays visible without AI captions.
2. Thumbnail failure was blocking vision from running (rejected promise
swallowed the chain). Fixed by catching thumbnail error separately so
processMemoryVision always executes and always sets a final status.
3. /api/img proxy was rejecting thumbnail keys (families/{id}/thumbnails/…)
because 'families/' was not in ALLOWED_PREFIXES. Added it.
Also: replaced the full-bleed 'Processing…' overlay with a small corner
badge so the uploaded photo is visible immediately after upload.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pub-xxx.r2.dev returns 503 for cross-origin sub-resource requests (img tags,
fetch) due to Cloudflare Bot Management on the r2.dev dev domain. Direct
browser navigation works but programmatic loading fails, so all uploaded
images appeared as placeholders after upload.
Fix: route all image display through a same-origin /api/img?key=... proxy that
fetches from R2 via the S3 API server-side. API responses (profile, children,
memories) now return proxy URLs. After upload, UI state is updated with proxy
URLs directly rather than raw R2 URLs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>