5 — Billboard: Prototype → Production Hardening
Rank 6 of 28 · Tier A · app/workers/billboard_users, app/BillboardGateway, docs/billboard/
Stack: TypeScript (Hono), Cloudflare Workers, D1, R2, KV, Durable Objects, Hyperdrive → Postgres, WASM (kissfft), GitHub CI
Status: ~60 commits over the hardening campaign. Upload live in production. CI gates enforced.
Why this ranks here. This is the production engineering story, and it is the one a bank cares about most. It starts from a written audit that names everything broken, then closes the gaps one numbered commit at a time, with the CI gates that stop them reopening. Google calls this "reduce toil and make the fix stick." Banks call it "evidence."
It starts with an audit, not code
docs/billboard/ is a 17-chapter engineering manual written before the
remediation began: executive summary, system architecture, iOS client, audio
engine, feature surfaces, recognition, edge, workers, data layer, an
API contract diff, upload current-state, security & auth, a gap
register, a Spotify parity matrix (14 of 52 features), an upload v2
design, a remediation roadmap, and a task list.
The audit's findings were blunt:
- Five distinct API hosts serve one feature mode. No single gateway; the iOS client fans out directly to each.
billboard-feed-apiwas a mock data generator — writes were discarded.BillboardGatewayExpress origin was a scaffold with one health route.- Auth was forgeable.
- No audio upload path existed at all.
What was then built
Auth made real — [F-2]
RS256 JWT verification replacing forgeable auth, split into four privilege
tiers, with identity bound to the token rather than trusted from the body.
Applied to global-media-worker as well.
The data layer made real — [F-3], [F-8], [D-4]
Nine missing D1 tables defined; column drift between code and schema bridged;
billboard-feed-db wired and its schema applied; ProfileService moved to
Postgres after Profile was 404ing against an empty D1 table.
Resumable multipart upload — [F-1], [W-3], [A-9]
R2 multipart ingest with 10 MiB equal parts, an audio probe, and an
IngestDO Durable Object coordinating the session. TUS uploads made
actually resumable. publishDraft made atomic.
Contract discipline in CI — [M-7], [F-10], [CI], [M-3]
openapi.yaml promoted to the single source of truth with generation and
contract tests; an OpenAPI contract for billboard-users enforced in CI;
contract-diff and shadow-type gates; and the first CI Billboard ever had —
typecheck, tests, and a real end-to-end pass on every push.
Moderation, auto-moderation and DMCA — [S-3], [auto-mod], [dmca]
Review-before-playback, report intake, queue, decision, takedown. Then a three-way automated classifier in front of the human queue, with the thresholds, the cost, and what the classifier cannot catch recorded. Then DMCA: expeditious removal, notice, counter-notice, repeat-infringer policy.
Audio fingerprinting — [F-6]
Built kissfft.wasm — the module JamzFingerprintDO had always loaded and
never actually had. A Shazam-style FFT constellation matcher running in a
Durable Object at the edge.
Search and discovery — [F-9], [F-11], [F-4]
Typo-tolerant search; a home surface that leads with what you were doing; the
following feed (empty for every user) fixed along with two unbound
bindings; /v1 contract aliases plus four endpoints that had never existed.
The habit worth showing
Read the commit titles. They are written as claims with evidence:
[F-11] the following feed was empty for every user; fix it and the two unbound bindings[F-5] Remove the fake R2 types, and fix the three bugs they were hiding[F-6] Build kissfft.wasm — the module JamzFingerprintDO loads and never had[seed] fix truncated Stream uids — the seeded catalog would not have playeddocs: record the scope leak and adopt pathspec-scoped commits
That last one is a process failure, caught and corrected in public. Interviewers notice.
Scope
| Metric | Value |
|---|---|
billboard-users Worker | 10,581 lines TypeScript, 65 routes |
| Hardening commits | ~60, numbered against a written gap register |
| Audit manual | 17 chapters + session records |
| D1 tables added | 9 |
| Datastores | D1, R2, KV, Durable Objects, Postgres via Hyperdrive |
| CI gates | typecheck, tests, e2e, contract diff, shadow types |
Interview surface this opens
- Edge compute constraints: no TCP sockets, and how that reshapes architecture
- Durable Objects as single-writer coordinators, and where they bottleneck
- Multipart/resumable upload protocol design and failure recovery
- Contract-first development and how you enforce it mechanically
- Building a gap register and burning it down without breaking live users