Commit Graph

6 Commits

Author SHA1 Message Date
5179786261 Docs: Bump constitution to v1.2.0 — reflect JWT auth completion
Phase 2 (JWT bearer) is shipped; update §2.4 phase status, add PyJWT
to §6 tech stack table, remove username/password from §8 out-of-scope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 19:17:18 +00:00
86961d19ee Chore: Add updated files 2026-05-03 15:13:35 -04:00
d91a65abe5 Docs: Update scope boundaries in constitution
Due to the introduction of image thumbnail generation in
cd89ba5dea, the scope boundaries in §10 of
the project constitution should be updated with a clarification.
2026-05-03 14:02:51 -04:00
f953c88984 Feat: Pre-generate WebP thumbnails on upload for faster library load
- Add Pillow dependency and thumbnail.py with generate_thumbnail() — produces
  WebP ≤400px, preserves aspect ratio, never upscales, handles GIF frame 0
- Alembic migration 002 adds nullable thumbnail_key column to images table
- Upload route generates thumbnail via asyncio.to_thread (non-blocking),
  stores at {hash}-thumb; failure is tolerated and upload succeeds with null key
- New GET /api/v1/images/{id}/thumbnail endpoint: serves WebP thumbnail or
  falls back to original for pre-feature images; ETag + immutable cache headers
- Delete route cleans up thumbnail storage object alongside original
- Library grid switches from /file to /thumbnail for all image src bindings
- 59 tests passing (46 existing + 13 new across unit, upload, serving, delete)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:26:16 +00:00
cd89ba5dea Feat: Proxy image content through the API instead of redirecting to MinIO
Replace the presigned-URL redirect (302) in GET /api/v1/images/{id}/file
with a direct proxy that fetches bytes from S3 server-side and returns them
to the client. The browser never contacts the storage backend, eliminating
the /etc/hosts workaround needed in local development.

- StorageBackend: swap get_presigned_url for get(key) -> bytes
- S3StorageBackend: implement get() via aiobotocore get_object
- serve_image_file: return Response with ETag + Cache-Control: immutable
- test_serving: assert 200 + content-type + ETag; add no-storage-details test
- Spec Kit artifacts for feature 002-api-image-proxy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 16:36:43 +00:00
691f7570fe [Spec Kit] Initial commit — constitution, spec, plan, and tasks for Reaction Image Board v1 2026-05-02 15:56:39 +00:00