Product context
Purpose
I am building a deeply personal predictive coach that helps me break out of negative stress → fitness → nutrition → weight cycles quicker by providing the right guidance at the right time. Proactive, predictive, and encouraging.
Application consolidation (replacing multiple paid apps) is a secondary benefit.
Guiding themes (from recovery run)
- Commitment – show up even when progress is slow.
- Adaptability – adjust to health data, recovery, stress.
- Self-care – value rest, sleep, mental health.
- Forgiveness – reset after missed workouts.
- Presence – focus on the moment.
- Identity – this isn't just logging runs, it's part of who I am.
- Resilience – recover from setbacks.
Stages overview
-
Stage 1: Foundation for Personal Coach — Production-ready base complete, building infrastructure
- Real-time Strava sync via webhooks (<30s latency)
- Normalized split data with accurate distances
- Route thumbnails with OpenStreetMap overlays
- Admin system for monitoring and management
- Performance optimised (95% fewer HTTP requests)
- Enterprise-grade audit trails
- Still need: k8s/GitOps deployment + auth/logging
-
Stage 2: iOS app with Apple HealthKit
- Connect to backend
- Import historical health data (10+ years for cycle prediction)
-
Stage 3: Personal Analytics & Prediction
- Predictive models based on stress, sleep, activity patterns
- Early warning system for negative cycles
- Personal voice coaching and encouragement
-
Stage 4: Holistic Health Integration
- Weight, nutrition, sleep, HRV tracking
- Stress correlation analysis
- Adaptive scheduling based on life circumstances
-
Stage 5: Apple Watch Personal Coach
- Proactive workout suggestions based on schedule gaps
- Real-time coaching in your personal voice
- Music + mood tracking alongside runs
Stage 1 (running).
Who this is for
- People who struggle with fitness cycles — those who recognise patterns of stress derailing their health and want predictive intervention.
- Runners seeking personal coaching — not elite athletes, but people who want intimate support that adapts to their life circumstances.
- Self-hosting enthusiasts — builders who want control over their personal health data and coaching algorithms.
- Long-term health thinkers — people willing to invest in 10+ years of data collection for meaningful predictive insights.
Jobs to be done (Stage 1)
- “Bring my runs together automatically without manual syncs.”
- “Show me trustworthy splits and best efforts with real history, not just top‑20.”
- “Let me filter and export quickly without waiting.”
- “Make it fast and predictable — if something fails, tell me exactly why.”
Value (vs current stack)
- No manual sync steps; Strava → webhook → DB in ~30s.
- Best‑effort rankings beyond top‑20 with time windows (All‑time, 2y, 1y, 3m).
- CSV export that matches what I see.
- Lower ongoing cost by self‑hosting.
Features built (stage 1 foundation)
Authentication & sync
- Database-first OAuth - tokens stored securely in PostgreSQL with enterprise-grade audit trail.
- Robust error handling - graceful OAuth error management with user-friendly messages.
- Secure state validation - CSRF protection with random state parameters.
- Athlete profile integration - automatic name and profile extraction from Strava.
- Automatic token refresh - database-managed refresh with timestamp tracking.
- Real-time webhooks - instant activity sync within 30 seconds of Strava upload.
- Intelligent job queue - webhook-triggered activity fetching with retry logic and rate limiting.
- Advanced sync filters - date range, thresholds, force updates, and activity limits.
- Multi-user ready - unique athlete ID storage for future expansion.
- Cross-device authentication - authenticate once, use everywhere via database persistence.
- Safari/mobile compatibility - automatic fallback for restrictive cookie environments.
- Background polling fallback - periodic sync as backup to webhooks.
- Configurable sync threshold - customise when auto-sync stops (5, 10, 20+ activities).
- Backup integration - tokens included in database backups.
- Pure database architecture - no legacy file dependencies or fallbacks.
Smart thumbnails
- Automatic generation - background worker creates thumbnails for all activities.
- OpenStreetMap integration - beautiful route previews with map backgrounds.
- Optimized caching - fast loading with intelligent cache headers.
- Integrated preview - thumbnails displayed inline with activity cards.
- Space-optimised design - compact 56x56px thumbnails for mobile-first layout.
Mobile-first interface
- Mobile-first design - responsive dark theme interface with clean, professional aesthetics.
- Intelligent slide-out menu - dynamic menu with connection-aware functionality.
- One-tap navigation - entire activity rows are clickable for instant access.
- Optimized spacing - full-width tiles with minimal gaps for maximum screen utilisation.
- Clean activity cards - distance, elevation, duration, and pace in compact format.
- Real-time activity count - dynamic count display in top navigation bar.
Smart menu system
- Connection-aware interface - menu adapts based on Strava authentication status.
- Dynamic button states - Connect/Disconnect buttons change automatically.
- Intelligent feature access - sync disabled when offline, analytics always available.
- Athlete identification - displays "Connected as athlete [Name]" when authenticated.
- Instant status updates - menu refreshes connection state after auth changes.
- Local data access - Analytics and CSV export work independently of Strava connection.
- Integrated webhook management - built-in Subscription admin interface for webhook control.
Advanced webhook management
- Real-time subscription monitoring - view active webhook subscriptions directly in-app.
- One-click webhook creation - automatically configure webhooks with your environment settings.
- Intelligent UI adaptation - interface adapts based on subscription status (0 or 1 webhook).
- Individual subscription control - delete specific webhook subscriptions with confirmation.
- Automatic cleanup on disconnect - webhooks are automatically removed when disconnecting from Strava.
- Smart caching system - database-backed caching with 5-minute TTL for instant UI response.
- Cache performance indicators - shows "(cached)" vs "(live)" status in subscription interface.
- Force refresh capability - bypass cache for real-time Strava API verification.
- Athlete relationship tracking - maintains audit trail of webhook creators while respecting app-wide nature.
- Error handling & recovery - graceful handling of webhook API failures with detailed logging.
- Strava IP whitelist documentation - comprehensive guide for firewall and ngrok configuration.
Detailed activity pages
- Professional dark theme - clean card-based design optimised for mobile running apps.
- Perfect header alignment - "Details" text precisely centered in screen with absolute positioning.
- Enhanced map thumbnails - 72×72px thumbnails (50% larger) for better route visibility.
- Unified typography - consistent 18px font size throughout with strategic 14px date subtitle.
- Minimal font hierarchy - only activity name is bold, everything else uses regular weight.
- Australian date format - "Wednesday, 17 September 2025 at 19:04" with 24-hour time.
- Comprehensive metrics - logically organised cards for different data types.
- Full-page splits view - dedicated splits page with proper column structure (Lap, Distance, Duration, Pace, HR).
- Accurate split data - real distance (0.08 km) and duration (0:38) from normalised database storage.
- Dark theme optimisation - black background with grey-800 cards and white text.
- Reduced spacing - compact padding (px-3 py-2) and margins (mb-2) for mobile efficiency.
- Smart conditional display - only shows relevant metrics (hides missing HR/cadence data).
- Preserved accent colors - blue "Show on Strava" links maintained for brand consistency.
- Perfect content alignment - content edges precisely match header navigation elements.
Analytics & performance
- Peak Performance Tracking - identify your best efforts across multiple distances (400m to marathon).
- GPS-based best efforts - TrainingPeaks-level accuracy using time-series data with advanced smoothing.
- Pre-calculated metrics - best efforts stored in BestEffort database table for instant access.
- Advanced algorithms - rolling median filtering, Gaussian smoothing, and hybrid GPS analysis.
- Comprehensive distance coverage - 400m, 800m, 1km, 5km, 10km, half marathon, marathon.
- Real-time calculation optimisation - analytics computed once during activity import, not on-demand.
- Per-km splits - detailed pace analysis with elevation and heart rate data.
- Leaderboard rankings - position and percentile tracking across all activities.
- Distance filtering - separate analytics for different race distances.
Performance optimizations
- Lazy loading thumbnails - thumbnails load only when visible in viewport using Intersection Observer API.
- Eliminated unnecessary requests - removed 40+ map requests on page load (95% reduction in initial HTTP requests).
- Smart caching - comprehensive HTTP caching with proper stale-while-revalidate headers.
- Progressive image loading - 50px preload margin with automatic observer cleanup.
- Background workers - 3 concurrent processes for optimal performance.
- Intelligent sync - only processes new activities, skips existing ones automatically.
- Early termination - stops sync when 20+ consecutive existing activities found.
- Database optimisation - efficient queries with field selection and proper indexing.
- Large field protection - automatic exclusion of heavy database fields (raw JSON, thumbnails).
- Pre-calculated analytics - best efforts computed once and stored for instant retrieval.
- Streamlined UI - removed unused features and optimised for mobile performance.
- Response time monitoring - sub-50ms API responses.
- Efficient data storage - normalised split data with proper distance and timing fields.
Code quality and documentation
- Lint error resolution - clean codebase with all TypeScript and ESLint errors resolved.
- Documentation validation - automated script (npm run docs:check) to ensure docs stay in sync with codebase.
What good looks like (stage 1)
< Core functionality achieved.
- New activity shows up in < 30s — webhook system working.
- Thumbnails render reliably; worker auto‑recovers — background processing complete.
- Splits match Strava's moving time/distance; HR shown when present — normalised data model.
- Best efforts and rankings are explainable (no "magic") — GPS analysis infrastructure ready.
- Feed is snappy; filters persist; CSV is instant — performance optimised
- API p95 < 50ms on core routes — measured and achieved.
Out (for now)
- iOS + Apple HealthKit (stage 2).
- Health metrics (stage 3).
- Food tracking (stage 4).
- Apple Watch capture + music (stage 5).
Personas (lightweight)
- Self‑hosted runner — wants control, hates subscriptions, okay with DIY.
- Pragmatic improver — still uses NRC/Strava socially, wants better analysis.
- Builder‑learner — follows the series and reuses the stack for their own idea.
Principles
- Be honest about errors; make recovery obvious.
- Never fabricate splits or “magic” pace.
- Store as little as possible; keep secrets encrypted.
- Prefer speed and clarity over cleverness.
Future vision: personal predictive coach
The foundation being built in stage 1 is designed to support something far more personal:
- Historical data import (10+ years) to understand long-term patterns.
- Predictive analytics that identify stress cycles before they impact fitness.
- Adaptive coaching that adjusts to your life circumstances.
- Personal voice that encourages like your inner dialogue.
- Proactive scheduling that finds opportunities in busy periods.
- Holistic view connecting fitness, nutrition, sleep, stress, and weight.
This isn't just an app. It's a personal predictive coach that knows you intimately.
How stage 1 enables this vision
- Stable infrastructure for handling complex health data streams.
- Real-time processing for immediate coaching responses.
- Audit trails for tracking what interventions work.
- Performance optimisation for responsive mobile coaching.
- Database foundation for storing years of personal history.