Skip to content

Personal project · 2026

Wedding Media Collector

Built for my own wedding: guests scan a QR code and share photos and videos, without an app or an account.

Role
Sole designer and engineer — 53 commits in 10 days
Year
2026
Stack
Next.js · Cloudflare Workers · D1 · R2 · Drizzle ORM · Better Auth · Zod · Turnstile · GSAP · Vitest · Playwright

The problem

At a wedding, the best photos end up scattered across a hundred phones. I wanted guests to share them in seconds, without installing anything or signing up.

Approach

A strictly Cloudflare-first architecture: Next.js on Workers through OpenNext, metadata in D1 with Drizzle, media bytes in a private R2 bucket. Separate preview and production environments, each with its own database and bucket.

Guests open an unlisted link from the QR code; access is verified on the server with hashed tokens. Each upload goes through a short-lived, single-object signed intent that checks type, size and per-event quota, with Turnstile in front.

How it flows

  1. 01

    Guest scans the QR

    Unlisted link, no account

  2. 02

    Access check

    Hashed token, verified on the server

  3. 03

    Upload intent

    Turnstile · type · size · quota

  4. 04

    Direct upload

    Signed single-object URL → private R2

  5. 05

    Moderated gallery

    Optional organizer approval · metadata in D1

What I built

  • QR-code guest access with no account
  • Signed, quota-checked direct uploads to private storage
  • A moderated gallery and an organizer dashboard
  • Unit tests with Vitest and end-to-end tests with Playwright

Outcome

Designed, built and shipped in ten days — and used at the wedding.