Skip to content

feat: image ingestion and serving - #14

Merged
jalmena merged 4 commits into
developfrom
feature/images
Sep 23, 2026
Merged

jalmena merged 4 commits into
developfrom
feature/images

Conversation

@jalmena

@jalmena jalmena commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Third Phase 1 slice: photographs.

  • Scrubbing at the container level (JPEG segments, PNG chunks): GPS, maker notes, comments and thumbnails never reach the disk; capture time and orientation are extracted first; pixels stay byte-identical. Other formats (HEIC…) are re-encoded as JPEG and marked.
  • Content-addressed blob store with atomic writes, hash-keyed directories and a free-space guard (507 when the volume is nearly full).
  • Renditions: upright, metadata-free progressive JPEGs at 2048/1024/256 px, generated at upload.
  • API: POST /api/persons/{id}/images (multipart; role, modality, capture time override), GET /api/persons/{id}/images, GET /api/images/{id}, GET /api/images/{id}/{original|full|preview|thumb} with ETag/304 and private, immutable caching, DELETE to the trash. Access follows the person's owner/manager/viewer roles.
  • Tests: scrubbing byte-level guarantees, orientation applied to renditions, deduplication of identical uploads, access matrix, limits, low disk. Verified locally on SQLite and PostgreSQL 16; alembic check clean on both.

…enditions

Uploads are cleaned at the container level so the compressed image data stays byte-for-byte the original: JPEG APPn and COM segments and PNG text, EXIF and time chunks are dropped, keeping JFIF and ICC; capture time and orientation are extracted first. Formats browsers cannot show are re-encoded as JPEG and marked as such. Blobs are written atomically under a hash-keyed tree with a free-space guard; renditions (2048, 1024, 256 px) are upright, metadata-free progressive JPEGs.

Signed-off-by: Jose David <josedalmena@gmail.com>
Images belong to a person and record role, modality, hash, size, orientation, source format, whether they were re-encoded and the capture time; renditions are unique per image and kind.

Signed-off-by: Jose David <josedalmena@gmail.com>
… see them

Owners and managers upload (size, pixel and free-space limits; unsupported files refused); everyone with access to the person fetches the original or a rendition with immutable private caching and ETags; deletion moves the image to the trash.

Signed-off-by: Jose David <josedalmena@gmail.com>
…nd limits

Signed-off-by: Jose David <josedalmena@gmail.com>
@jalmena
jalmena merged commit 8eddac7 into develop Sep 23, 2026
5 checks passed
@jalmena
jalmena deleted the feature/images branch September 23, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant