Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesProgress PhotosProgress Photos

Progress Photos

Linear epic: FIT-72 Status: Shipped. Last reviewed: 2026-05-28

What

A private, chronological gallery of member-uploaded body photos. Each photo carries recorded_at (day granularity), optional notes, optional bodyweight_kg, dimensions, MIME, R2 storage key, and a generated thumbnail. Standalone — not linked to a body_metrics row (members can snap a photo without logging a measurement and vice versa).

Why

  • Visual progress is a primary engagement driver for body-recomp members.
  • Lighting / pose comparison is more meaningful than scale weight.
  • Photos are private: visible only to the member and active staff (owner/admin/coach) in the same org.

Personas

PersonaSurfaceCapabilities
MemberMobile app (primary) + web /members/me/progress-photosUpload, list own timeline, soft-delete own photos
Staff (coach/admin/owner)Member detail pageList a member’s photos, view full-res via presigned URL

Capabilities

  • Upload via the standard staged-PUT flow (uploads module) — member POSTs { uploadId } after the binary lands in R2; service runs sharp to generate a thumbnail and probe dimensions.
  • Thumbnail stored under a separate thumbnail_r2_key.
  • List is paginated by cursor (id of the oldest row in the previous page), date-range filterable.
  • Presigned reads — every list response presigns both full-size and thumbnail URLs (1h TTL, Redis-cached).
  • Soft deletedeleted_at is set; binary remains in R2 (no janitor today).

Capabilities (gaps)

GapTracking
R2 janitor for soft-deleted photo binariesnot tracked
Side-by-side compare UInot tracked
Member-controlled per-photo “share with coach” toggle (today all photos are coach-visible)not tracked
Push notification on upload (for coach attention)FIT-170 follow-up
EXIF stripping on uploadnot tracked — security concern: GPS coords could leak

Source code

  • API: apps/api/src/progress-photos/
  • DB: libs/db/src/lib/schema/progress-photos.ts
  • Web: apps/web/src/components/member/ (member self-view); apps/web/src/components/overview/members/ (staff view)
  • R2: apps/api/src/r2/r2.service.ts