Tejas VinayBengaluru

Work 01 AI product MVPs

ARK

A field operations app for adventure racing squads: training telemetry, live timed races and offline maps in one installable PWA.

Platform
Progressive web app
Year
2026
Code
Private repo, code walkthrough on request.
Stack
  • Next.js 16
  • React 19
  • TypeScript
  • MongoDB
  • MapLibre
  • Strava API
  • Gemini
  • Vitest

01 The problem

Expedition adventure racing is run by teams of four over days, not hours. The race ARK was first built around, the Adventure @ Mechukha 2026 ARWS Qualifier, is roughly 450 km and five days non-stop.

Squads training for a race like that juggle seven activity types, a shared gear list and long sessions in places with no signal. Fitness apps track one person's runs. They don't tell a squad that nobody has paddled in a month, and they can't time a checkpoint race in a forest.

02 My role

Sole developer: product, architecture, build, tests and the pre-launch audit.

03 Architecture

A Next.js App Router app on MongoDB, installed as a PWA. Strava activity arrives by webhook. The route acknowledges at once and queues the work instead of doing it inside the request. Jobs live in MongoDB with an idempotency key, a four-minute lease, a priority (a revoked authorisation jumps ahead of new activities) and backoff from one minute to six hours. The Strava client reads the API's rate-limit headers and defers work to the next window instead of failing. OAuth tokens are encrypted with AES-256-GCM before they reach the database.

On race day, every checkpoint punch is checked against a GPS geofence and signed on the server with HMAC-SHA256. Maps run on MapLibre with downloadable tiles, a 1 km UTM grid, magnetic declination and printable topo sheets.

ARK: training sync and race-day punchesTRAINING SYNCRACE DAYStravawebhook eventWebhook routereplies at once,queues afterJob queueMongoDB,idempotency key,4-min leaseSync workerAES-256-GCMtokens, obeys ratelimits, backoff to6 hActivitiesvisible to theowner onlyRacer's phoneoffline punchqueuePunch APIGPS geofence +HMAC-SHA256Resultsprovisional, thenfinalSpectatorswatch-only codeARK: training sync and race-day punchesTRAINING SYNCRACE DAYStravawebhook eventWebhook routereplies at once,queues afterJob queueMongoDB,idempotency key,4-min leaseSync workerAES-256-GCMtokens, obeysrate limits,backoff to 6 hActivitiesvisible to theowner onlyRacer's phoneoffline punchqueuePunch APIGPS geofence +HMAC-SHA256Resultsprovisional, thenfinalSpectatorswatch-only code
the path this case study is about outside the system

04 Two hard decisions

  1. A

    Imported data stays personal

    Strava activities are visible only to the athlete who connected them. Squad feeds, stats and race timing use only data logged in the app.

    That costs some convenience. In exchange, nobody's private runs leak onto a group screen, and nothing imported can change a race result.

  2. B

    Offline punches are never lost or double-counted

    Punches made without signal queue on the device, scoped to the competition and the account, so two people sharing a phone can't flush each other's punches.

    Rejected punches are kept and shown instead of silently dropped, and a page reload can't invalidate a legitimate later punch.

05 The result

pages
30
API routes
51
test files
39
audit defects reproduced
10

A full squad and competition platform over 20 data models, tested with Vitest and database tests on an in-memory MongoDB.

A pre-launch audit reproduced 10 defects in isolated probes. The public-safety and event-day fixes, the first two phases of the roadmap, are done. The rest are scheduled.

The audit also changed the product. The front door became "join our next session", with organiser approval, RSVPs and public event pages, and the squad tools stayed for members.

ARK squad page for a demo squad: target race countdown and a 30-day discipline gap analysisARK navigation training on a phone, listing the Cubbon Park orienteering course

Screens show seeded demo data on local or emulated devices. No real users or records.

Sources: every claim on this page traces to the project-blueprint repo (README.md, ROADMAP.md, lib/strava/jobs.ts, lib/strava/client.ts, lib/strava/crypto.ts, app/api/integrations/strava/webhook/route.ts, lib/competition/crypto.ts, lib/competition/punchQueue.ts, docs/community-audit/AUDIT-2026-09-12.md).

Next case studyContrail