Back to Developer Logs

Build Log — March 2, 2026

Build Log — March 2, 2026

What We Shipped

Training Science

  • Banister HR Reserve TRIMP — Replaced the legacy TRIMP formula with the Banister HR Reserve model. Training Load Score is now calculated using heart rate reserve (HRR), which accounts for resting HR and produces more accurate intensity weighting across aerobic and threshold efforts.
  • Garmin LTHR personalization — Training load zones are now seeded from your Garmin Lactate Threshold Heart Rate when available. LTHR-based intensity zones replace the previous generic zone definitions, making CTL/ATL/TSB meaningfully personal.
  • Readiness band on Recovery widget — The Recovery widget now shows a prominent green/yellow/red readiness band at a glance. No more squinting at numbers to know if you're good to go hard.
  • Week start date on metrics charts — Chart x-axis labels now show actual week start dates (e.g. "Mar 2") instead of relative "W1/W2" labels, making it easy to cross-reference with your training calendar.
  • Today's load for Form/TSB display — Fixed a bug where the TSB display was reading from the last array entry instead of today's actual training load entry.
  • 7-day average on HRV and Sleep Score charts — Replaced confusing +/- deltas with a clean 7-day rolling average line on HRV and Sleep Score trend charts.

Platform Integrations

  • AI-generated workout recap at sync — When a workout syncs from Garmin or other platforms, the AI coach now automatically generates a short personalized recap. Athletes get instant context on what they just did — splits, effort, how it fits their training load — without asking.
  • TrainingPeaks import — Added an "Import history from TrainingPeaks" option to the Sync menu. Athletes migrating from TrainingPeaks can now pull their historical workouts directly.
  • Fitbit integration enabled — Fitbit integration card is now live with OAuth credentials configured. The card was previously hidden until credentials were in place; it's now active and ready.
  • Welcome email sequence — New users now receive a welcome email on sign-up. Shipped the full stack: DB table to track sequence state, API route, Supabase auth webhook trigger, and a backfill script for existing users.
  • Automated Garmin backfill script — Added an agent-browser-powered script for automating Garmin historical backfills. Useful for onboarding athletes with years of training history.

Mobile Polish

  • Avatar upload on mobile — Profile photo upload now works from the mobile profile sheet. Avatar persists to Supabase storage and syncs to desktop.
  • How-found-us onboarding prompt — New users see a one-time prompt asking how they found Flow State Endurance. Feeds into acquisition analytics.
  • iOS keyboard fix for coach input — Coach chat input now uses visualViewport to stay above the iOS keyboard instead of getting buried under it.
  • New chat button on mobile coach — Replaced the confusing rotate/clear icon with a clear + (new chat) button. Much more intuitive.
  • Mic → keyboard icon — Replaced mic icons in the coach chat input with keyboard icons. Voice input isn't supported; the mic was misleading.
  • iOS nav bar overlap fix — Navigation bar no longer overlaps content on iOS devices with home indicators.
  • Recovery skeleton loader — Replaced "Loading recovery..." text with an animated skeleton. Feels snappier.

Admin & Infrastructure

  • Agent API column in admin impersonation table — Admin user table now shows an Agent API column, making it faster to grab agent API tokens for debugging.
  • GitHub webhook → Mission Control activity feed — GitHub events (pushes, PRs, deploys) now flow into the Mission Control activity feed, giving the team a unified view of what's shipping.
  • Avatar compression — Profile avatars are now compressed to 256px JPEG before saving. Fixes crashes caused by large base64 payloads exceeding API limits.
  • Google Calendar ID overflow — Long calendar integration IDs no longer break the layout; clipped with overflow-hidden.
  • Export sheet sizing — Export sheet is now taller (85dvh) and main content properly pads when the sheet is open.