Add video as a media kind in photos: streaming upload with per-kind
limits, ffprobe metadata, poster frame reusing the image variant
pipeline, and a playback object (remux when web-compatible, else
h264/yuv420p/aac transcode). Video jobs run on a separate pool with a
long lease. Frontend gains a video viewer, grid badge/duration and
video upload.
- rename Go module, binary, systemd unit, PG_DATABASE default, frontend package and docs from shared-album to galo
- add theme-aware halo emblem and favicon (new ui-branding capability)
- add make build-release (versioned, stripped, static binary) and run the binary from the repo root
- app_settings table (PostgreSQL migration 000010, SQLite 000002)
- internal/settings repository (Get/Set/Ensure) wired into store.Repos
- secret generated with crypto/rand on first start and persisted; reused on restart
- drop required JWT_SECRET from env/config; app.New takes a TokenManager and
storage.Open takes the resolved secret (URL_SECRET still overrides)
- docs updated
- introduce storage.Backend with S3 and local file-system implementations
- deliver all blobs via signed GET/HEAD /api/objects/<key> (Range, Content-Type)
- stream S3 objects through the backend; remove presigned URL path
- share shared HMAC Signer between backends
- remove S3_PUBLIC_URL; rename S3_PRESIGN_TTL to OBJECT_URL_TTL
- make storage label in health dynamic; nginx proxy_buffering off for objects
Backend (Go/Gin/pgx): env config, pgx pool with retries, Garage S3 client
(path-style, region garage), embedded golang-migrate migrations, JWT auth with
refresh rotation, albums CRUD, members/roles/invites with no-escalation matrix,
photo upload + async imaging/goexif WebP variants, cursor pagination, presigned
URLs, likes/comments, SSE hub (album + personal), notifications, share links.
Frontend (SvelteKit 2 + Svelte 5 + Tailwind v4): API wrapper with 401 refresh,
auth store, all screens, Uploader/PhotoGrid/Lightbox/Comments, SSE client with
reconnect + REST catch-up, three themes + system via data-theme.
Deploy without Docker: Makefile builds the frontend into backend/static and
embeds it (go:embed) into a single statically linked binary; systemd unit and
nginx SSE example included.
Use gen2brain/webp (-tags nodynamic) instead of cgo kolesa-team/go-webp to keep
CGO_ENABLED=0 static builds; design.md/proposal.md updated accordingly.