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.
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.
04 Two hard decisions
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.
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.


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