Personal Project · Fitness Dashboard
Apple Health collects the basics, but I wanted the full picture — training, body composition, nutrition, and sleep all in one place, cross-referenced and queryable
Apple Health is great at collecting data, but terrible at helping you do anything with it. It can't tell you how your Tonal strength volume affects your Peloton output the next day, whether your calorie intake on MyFitnessPal is tracking with your body composition changes on the scale, or how your Oura sleep score correlates with your training performance. When you're wearing both an Apple Watch and an Oura Ring, you're also getting overlapping data — duplicate heart rate readings, competing sleep scores, redundant step counts. So I built a system with a custom data mastering layer that pulls raw data from six sources into BigQuery, reconciles the overlaps using source-priority logic, and produces one golden record per event. A lightweight data governance tool lets me dial in source trust rankings, field-level priority rules, and conflict resolution policies — the same concepts enterprises spend millions on, applied to a personal health stack. The dashboard surfaces goal rings, streak tracking, nutrition breakdowns, sleep quality trends, and real cross-domain analysis you can't get anywhere else. The endgame: custom watch complications that replace Apple's fitness rings with my own goal trackers on the watch face, and a full-screen SwiftUI dashboard app one tap away — my own health command center on my wrist.
Click any tab · Mockup data
The /api/dashboard endpoint fires 5 parallel BigQuery queries: daily summary, workouts, body measurements, goals, and trends. Results are cached for 15 minutes to keep sub-second load times.
All workouts from Peloton, Tonal, and Apple Watch synced through HealthKit. Deduplicated on external_id, sortable by date, type, or duration.
| Date | Type | Title | Duration | Calories | Avg HR |
|---|---|---|---|---|---|
| Apr 5, 2026 | ● Peloton | 45-Min Cycling Class | 45 min | 412 | 142 bpm |
| Apr 5, 2026 | ● Tonal | Upper Body Strength | 38 min | 285 | 118 bpm |
| Apr 4, 2026 | ● Peloton | 30-Min Power Ride | 30 min | 298 | 156 bpm |
| Apr 4, 2026 | ● Watch | Evening Run | 22 min | 201 | 162 bpm |
| Apr 3, 2026 | ● Tonal | Lower Body + Core | 42 min | 305 | 125 bpm |
Measurements from Fit Profile smart scale synced daily through HealthKit. Tracked metrics: weight, body fat %, muscle mass, BMI, body water, and basal metabolic rate.
The API automatically calculates percentage complete on every data write. Daily snapshots track progress toward monthly and overall targets.
Pre-aggregated daily and weekly summaries power fast dashboard loads. BigQuery views handle month-over-month comparisons and trend analysis.
How Data Flows
The whole point of this system is that data from six different sources ends up in one place where it can be queried together. Apple Health and direct APIs handle the collection, but BigQuery is where the real analysis happens — joining Peloton ride metrics with Tonal strength data, correlating body composition with MyFitnessPal nutrition logs, layering in Oura sleep and recovery scores, and pre-aggregating daily summaries so the dashboard loads in under a second.
Peloton syncs cycling metrics, Tonal pushes strength data, the Fit Profile scale uploads body composition through HealthKit. MyFitnessPal logs nutrition via its API, and the Oura Ring pushes sleep stages, HRV, and readiness scores through the Oura Cloud API.
Six sources sync on a near real-time 15-minute cadence during waking hours. When Apple Watch and Oura Ring both report heart rate and sleep, the data mastering layer applies source-priority logic — Oura wins for sleep and HRV, Apple Watch wins for active heart rate and workout metrics — and deduplicates on external_id plus time-window matching to produce one golden record per event. A lightweight data governance tool manages source trust rankings and field-level conflict resolution. Watch complications refresh every ~30 minutes via watchOS TimelineReloadPolicy, pulling the latest goal progress, streaks, and scores from the API.
Data lands in partitioned, clustered tables. Daily summaries pre-aggregate for fast reads. Views power the dashboard queries.
The /api/dashboard endpoint fires 5 parallel BigQuery queries. Every write auto-updates streaks, daily summaries, and goal progress.
Next.js frontend renders goal rings, streak bars, workout feeds, and body comp trends. Mobile-first, data-dense, Garmin-inspired.
Every write triggers automatic side effects — daily summary rollups, streak updates, and goal progress checks. But the real differentiator is the data mastering layer: when Apple Watch and Oura Ring both report heart rate and sleep, source trust rankings and field-level governance rules determine which signal wins for each metric. The same master data management concepts that enterprises spend millions implementing — source-of-truth hierarchies, conflict resolution policies, golden record creation — applied to a six-source personal health platform.
System Architecture
Current state plus where it's heading. Use the phase buttons to see how the system evolves.
Tech Stack
8 tables, 3 views, partitioned by date and clustered by source. Pre-aggregated daily summaries for sub-second dashboard loads.
REST API handling data ingestion, dashboard queries, and goal tracking. Auto-updates streaks and summaries on every write. Lives on Railway.
Mobile-first React app with a Garmin-inspired data-dense UI. Goal rings, streak indicators, workout feeds, and body composition charts. Will deploy to Vercel.
One of two integration paths. Peloton, Tonal, and Fit Profile sync through HealthKit for workout and body comp data. MyFitnessPal and Oura connect via their own REST APIs for nutrition and sleep — giving us six sources feeding one warehouse.
Auto-deploys from GitHub on every push to main. Environment variables for GCP credentials, API keys, and CORS config. Health check monitoring built in.
Edge-deployed Next.js with automatic preview deployments on PRs. Same hosting stack as briancronin.ai.
Peloton for cycling and cardio metrics, Tonal for strength training and volume tracking. Both sync through HealthKit, with optional Peloton API enrichment for instructor names and class details.
Smart scale pushing weight, body fat percentage, muscle mass, BMI, body water, bone mass, and basal metabolic rate through HealthKit.
Calorie and macro tracking via the MFP API. Logs meals, snacks, and water intake. Cross-referenced with body composition data to surface whether nutrition is actually driving the results you're seeing on the scale.
Sleep stages (deep, REM, light), HRV trends, readiness scores, and resting heart rate via the Oura Cloud API. The missing piece that connects training load to recovery — so you know when to push and when to pull back.
Monthly and overall goals with daily progress snapshots. The API automatically calculates percentage complete on every data write.
Apple Push Notification service delivering real-time nudges to Apple Watch and iPhone. Streak warnings before you break a run, goal pace alerts when you're slipping, inactivity nudges if you haven't moved by afternoon, and milestone celebrations when you hit PRs. Your own accountability coach on your wrist.
Custom goal ring complications that replace Apple's built-in fitness rings right on the watch face. Your weight, workout, output, and strength goals — glanceable on your wrist 24/7, powered by your own API. One tap opens the full dashboard app.
Full-screen SwiftUI dashboard app — the health command center Apple doesn't make. Goal rings, streaks, sleep score, nutrition summary, and today's training all on your wrist. Talks to the same Railway API that powers the web dashboard — one backend, three frontends (web, watch face, watch app).