Case study · Rob Murcek2026

Coach Rob

A production, multi-tenant AI running coach — architected, shipped, and operated end-to-end by one engineer directing a fleet of AI agents.

27.5klines shipped
362tests, 4 CI gates
88.6%coverage (85% floor)
33API endpoints
17row-secured tables
3wearable integrations

The product

An AI coach that reads your actual training

Each athlete connects Garmin, Strava, and Oura. The platform ingests every run and every night of sleep, builds a periodized training plan, labels workouts by reading the raw .FIT lap data, generates grade-adjusted race pacing plans from course GPX files, and writes a weekly coaching note. A chat coach answers questions grounded in the athlete's real numbers — not generic advice.

"Solid week — 21.5mi over 3 runs with a clean 10mi long run, and sleep is up to 7.85h/night (score 80.8), which is your best stretch in a month and exactly the lever that lets you build."

Live response from the production coach, grounded in synced wearable data

Live on Fly.io today, invite-gated, coaching real athletes. Born from my own marathon training — the first version coached me to a 3:08 PR — then rebuilt as a multi-tenant platform.

Architecture

Boring infrastructure, sharp boundaries

SourcesGarmin · Strava · Oura
Ingest workerspoll · dedupe · backfill
Postgresrow-level security
Engine + Claudemath · prose
AthleteNext.js · API
Tenant isolation enforced by the database, not the app
Every table carries Postgres row-level security; the API can only see the authenticated tenant's rows. Cross-tenant isolation is proven in CI against a real Postgres on every pull request — not assumed.
Deterministic math, LLM prose — never mixed
Mile splits, pace targets, and workout segmentation are pure, unit-tested functions. The model writes only what language is for: strategy, summaries, coaching judgment. A race plan's splits integrate to the goal time exactly, every time.
Integrations built for the real world
Rate-limit-aware polling with persisted cursors, cross-provider duplicate detection (Garmin wins, athlete edits survive), 12-week history backfill on connect, per-athlete timezone scheduling, and OAuth tokens encrypted at rest with a zero-downtime key rollout path.
Cost-engineered LLM usage
Four-tier prompt caching keeps the shared coaching framework byte-stable across athletes and requests, so most input tokens bill at the ~10% cache-read rate.

Engineering rigor

Nothing merges on vibes

Every pull request clears four independent CI gates before it can land. Deploys run migrations first, then roll the API and web apps; production emits job heartbeats and per-tenant failure alerts to an ops endpoint.

GateWhat it provesScale
Unit + coverageDomain logic — pacing math, lap segmentation, dedupe windows, token crypto — with an enforced coverage floor248 tests · ≥85%
Isolation e2eFull HTTP flows against a real Postgres; row-level security attacked as the unprivileged role100 tests
Contract gateTypeScript API types generated from the OpenAPI schema; any drift between frontend and backend fails the buildgenerated
Browser e2ePlaywright drives signup → connect → dashboard → chat against the built app with a mocked LLMheadless CI

The method

One engineer, an org chart of AI agents

The platform's multi-tenant buildout — three integrations, per-athlete timezones, onboarding, security hardening — shipped in days, not months. The method: I acted as architect and engineering lead over autonomous AI agents with strictly separated roles.

Builder → adversarial reviewer → fix loop
Every feature was implemented by one agent and then attacked by an independent reviewer instructed to execute the code against real data and a real database — not just read it. Confirmed findings went back to the builder with regression tests required.
The reviews earned their keep
Adversarial review caught confirmed production-grade defects before merge, including a cascade-delete that silently destroyed athlete-edited data, a sync cursor that starved dual-provider accounts, and a timezone bug that permanently lagged sleep data for athletes east of UTC+8.
Self-sustaining loop on GitHub Actions
An event-driven "conductor" agent reviews PRs against acceptance criteria, dispatches dev agents per issue, verifies deploys against production health, and journals every decision — with hard rules learned from its own early mistakes written into its charter.

The skill on display isn't typing speed — it's system design, quality-bar enforcement, and knowing exactly what to verify before trusting generated work.

Operations

Run like a real product

Invite-gated signup, secrets in platform vaults, athlete OAuth tokens Fernet-encrypted at rest, ops heartbeats with per-tenant failure surfacing, one-command deploys with automatic migrations, and a documentation set deliberately consolidated to two files — an architecture README and an ops runbook — so a new engineer (or a future me) onboards in one sitting. The codebase was then audited and cut by 5,700+ lines of dead weight before this page was written.

Finish line

Coach Rob is a working demonstration of what I bring to a team: product sense to scope something real, architecture instincts to keep it simple and secure, the operational discipline to run it in production, and fluency in directing AI systems as a force multiplier — with the judgment to verify everything they produce.

Rob Murcek · Engineering leadership & AI systems
Private repository — code walkthrough available on request.

BUILT 2026 · FASTAPI · NEXT.JS · POSTGRES RLS · CLAUDE · FLY.IO · GITHUB ACTIONS