Case study

Milk & Henny Sharing

Work on the tools around the archive: event-night check-in, voting, uploads, private transfers, downloads, auth, cleanup, and cost controls.

Context
Personal platform / 2025
Focus
Photo sharing, event tooling, private transfers, auth, R2, Redis/KV
Link
milkandhenny.com

The product came from a simple repeated friction: I would take photos at parties, while travelling, and on film/digital cameras, then people would ask for them afterwards. Milk & Henny makes that exchange cleaner: an event can have tools, a gallery can have filters and downloads, and large media can stay cheap instead of becoming a chain of temporary transfer links.

Thread Work Signal
Event operations Built the party hub, guest-list check-in, admin management, best-dressed voting, vote-code controls, multi-device sync, and album download paths. The site supports the whole event loop: guests arrive, participate, find photos, and leave with a way to get what they need.
Photo sharing Built private transfer links, R2 storage, presigned uploads, delete tokens, media previews, optimized galleries, and batch download paths. People can browse and download their own photos from an owned surface instead of repeatedly asking for files after the event.
Operational control Implemented httpOnly role cookies, token revocation/versioning, admin step-up, cron cleanup, R2 lifecycle guidance, worker fallbacks, and CLI diagnostics. The archive can stay inexpensive and recoverable: sessions can be revoked, files can expire, credentials can rotate, and costs have guardrails.
Layer Detail
Guest list Door-staff check-in uses server-readable auth, optimistic UI, multi-device polling, CSV import, plus-one handling, and conservative fetch gaps.
Best dressed Voting uses staff-minted one-time codes, optional voting windows, per-device identity, server validation against the guest list, and admin resets.
Upload path Browser uploads use presigned PUT URLs so large photo and video files go directly to Cloudflare R2 instead of through serverless request bodies.
Lifecycle Transfer metadata lives in Redis with TTL, pages are noindexed, delete tokens are separate from recipient links, and cron/R2 lifecycle cleanup catches residue.
Heavy media Hybrid processing handles RAW previews, video posters, browser HEIC/HIF conversion, and ZIP fallback for multi-file downloads.
Auth model Role JWTs live in httpOnly cookies; API bearer auth remains available for CLI and tools; admin actions use step-up tokens and revocation checks.
Cost guardrails CDN caching, direct R2 media delivery, polling budgets, retry rules, rate limits, and documented rotation paths reduce expensive surprises.
  1. Event tools define the role first: guest, staff, or admin.
  2. Live state stays lightweight so check-in and voting remain usable during the night.
  3. Uploads go straight to R2 while metadata records expiry, ownership, and deletion paths.
  4. Galleries and transfer pages expose previews, filters, sorting, and downloads so recipients can self-serve.
  5. Auth, cleanup, budgets, and rate limits keep the archive private, cheap, and recoverable.

The nicest sharing experience is often the one where nobody has to ask twice. People can find themselves, choose the quality they need, and download from a place that feels like mine rather than a temporary workaround.