Skip to content
brorn
No. 004 · Sports & video

douro.united

App for a weekly pickup football game: roster, balanced team draw, live score, stats, game video and an Apple Watch app.

Live
Period
2026-08 → now
Platforms
iPhone · Apple Watch · Web
Role
Solo: design, build, ship
Tech
Fig. 1 · Live game
Fig. 2 · Player ranking
Fig. 3 · Share card

§1The problem

Organising a pickup game every week (who's coming, even teams, score and history) was done in a group chat and from memory.

§2What I built

  • PWAInstallable web app with 4 tabs: players, match, history and stats.
  • Player levelVisible in the app but hidden on shared cards.
  • Team drawLevel suggested by an explainable heuristic (never applied on its own).
  • Roster importFrom the group chat messages, using an AI model.
  • SharingShareable match card (image) and video with clips, like match.day.
  • Watch appApple Watch and iPhone (record, log goals); a mock server to test without a watch.

§3The hard parts

5 entries
  1. 01

    Rewrite as a monorepo shared with match.day

    Server, web and shared types, done in phases with tests.

  2. 02

    Database migration

    A backup before migrating and a hash of each migration.

  3. 03

    Offline

    Service worker, queue and local copy, with safe batched resending.

  4. 04

    Two cameras

    The iPhone looks for the other camera when it opens.

  5. 05

    Local access guard

    Host allowlist, cross-site requests refused, IP addresses fully validated.

§4Result

In production on my home server (web and API). Every stage of the plan, including the watch app and the two cameras, is done and was tested with the person who wears the watch. Sharing the match card was tested on a real iPhone and works.

§5Stack

  • Next.js 16
  • React 19
  • TypeScript 7
  • Tailwind 4
  • Zustand
  • SQLite (better-sqlite3)
  • ffmpeg
  • SwiftUI / watchOS
  • pm2
  • Tailscale