Skip to main content
Back to selected work

Case study

Horrorometer

A horror-focused discovery and rating platform where fans track, rate, and surface scary movies, TV shows, and books. It scores titles on three genre-specific axes — Creepy, Gory, and Jumpy — instead of a single star rating, so fans can find what actually matches their taste.

Horrorometer product interface
My role
Sole engineer, end-to-end: product design, frontend build, backend/API architecture, database design, authentication, rate limiting and resilience patterns, Cloudflare Workers deployment, and observability setup.
Year / status
2025 · Live product

01 — The challenge

One number can't describe a scare.

General-purpose rating sites flatten horror into one number. A slow-burn atmospheric film and a gorefest score the same 3.5 stars, so fans can't find what actually matches their taste. Horrorometer gives each title a multi-axis profile and lets users build watchlists and favorites around the kind of scare they want.

02 — The approach

Architecture, resilience, then interface.

Architecture first: defined the API surface before UI — file-based Next.js routes for primary resources, dedicated proxy routes with circuit breakers for TMDB and Open Library, and a legacy catch-all that redirects to the new routes. Resilience by default: external calls run through a circuit breaker (5 failures / 60s → 30s open, 2 successes to close) with 3-attempt exponential backoff, plus a graceful-degradation layer that returns cached/empty data when upstreams fail so the UI never hard-errors on a TMDB outage. Security hardening through two formal audits (2026-05-28 and 2026-06-27) drove 31 audit cards to done: CSRF on ~18 admin mutation routes, Zod enum validation on role escalation paths, fail-open rate limiting so a DB outage can't block all traffic, and PII-scrubbed Sentry breadcrumbs. Auth uses Firebase client-side with JWT verification in API routes, generic error messages to prevent info leakage, CSRF tokens with cleanup, and a 60s password-reset cooldown to prevent email enumeration. Edge-native deploy on Cloudflare Workers via @opennextjs/cloudflare, with three post-build patch scripts to make Next.js 16 run on the Workers runtime. Testing covers Jest unit coverage (migrating to Vitest), Playwright E2E with dedicated auth-flow suites, and 20 state-machine tests for OAuth device-flow race conditions.

03 — The outcome

A resilient, audited, live product.

Shipped to production on Cloudflare Workers with real users. 31 audit cards closed across two security/architecture audits covering rate limiting, CSRF, info-leakage, circuit breakers, and observability. RFC 8628 OAuth device flow implemented end-to-end (code issuance, authorize, token, polling, revocation) with compare-and-swap state transitions and full race-condition test coverage. External watchlist API with Bearer-token watchlist scope, plus read-only monitor-scope admin endpoints for external agents. Two cron routes (hourly prune, nightly inactivity sweep) with optional CRON_SECRET gating. Observability in place: Sentry with PII scrubbing, 10% production perf sampling, plus liveness and readiness health endpoints.

More work

Keep exploring.