By: Michael Lynch <git@mtlynch.io>
Add owner media uploads (milestone 6) Owners can now upload photos and videos through the web UI, the first write path in the app. Everything was previously read-only, populated only by the offline import-from-tinybeans command. Behavior: - An always-visible "Upload" button appears in the navbar for owners (outside the collapsible region so it stays visible on mobile). - Photos (JPEG) and animated GIFs are processed synchronously: the full-size image is re-encoded to strip Exif/metadata, and display and thumbnail variants are generated, before the item is published. - Videos are transcoded to WebM (VP9 + Opus) in a background worker. The uploader sees a "Video processing in progress" notice and the item is hidden from other users until transcoding completes. - Uploads are owner-only; subscribers get 403 and never see the button. Media model and storage: - Video is now always WebM. The TinyBeans import pipeline transcodes imported .mp4 videos to .webm too, so the system has a single video format. ImportMedia takes an injected video converter alongside the GIF converter. - media_items gains a status column (ready/processing). ReadMediaItems filters by viewer so processing items are visible only to their uploader. Other changes: - newPageData resolves the current user to expose IsOwner to templates. - The app binary is wrapped with ffmpeg in flake.nix, and the prod Dockerfile installs ffmpeg, since the app now execs ffmpeg/ffprobe. Known limitation: because raw originals are not retained, a server restart mid-transcode leaves a video stuck in the processing state; durable job scheduling is future work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>