Skip to content

Track 1: MVP Tasks

Deadline: March 20, 2026 Tasks: 242 (235 original + 7 Gorillas) Repos: backend-api, athion-sdk, app-user, app-device, coach-app, champion-stats-hub Devices: X3B Ring, JVC Band, Godzilla Station, Gorillas (arriving Mar 30) Status tracking: [ ] To Do | [~] In Progress | [x] Done

Branch Naming Convention

  • Backend API: feature/BE-XXX-short-description
  • SDK: feature/SDK-XXX-short-description
  • App User: feature/AU-XXX-short-description
  • App Device: feature/AD-XXX-short-description
  • Coach App: feature/CA-XXX-short-description
  • Web: feature/WEB-XXX-short-description
  • Gorillas: feature/GOR-XXX-short-description

Progress

Section Total Done %
Backend API (BE-001..072) 72 0 0%
SDK (SDK-001..025) 25 0 0%
App User (AU-001..068) 68 0 0%
App Device (AD-001..018) 18 0 0%
Coach App (CA-001..021) 21 0 0%
Web (WEB-001..031) 31 0 0%
Gorillas (GOR-001..007) 7 0 0%
Total 242 0 0%

Backend API

Repo: backend-api Timeline: Mar 6 — Mar 16

1.1 Device Sync — Deduplication

ID Task Repo Branch Status Done When
BE-001 Add unique constraint on (user_id, device_id, metric_type, measured_at) in health_metrics table backend-api feature/BE-001-health-metrics-unique-constraint [ ] Migration runs. Inserting a duplicate row returns a DB conflict error instead of creating a second row
BE-002 Handle conflict in POST /devices/{id}/sync — on duplicate, skip row and count it backend-api feature/BE-002-sync-dedup-handling [ ] Sync handler uses ON CONFLICT DO NOTHING. Response body includes { inserted: N, skipped: M }. Test: send same 10 data points twice → first call inserts 10, second call inserts 0, skipped 10
BE-003 Add integration test for dedup sync backend-api feature/BE-003-dedup-integration-test [ ] Test in tests/ sends 50 metrics, then sends same 50 again. Asserts DB has exactly 50 rows. Test passes in CI

1.2 Device Sync — Bulk Validation

ID Task Repo Branch Status Done When
BE-004 Add field-level validation to POST /health/metrics/bulk backend-api feature/BE-004-bulk-field-validation [ ] HR outside 20-300 → rejected. SpO2 outside 0-100 → rejected. Steps < 0 → rejected. Response: 422 with array of { field, value, error } per invalid item
BE-005 Partial success support — valid rows inserted, invalid rows returned backend-api feature/BE-005-partial-success-support [ ] Send 10 metrics where 2 are invalid → 8 inserted, response includes { inserted: 8, errors: [{index: 3, ...}, {index: 7, ...}] }
BE-006 Add validation tests for all metric types backend-api feature/BE-006-metric-validation-tests [ ] Tests cover: heart_rate, spo2, steps, sleep_duration, temperature, hrv. Each has min/max boundary test

1.3 Device Sync — Status Tracking

ID Task Repo Branch Status Done When
BE-007 Update last_sync_at on device after successful sync backend-api feature/BE-007-update-last-sync-at [ ] After POST /devices/{id}/sync returns 200, query user_devices row → last_sync_at is within 2 seconds of now
BE-008 Set connection_status = 'connected' on sync backend-api feature/BE-008-connection-status-on-sync [ ] After sync, device status = "connected". GET /devices/{id} confirms
BE-009 Add DB trigger or cron: set connection_status = 'disconnected' after 30 min idle backend-api feature/BE-009-auto-disconnect-idle [ ] Device syncs at T=0. At T=31 min (no new sync), status auto-changes to "disconnected". Verify with query
BE-010 Add sync_count column to user_devices — increment on each sync backend-api feature/BE-010-sync-count-column [ ] Migration adds column default 0. Each POST /devices/{id}/sync increments by 1. GET /devices/{id} returns sync_count

1.4 Device Registration

ID Task Repo Branch Status Done When
BE-011 Fix POST /devices upsert — same device_identifier updates existing row backend-api feature/BE-011-device-upsert-fix [ ] Register device with MAC AA:BB:CC. Register again with same MAC but new firmware_version → existing row updated, no new row created. Returns the updated device
BE-012 Return is_new: true/false in registration response backend-api feature/BE-012-is-new-response-flag [ ] First registration returns is_new: true. Re-registration returns is_new: false. Frontend can show different UI
BE-013 Add device_type detection from name — "X3B" → ring, "JVC" → band backend-api feature/BE-013-device-type-detection [ ] POST /devices with name containing "X3B" auto-sets device_type = "ring". Name containing "JVC" → device_type = "band". Others → device_type = "unknown"

1.5 Historical Backfill

ID Task Repo Branch Status Done When
BE-014 Increase payload limit on POST /devices/{id}/sync to accept 5000 data points backend-api feature/BE-014-increase-sync-payload-limit [ ] Send 5000-item array → 200 OK, all inserted. Send 5001 → 413 Payload Too Large with clear error message
BE-015 Add is_backfill: bool flag to sync request backend-api feature/BE-015-backfill-flag [ ] When is_backfill: true, skip real-time alerts (don't fire abnormal HR notification for old data). Test: backfill with HR=200 from last week → no push notification sent
BE-016 Track backfill progress in user_devices.meta backend-api feature/BE-016-backfill-progress-tracking [ ] During backfill, meta shows { backfill_status: "in_progress", backfill_start: "...", points_received: N }. After completion: { backfill_status: "complete" }

1.6 Health Summary API

ID Task Repo Branch Status Done When
BE-017 Fix GET /health/summary — aggregate steps as SUM, HR as AVG for given date backend-api feature/BE-017-fix-health-summary-aggregation [ ] Insert 3 step records (1000, 2000, 3000) for today. GET /health/summary?date=today returns steps: 6000. Insert 3 HR records (60, 80, 100) → returns avg_heart_rate: 80
BE-018 Add sleep duration to summary — sum sleep stages backend-api feature/BE-018-sleep-duration-summary [ ] Summary includes sleep_duration_minutes, sleep_score, sleep_deep_minutes, sleep_rem_minutes. Values match raw health_metrics sleep records for that night
BE-019 Add calories and active_minutes to summary backend-api feature/BE-019-calories-active-minutes [ ] Summary includes total_calories (sum), active_minutes (sum). Test with known data verifies accuracy
BE-020 Handle empty data gracefully — return nulls, not errors backend-api feature/BE-020-empty-data-graceful [ ] GET /health/summary?date=2020-01-01 (no data) returns 200 with all fields null and has_data: false. Not 404 or 500

1.7 Health Dashboard API

ID Task Repo Branch Status Done When
BE-021 Implement readiness score calculation backend-api feature/BE-021-readiness-score [ ] GET /health/dashboard returns readiness_score: 0-100 based on last night sleep + resting HR + HRV. Formula documented in code comment. Returns null with reason when <3 days data
BE-022 Implement strain score calculation backend-api feature/BE-022-strain-score [ ] Dashboard returns strain_score: 0-21 based on HR zones during activities. Matches documented formula
BE-023 Implement recovery score calculation backend-api feature/BE-023-recovery-score [ ] Dashboard returns recovery_score: 0-100 based on HRV, resting HR, sleep quality. Returns null when insufficient data
BE-024 Add trend arrows — compare today vs yesterday backend-api feature/BE-024-trend-arrows [ ] Each score includes trend: "up" | "down" | "stable" and trend_delta: number. Delta = today - yesterday

1.8 Sleep Analysis API

ID Task Repo Branch Status Done When
BE-025 GET /health/metrics?metric_type=sleep returns structured sleep data backend-api feature/BE-025-structured-sleep-data [ ] Response includes: sleep_score, total_duration, time_in_bed, sleep_efficiency, stages: { awake, light, deep, rem } as minutes. Matches raw data from device sync
BE-026 Add 7-day sleep trend endpoint — GET /health/sleep/trend?days=7 backend-api feature/BE-026-sleep-trend-endpoint [ ] Returns array of 7 objects with date, score, duration, deep_minutes. Missing nights return null entry (not omitted)
BE-027 Sleep insights text generation backend-api feature/BE-027-sleep-insights [ ] Sleep response includes insights: string[] e.g., ["Your deep sleep increased 15% this week", "You went to bed 45 min later than usual"]. At least 1 insight when >3 nights data

1.9 Activity Metrics API

ID Task Repo Branch Status Done When
BE-028 Daily activity rollup — GET /health/activity?date=... backend-api feature/BE-028-daily-activity-rollup [ ] Returns { steps, distance_km, calories, active_minutes, floors } summed for the day. Verified against raw records
BE-029 Weekly activity rollup — GET /health/activity?period=weekly backend-api feature/BE-029-weekly-activity-rollup [ ] Returns array of 7 daily summaries + weekly_total object with sums. Sunday=0 convention
BE-030 Monthly activity rollup — GET /health/activity?period=monthly backend-api feature/BE-030-monthly-activity-rollup [ ] Returns array of daily summaries for current month + monthly_total. Days without data show nulls

1.10 Health Insights API

ID Task Repo Branch Status Done When
BE-031 Pattern detection — correlate sleep with next-day HRV backend-api feature/BE-031-pattern-detection [ ] GET /health/insights with 14+ days data returns patterns like { type: "correlation", metrics: ["sleep_duration", "hrv"], description: "...", confidence: 0.82 }
BE-032 Return empty array (not error) when insufficient data backend-api feature/BE-032-empty-insights-graceful [ ] User with 0 days data → GET /health/insights returns { patterns: [], message: "Need at least 7 days of data" }. 200 status
BE-033 Anomaly detection — flag unusual readings backend-api feature/BE-033-anomaly-detection [ ] Insights include anomalies: { type: "anomaly", metric: "resting_hr", description: "Resting HR 15% higher than your baseline", date: "..." }

1.11 Coach-Client Permissions

ID Task Repo Branch Status Done When
BE-034 Enforce can_view_health flag on health endpoints backend-api feature/BE-034-enforce-can-view-health [ ] Coach calls GET /coach/clients/{id}/health/summary with can_view_health=false in permissions → 403. With true → 200 with data
BE-035 Enforce can_view_body flag on body endpoints backend-api feature/BE-035-enforce-can-view-body [ ] Same pattern for GET /coach/clients/{id}/body. 403 when denied, 200 when allowed
BE-036 Enforce can_view_workouts flag on training endpoints backend-api feature/BE-036-enforce-can-view-workouts [ ] Same pattern for GET /coach/clients/{id}/training
BE-037 Enforce can_view_food flag on nutrition endpoints backend-api feature/BE-037-enforce-can-view-food [ ] Same pattern for GET /coach/clients/{id}/food
BE-038 Enforce can_view_devices flag on device endpoints backend-api feature/BE-038-enforce-can-view-devices [ ] Same pattern for GET /coach/clients/{id}/devices
BE-039 Enforce can_view_goals flag on goals endpoints backend-api feature/BE-039-enforce-can-view-goals [ ] Same pattern for GET /coach/clients/{id}/goals
BE-040 Integration test for all 6 permission flags backend-api feature/BE-040-permissions-integration-test [ ] Single test creates coach-client relationship, tests all 6 flags with true/false. All assertions pass

1.12 Live Session Lifecycle

ID Task Repo Branch Status Done When
BE-041 POST /coach/sessions — create session with validation backend-api feature/BE-041-create-session [ ] Creates session with title, scheduled_at (future), duration_minutes, price, max_participants. Returns session with status="scheduled". Past date rejected with 422
BE-042 PUT /sessions/{id}/start — transition to live backend-api feature/BE-042-start-session [ ] Only session owner (coach) can start. Status changes "scheduled" → "live". started_at set to now. Starting already-live session returns 409
BE-043 POST /sessions/{id}/join — add participant backend-api feature/BE-043-join-session [ ] User joins live session. SessionParticipant created with joined_at. Max participants enforced → 409 when full. Only live sessions joinable
BE-044 PUT /sessions/{id}/end — complete session backend-api feature/BE-044-end-session [ ] Status "live" → "ended". ended_at set. All participants get left_at = now. Duration calculated. Ending non-live session returns 409
BE-045 POST /sessions/{id}/reserve — book a spot with payment backend-api feature/BE-045-reserve-session [ ] Creates reservation with transaction_id. Deducts from wallet. Reservation count < max_participants enforced. Double-reservation returns 409

1.13 Agora Token Generation

ID Task Repo Branch Status Done When
BE-046 POST /agora/token generates valid RTC token backend-api feature/BE-046-agora-token-generation [ ] Returns { token, channel, uid, expires_at }. Token is valid Agora RTC token string. Expiry = session duration + 30 min
BE-047 Validate session exists and user is participant backend-api feature/BE-047-agora-session-validation [ ] Request with invalid session_id → 404. User not participant/coach of session → 403. Valid participant → token generated

1.14 Coach Managed Clients

ID Task Repo Branch Status Done When
BE-048 POST /coach/managed-clients — create offline client backend-api feature/BE-048-create-managed-client [ ] Coach creates client with name, email (optional), phone (optional), goals, notes. Returns managed client with generated ID. Only coaches can call this
BE-049 GET /coach/managed-clients — list all managed clients backend-api feature/BE-049-list-managed-clients [ ] Returns paginated list of coach's managed clients with last_activity_at. Supports search by name
BE-050 PUT /coach/managed-clients/{id} — update client info backend-api feature/BE-050-update-managed-client [ ] Update name, goals, notes. Only owning coach can edit. Returns updated client
BE-051 DELETE /coach/managed-clients/{id} — soft delete backend-api feature/BE-051-delete-managed-client [ ] Sets deleted_at. Client no longer appears in list. Data preserved for audit
BE-052 POST /coach/managed-clients/{id}/metrics — log health data for client backend-api feature/BE-052-managed-client-metrics [ ] Coach logs weight, body fat, measurements for managed client. Stored in health_metrics with source=coach_entry. Client's health summary includes this data

1.15 Coach Portal Endpoints

ID Task Repo Branch Status Done When
BE-053 Intake forms CRUD — POST/GET/PUT/DELETE /coach/portal/intake-forms backend-api feature/BE-053-intake-forms-crud [ ] Coach creates intake form template. Assigns to client. Client fills it out. Coach views responses. All 4 operations return 200
BE-054 Client journey — GET /coach/portal/clients/{id}/journey backend-api feature/BE-054-client-journey [ ] Returns chronological timeline: sessions attended, metrics logged, check-ins, notes. Paginated. Empty for new clients
BE-055 Messaging — POST/GET /coach/portal/messages backend-api feature/BE-055-portal-messaging [ ] Coach sends message to client. Client retrieves messages. Thread-based. Unread count included. Real-time via polling (not WebSocket)
BE-056 Billing — POST/GET /coach/portal/billing backend-api feature/BE-056-portal-billing [ ] Coach creates invoice for client. Lists billing history. Integrates with wallet for payment
BE-057 Notes — POST/GET/PUT/DELETE /coach/portal/clients/{id}/notes backend-api feature/BE-057-portal-notes [ ] Coach creates private notes on client. Notes searchable, timestamped, editable. Only visible to owning coach

1.16 Push Notifications

ID Task Repo Branch Status Done When
BE-058 POST /push/register — store FCM token per device backend-api feature/BE-058-push-register [ ] Stores token with user_id and device_identifier. Duplicate token updates existing row. Returns 201 on create, 200 on update
BE-059 DELETE /push/{token} — invalidate token backend-api feature/BE-059-push-invalidate [ ] Token marked inactive. Future push to this token skipped. Returns 204
BE-060 FCM send function — deliver push via Firebase backend-api feature/BE-060-fcm-send [ ] Internal push::send(user_id, title, body, data) function finds all active tokens for user, sends via FCM API. Returns count of successful deliveries
BE-061 Health alert notification — abnormal HR/SpO2 backend-api feature/BE-061-health-alert-push [ ] When sync receives HR > 180 or HR < 40 or SpO2 < 90 (not backfill), push sent: "Abnormal heart rate detected: 185 bpm". Logged in notifications table
BE-062 Session reminder notification — 30 min before backend-api feature/BE-062-session-reminder-push [ ] Background job checks sessions starting in 30 min. Sends push to all participants + coach. Idempotent: won't send twice for same session
BE-063 Sync reminder notification — no sync in 24h backend-api feature/BE-063-sync-reminder-push [ ] Background job checks users with devices but no sync in 24h. Sends push: "Your [Ring/Band] hasn't synced in a while. Open the app to sync." Once per day max

1.17 GPS Activity Tracking (Running/Cycling)

ID Task Repo Branch Status Done When
BE-064 Create activities table migration backend-api feature/BE-064-activities-table [ ] Table: id, user_id, activity_type (enum: run, cycle, walk, hike, swim, other), started_at, ended_at, duration_seconds, distance_meters, avg_pace_sec_per_km, avg_speed_kmh, calories, elevation_gain_meters, elevation_loss_meters, avg_heart_rate, max_heart_rate, route (JSONB — array of {lat, lng, alt, timestamp}), summary (JSONB), source (app, device, import), meta (JSONB), created_at. Index on (user_id, activity_type, started_at)
BE-065 POST /activities — save completed activity with GPS route backend-api feature/BE-065-save-activity [ ] Accepts full activity object including route points array. Validates: distance > 0, duration > 0, route has >=2 points. Calculates avg_pace and avg_speed if not provided. Returns activity with ID
BE-066 GET /activities — list user activities backend-api feature/BE-066-list-activities [ ] Returns paginated list: id, type, date, distance, duration, pace, calories. Filter by activity_type, date range. Sort by date desc. Route NOT included in list (too large)
BE-067 GET /activities/{id} — get activity detail with route backend-api feature/BE-067-activity-detail [ ] Returns full activity including route points array. Used for map display
BE-068 DELETE /activities/{id} — delete activity backend-api feature/BE-068-delete-activity [ ] Soft delete. Returns 204
BE-069 GET /activities/stats — activity summary stats backend-api feature/BE-069-activity-stats [ ] Returns: total_distance (all time), total_activities, this_week_distance, this_month_distance, longest_run, fastest_pace, total_elevation. Filter by activity_type
BE-070 Live activity endpoint — POST /activities/live — save GPS point during activity backend-api feature/BE-070-live-activity-points [ ] Accepts single GPS point {lat, lng, alt, timestamp, heart_rate}. Appends to in-progress activity. For real-time tracking. Batched: accepts array of up to 50 points
BE-071 POST /activities/start — begin live activity backend-api feature/BE-071-start-live-activity [ ] Creates activity with status=in_progress. Returns activity ID. Client sends GPS points to /activities/live
BE-072 POST /activities/{id}/finish — complete live activity backend-api feature/BE-072-finish-live-activity [ ] Sets status=completed, ended_at=now. Calculates: total distance from route points, avg pace, elevation gain/loss, calories (from HR + distance + weight). Returns completed activity summary

Athion SDK

Repo: athion-sdk Timeline: Mar 6 — Mar 16

1.17 Buddy Service (0/23 endpoints)

ID Task Repo Branch Status Done When
SDK-001 Buddy challenge CRUD — create, list, get, update, delete athion-sdk feature/SDK-001-buddy-challenge-crud [ ] 5 methods in BuddyService. Each method sends correct HTTP request, returns typed model. Compiles without errors
SDK-002 Buddy matching — find, request, accept, reject athion-sdk feature/SDK-002-buddy-matching [ ] 4 methods for buddy discovery and matching. Request/response types match backend API contract
SDK-003 Buddy messaging — send, list messages, mark read athion-sdk feature/SDK-003-buddy-messaging [ ] 3 methods. Message model includes sender_id, content, timestamp, read status
SDK-004 Buddy sessions — create, join, leave, complete athion-sdk feature/SDK-004-buddy-sessions [ ] 4 methods for shared workout sessions. Session model matches backend schema
SDK-005 Buddy stats and leaderboard — get stats, rankings athion-sdk feature/SDK-005-buddy-stats [ ] 3 methods for buddy pair statistics. Remaining endpoints covered. Total = 23 methods
SDK-006 Buddy models — all request/response types athion-sdk feature/SDK-006-buddy-models [ ] BuddyChallenge, BuddyMatch, BuddyMessage, BuddySession, BuddyStats models in lib/src/models/buddy.dart. All have fromJson/toJson

1.18 Coach Managed Clients (0/13 endpoints)

ID Task Repo Branch Status Done When
SDK-007 Managed client CRUD — create, list, get, update, delete athion-sdk feature/SDK-007-managed-client-crud [ ] 5 methods in ManagedClientService. Typed models for ManagedClient
SDK-008 Managed client health — log metrics, get summary, get history athion-sdk feature/SDK-008-managed-client-health [ ] 3 methods. Coach can post metrics and retrieve them. Matches BE-052 contract
SDK-009 Managed client notes and progress — notes CRUD, progress tracking athion-sdk feature/SDK-009-managed-client-notes [ ] 5 methods. CRUD for notes + progress milestone tracking
SDK-010 Managed client models athion-sdk feature/SDK-010-managed-client-models [ ] ManagedClient, ManagedClientMetric, ManagedClientNote models with serialization

1.19 Coach Portal (0/46 endpoints)

ID Task Repo Branch Status Done When
SDK-011 Intake service — form templates CRUD, assign, get responses athion-sdk feature/SDK-011-intake-service [ ] 6 methods in CoachIntakeService. Compiles, types match backend
SDK-012 Journey service — get timeline, add event athion-sdk feature/SDK-012-journey-service [ ] 3 methods in CoachJourneyService
SDK-013 Messaging service — send, list threads, list messages, mark read athion-sdk feature/SDK-013-messaging-service [ ] 5 methods in CoachMessagingService
SDK-014 Notes service — CRUD athion-sdk feature/SDK-014-notes-service [ ] 4 methods in CoachNotesService
SDK-015 Sessions service — CRUD, manage participants athion-sdk feature/SDK-015-sessions-service [ ] 6 methods in CoachSessionsService
SDK-016 Locations service — CRUD for training locations athion-sdk feature/SDK-016-locations-service [ ] 4 methods in CoachLocationsService
SDK-017 Billing service — create invoice, list, get, mark paid athion-sdk feature/SDK-017-billing-service [ ] 5 methods in CoachBillingService
SDK-018 Payouts service — request, list, get status athion-sdk feature/SDK-018-payouts-service [ ] 4 methods in CoachPayoutsService
SDK-019 Campaigns service — create, list, update, delete, get stats athion-sdk feature/SDK-019-campaigns-service [ ] 5 methods in CoachCampaignsService
SDK-020 Analytics service — revenue, clients, sessions, retention athion-sdk feature/SDK-020-analytics-service [ ] 4 methods in CoachAnalyticsService
SDK-021 Coach portal models — all request/response types athion-sdk feature/SDK-021-coach-portal-models [ ] All models for portal services in lib/src/models/coach_portal.dart. Total 46 endpoints covered

1.20 Circles Completion (15/20 → 20/20)

ID Task Repo Branch Status Done When
SDK-022 Circle challenges — create, list, join, leave, complete athion-sdk feature/SDK-022-circle-challenges [ ] 3 missing challenge methods added. Total challenge coverage complete
SDK-023 Circle milestones and activities — remaining endpoints athion-sdk feature/SDK-023-circle-milestones [ ] 2 missing methods added. All 20 circle endpoints now covered. Existing tests still pass

1.21 Activity / GPS Service

ID Task Repo Branch Status Done When
SDK-024 Add ActivityService — CRUD for GPS activities athion-sdk feature/SDK-024-activity-service [ ] Methods: startActivity(type), sendLivePoints(id, points), finishActivity(id), saveActivity(activity), listActivities(filters), getActivity(id), deleteActivity(id), getStats(type). All typed
SDK-025 Add activity models athion-sdk feature/SDK-025-activity-models [ ] Activity, GpsPoint, ActivityStats, ActivitySummary models with fromJson/toJson

App User

Repo: app-user Timeline: Mar 6 — Mar 20 (parallel with backend)

1.21 BLE Auto-Reconnect

ID Task Repo Branch Status Done When
AU-001 Add reconnect logic in ble_manager.dart — retry connection on disconnect app-user feature/AU-001-ble-auto-reconnect [ ] When onDisconnected fires, start retry loop: attempt reconnect every 5s for up to 2 min. Log each attempt
AU-002 Show reconnecting UI state in device_screen.dart app-user feature/AU-002-reconnecting-ui [ ] Device screen shows "Reconnecting..." with spinner during retry. Shows "Connected" on success, "Disconnected" with manual reconnect button after timeout
AU-003 Test: toggle Bluetooth off/on → app reconnects within 30s app-user feature/AU-003-ble-reconnect-test [ ] Manual test on iOS and Android. Document in test notes. Both pass

1.22 BLE Background Sync

ID Task Repo Branch Status Done When
AU-004 iOS: configure CBCentralManager for background BLE restoration app-user feature/AU-004-ios-background-ble [ ] Add bluetooth-central to Info.plist UIBackgroundModes. BleService uses restoreIdentifier. App resumes BLE after system kills it
AU-005 Android: create foreground service for BLE sync app-user feature/AU-005-android-foreground-service [ ] AndroidManifest.xml declares foreground service. Notification shows "Syncing health data". Service runs when app backgrounded
AU-006 Sync data to backend while backgrounded app-user feature/AU-006-background-sync [ ] Background: BLE receives data → batches locally → posts to POST /devices/{id}/sync every 5 min. Test: background app, wait 1 hour, open app → data from that hour visible

1.23 BLE Error Recovery

ID Task Repo Branch Status Done When
AU-007 Save partial sync data locally on BLE disconnect app-user feature/AU-007-partial-sync-recovery [ ] If connection drops during 500-point sync at point 300, first 300 points saved to local DB. Next sync starts from point 301
AU-008 Show user-friendly error messages for BLE failures app-user feature/AU-008-ble-error-messages [ ] "Bluetooth turned off" → "Turn on Bluetooth to sync". "Device out of range" → "Move closer to your device". "Unknown error" → "Sync failed. Tap to retry"
AU-009 No app crash on any BLE error path app-user feature/AU-009-ble-crash-prevention [ ] Wrap all BLE callbacks in try-catch. Test: force-kill Bluetooth mid-sync, unpair device during sync, send malformed BLE data → no crash in any scenario

1.24 Historical Backfill

ID Task Repo Branch Status Done When
AU-010 On first pair, trigger full history download from device app-user feature/AU-010-first-pair-history [ ] After pairing completes, automatically call BLE commands for all history types: activity, sleep, HRV, SpO2, temperature. Don't require user action
AU-011 Show backfill progress UI app-user feature/AU-011-backfill-progress-ui [ ] Progress bar: "Syncing 15 days of history... 45%". Updates as each day's data transfers. Completion toast: "History sync complete"
AU-012 Post backfill data to backend with is_backfill: true app-user feature/AU-012-backfill-to-backend [ ] All historical data sent to POST /devices/{id}/sync with is_backfill: true. Backend won't send false alerts for old data

1.25 Firmware Version Check

ID Task Repo Branch Status Done When
AU-013 Read firmware version on BLE connect app-user feature/AU-013-read-firmware-version [ ] ble_manager.dart reads device version characteristic on connect. Stores in device provider state
AU-014 Compare against minimum version and show warning banner app-user feature/AU-014-firmware-warning-banner [ ] If firmware < min version (from remote config or hardcoded), show non-blocking banner on device screen: "Firmware update available". Dismiss-able. Does not block usage

1.26 Dashboard — Real Data

ID Task Repo Branch Status Done When
AU-015 Set useMockDataProvider = false and fix all null/error states app-user feature/AU-015-disable-mock-data [ ] App launches with mock data off. All 5 tabs render without crash. Empty states shown for tabs with no data
AU-016 Dashboard tab → wire to GET /health/summary app-user feature/AU-016-dashboard-real-data [ ] Dashboard tab calls API on load and shows today's steps, HR, sleep, calories. Pull-to-refresh works. Loading spinner while fetching
AU-017 Health tab → wire to health metrics API app-user feature/AU-017-health-tab-real-data [ ] Health tab shows HR chart, HRV, SpO2 from GET /health/metrics. Date picker filters by day
AU-018 Training tab → wire to training API app-user feature/AU-018-training-tab-real-data [ ] Training tab lists programs from GET /training/programs. Empty state: "No training programs yet"
AU-019 Community tab → wire to community API app-user feature/AU-019-community-tab-real-data [ ] Community tab shows posts feed from GET /community/posts. Empty state: "No posts yet. Be the first!"
AU-020 Profile tab → wire to profile API app-user feature/AU-020-profile-tab-real-data [ ] Profile tab loads user data from GET /profile. Shows name, avatar, stats summary

1.27 Heart Rate Display

ID Task Repo Branch Status Done When
AU-021 Current HR widget — show live value when device connected app-user feature/AU-021-live-hr-widget [ ] Dashboard shows large HR number updating from BLE stream. Grey out with "—" when disconnected
AU-022 Resting HR card — show from daily summary app-user feature/AU-022-resting-hr-card [ ] Card shows resting HR from API. Label "Resting HR". Trend arrow vs yesterday
AU-023 HR zones chart — today's time in each zone app-user feature/AU-023-hr-zones-chart [ ] Horizontal stacked bar chart: Zone 1-5 with minutes. Colors: grey/blue/green/orange/red. Data from health_metrics
AU-024 7-day HR trend — line chart app-user feature/AU-024-hr-trend-chart [ ] Line chart with 7 data points (daily avg HR). X-axis = day. Y-axis = bpm. Tapping point shows value

1.28 Sleep Tracking UI

ID Task Repo Branch Status Done When
AU-025 Sleep score circle — large score 0-100 with color app-user feature/AU-025-sleep-score-circle [ ] Circular progress showing score. Green >80, yellow 60-80, red <60. "Last night" label
AU-026 Sleep stages breakdown — stacked bar app-user feature/AU-026-sleep-stages-bar [ ] Horizontal bar: awake (red), light (blue), deep (purple), REM (cyan) with minutes label for each
AU-027 Sleep duration and bed/wake times app-user feature/AU-027-sleep-duration-times [ ] Shows "7h 23m" total, "11:15 PM → 6:38 AM" bed/wake. Matches API data
AU-028 7-day sleep trend — bar chart app-user feature/AU-028-sleep-trend-chart [ ] Bar chart: 7 nights, bar height = duration, color = score quality. Tapping shows that night's detail

1.29 Activity Summary

ID Task Repo Branch Status Done When
AU-029 Activity rings/progress — steps, calories, active minutes app-user feature/AU-029-activity-rings [ ] 3 concentric rings (like Apple Watch). Steps = blue, calories = red, active min = green. Progress vs daily goal. Animated fill
AU-030 Today's stats cards — steps, distance, calories, active minutes, floors app-user feature/AU-030-today-stats-cards [ ] 5 metric cards showing today's values with icons. Data from GET /health/activity?date=today
AU-031 Weekly activity bar chart app-user feature/AU-031-weekly-activity-chart [ ] 7-bar chart for weekly steps. Tapping bar shows that day's full stats. Today's bar highlighted

1.30 HRV & SpO2 Display

ID Task Repo Branch Status Done When
AU-032 HRV current value + 7-day trend app-user feature/AU-032-hrv-display [ ] Card: "HRV" with RMSSD value, "ms" unit. Mini line chart for 7-day trend. Green/yellow/red based on personal baseline
AU-033 Stress indicator from HRV app-user feature/AU-033-stress-indicator [ ] Card: "Stress Level" with Low/Medium/High indicator. Derived from HRV. Color-coded
AU-034 SpO2 current reading + overnight trend app-user feature/AU-034-spo2-display [ ] Card: "Blood Oxygen" with percentage. Mini line chart for overnight readings. Red alert if <90%

1.31 Onboarding

ID Task Repo Branch Status Done When
AU-035 Personal info step saves to API app-user feature/AU-035-onboarding-personal-info [ ] Name, DOB entered → stored locally. Proceed to next step
AU-036 Country/language step saves to API app-user feature/AU-036-onboarding-country-language [ ] Country picker, language picker. Selection saved
AU-037 Fitness level step saves app-user feature/AU-037-onboarding-fitness-level [ ] Beginner/Intermediate/Advanced selection saved
AU-038 Training objective step saves app-user feature/AU-038-onboarding-training-objective [ ] Multi-select objectives (lose weight, build muscle, etc.) saved
AU-039 Training days step saves app-user feature/AU-039-onboarding-training-days [ ] Day-of-week picker. Selected days saved
AU-040 Daily goals step saves app-user feature/AU-040-onboarding-daily-goals [ ] Steps goal, calorie goal, sleep goal entered and saved
AU-041 Hobbies/sports step saves app-user feature/AU-041-onboarding-hobbies [ ] Multi-select sports/hobbies saved
AU-042 Final submit — all steps sent to PUT /profile app-user feature/AU-042-onboarding-final-submit [ ] On completion, all collected data sent in single API call. Success → navigate to home. Failure → show error, retry button
AU-043 Skip behavior — skipped steps use defaults app-user feature/AU-043-onboarding-skip-defaults [ ] Skipping step doesn't block progress. Default values used. User can edit later from profile

1.32 Push Notifications

ID Task Repo Branch Status Done When
AU-044 Register FCM token on login app-user feature/AU-044-fcm-register [ ] After successful auth, get FCM token → POST /push/register. Token refreshed on token-change callback
AU-045 Handle incoming push — show system notification app-user feature/AU-045-push-notification-handler [ ] When push received (foreground): show in-app banner. Background: system notification. Tap opens relevant screen based on data.screen field
AU-046 Deep link from notification tap app-user feature/AU-046-push-deep-link [ ] Push with { screen: "device" } → opens device screen. { screen: "session", id: "..." } → opens session. { screen: "health" } → opens health tab

1.33 QR Login

ID Task Repo Branch Status Done When
AU-047 Scan QR code from web → extract session token app-user feature/AU-047-qr-scan [ ] QR scanner reads URL/token from web-displayed QR. Parses session ID
AU-048 Call POST /auth/qr/verify with session token app-user feature/AU-048-qr-verify [ ] Sends session token + user's auth token. Backend verifies and marks QR session as authenticated
AU-049 Show success/error feedback app-user feature/AU-049-qr-feedback [ ] Success: "Logged in on web!" with checkmark. Error: "QR expired. Try again."

1.34 Training Screen

ID Task Repo Branch Status Done When
AU-050 List training programs from API app-user feature/AU-050-training-programs-list [ ] Training tab shows programs from GET /training/programs. Card per program: title, difficulty, duration, thumbnail
AU-051 Program detail → series → exercises app-user feature/AU-051-program-detail [ ] Tap program → see series list. Tap series → see exercises with video thumbnails, sets, reps
AU-052 Mark exercises complete and save workout app-user feature/AU-052-complete-workout [ ] User taps checkbox per exercise. "Complete Workout" button → POST /training saves session. Confirmation shown

1.35 Community Feed

ID Task Repo Branch Status Done When
AU-053 Post feed — list posts from friends app-user feature/AU-053-community-feed [ ] Community tab loads GET /community/posts. Shows post cards: author, text, image, like count, comment count
AU-054 Create post — text and image app-user feature/AU-054-create-post [ ] "+" button → compose screen. Type text, attach image. Submit → POST /community/posts. Appears in feed
AU-055 Stories — view and create app-user feature/AU-055-stories [ ] Story circles at top. Tap to view. "+" to create (image/text). Stories from GET /community/stories
AU-056 Friend requests — send, accept, reject app-user feature/AU-056-friend-requests [ ] Friends tab shows pending requests. Accept/reject buttons. Search users to send request. All via community API

1.36 Wallet & Rewards

ID Task Repo Branch Status Done When
AU-057 Show wallet balance from GET /wallet app-user feature/AU-057-wallet-balance [ ] Wallet screen shows balance prominently. Matches backend value
AU-058 Transaction history list app-user feature/AU-058-transaction-history [ ] Scrollable list of transactions: date, type (top-up/purchase/refund), amount, description. From GET /wallet/transactions

1.37 GPS Activity Tracking (Running/Cycling)

ID Task Repo Branch Status Done When
AU-059 Request location permissions (iOS + Android) app-user feature/AU-059-location-permissions [ ] App requests "Always" or "While Using" location permission. Handles denied gracefully. Uses geolocator or location package
AU-060 Activity start screen — select type (run/cycle/walk/hike) app-user feature/AU-060-activity-start-screen [ ] Screen with activity type picker (icons + labels). "Start" button begins GPS tracking. Countdown 3-2-1 before recording starts
AU-061 Live GPS tracking during activity app-user feature/AU-061-live-gps-tracking [ ] Screen shows: live map with route line drawing, elapsed time, current pace/speed, distance, heart rate (from ring/band if connected). GPS points recorded every 2-5 seconds
AU-062 Live metrics display — pace, distance, HR, elevation app-user feature/AU-062-live-metrics-display [ ] During activity: large pace/speed display, distance counter, HR from BLE device, elevation from GPS. Configurable metric layout
AU-063 Auto-pause detection app-user feature/AU-063-auto-pause [ ] If user stops moving for >10 seconds, auto-pause timer and show "Paused" indicator. Resume when movement detected. Pause duration tracked separately
AU-064 Send live GPS points to backend app-user feature/AU-064-send-live-gps [ ] During activity, batch GPS points every 30 seconds → POST /activities/live. If offline, queue locally and sync when connected
AU-065 Activity completion screen — summary + map app-user feature/AU-065-activity-completion [ ] "Stop" button → confirm → show summary: map with route, total distance, duration, avg pace, calories, elevation gain, HR zones. Save button → POST /activities/{id}/finish
AU-066 Activity history list app-user feature/AU-066-activity-history [ ] List of past activities: type icon, date, distance, duration, pace. Tapping opens detail with map
AU-067 Activity detail screen — full map + splits app-user feature/AU-067-activity-detail [ ] Full route on map (Google Maps or Mapbox). Per-km splits table. HR chart over time. Elevation profile. Share button
AU-068 Activity stats screen — totals and records app-user feature/AU-068-activity-stats [ ] From GET /activities/stats: total distance, total activities, weekly mileage chart, personal records (longest run, fastest pace). Filter by activity type

App Device

Repo: app-device Timeline: Mar 6 — Mar 20

1.37 Serial Connection

ID Task Repo Branch Status Done When
AD-001 Serial port discovery — scan for connected equipment app-device feature/AD-001-serial-port-discovery [ ] App scans USB serial ports on launch. Lists available equipment with name. Auto-connects to last known device
AD-002 Connection stability — maintain serial connection during session app-device feature/AD-002-connection-stability [ ] Serial connection stays open for 60+ min workout session. No random disconnects. If USB physically unplugged, error shown within 2s
AD-003 Reconnect on disconnect — auto-retry with user feedback app-device feature/AD-003-auto-reconnect [ ] On unexpected disconnect, show "Reconnecting..." and retry 3 times. Success → resume. Failure → "Connection lost. Check cable." with manual retry

1.38 Real-Time Metrics

ID Task Repo Branch Status Done When
AD-004 Parse serial data packets — force, power, HR, reps app-device feature/AD-004-parse-serial-packets [ ] EquipmentInfoRx correctly parses all fields from serial stream. Unit test with sample packet data passes
AD-005 Display live metrics on workout screen — <500ms latency app-device feature/AD-005-live-metrics-display [ ] Screen shows: left/right force, power (W), calories, reps, duration. Values update every 200-500ms matching equipment output
AD-006 Heart rate display from equipment sensor app-device feature/AD-006-equipment-hr-display [ ] HR from equipment's built-in sensor shown. "—" when no contact detected

1.39 Resistance Control

ID Task Repo Branch Status Done When
AD-007 Resistance slider sends serial command to motor app-device feature/AD-007-resistance-slider [ ] Slider 0-100 maps to motor resistance. Moving slider → equipment responds within 1s. Value persists during session
AD-008 Support all 5 resistance modes app-device feature/AD-008-resistance-modes [ ] Mode picker: constant, centrifugal, centripetal, elastic, fluid. Selecting mode sends correct serial command. Equipment acknowledges
AD-009 Remote control button handling — power up/down app-device feature/AD-009-remote-control [ ] BLE remote buttons: up/down adjust resistance by 5 per press. Long-press = continuous adjustment. Mode button cycles through modes

1.40 Workout Session

ID Task Repo Branch Status Done When
AD-010 Start/stop workout session with timer app-device feature/AD-010-workout-session-timer [ ] "Start" button begins session timer. Metrics accumulate. "Stop" button ends session. Confirm dialog prevents accidental stop
AD-011 Post workout summary to backend app-device feature/AD-011-post-workout-summary [ ] On session end, data sent to POST /training: duration, calories, total_reps, avg_power, max_power, HR_avg, HR_max. Returns success
AD-012 Show workout summary screen app-device feature/AD-012-workout-summary-screen [ ] After session: summary card with all stats. "Save" button posts to backend. "Discard" button skips save

1.41 KinesteX AI Training

ID Task Repo Branch Status Done When
AD-013 Launch KinesteX SDK with camera app-device feature/AD-013-kinestex-launch [ ] AI Training screen opens camera via KinesteX SDK. User sees themselves with skeleton overlay. No crash, permissions requested correctly
AD-014 Rep counting and form scoring app-device feature/AD-014-rep-counting-form-score [ ] During exercise, KinesteX counts reps and shows form score (0-100). Matches expected count for test exercise
AD-015 Save AI training results to backend app-device feature/AD-015-save-ai-training [ ] Session results (exercise, reps, form_score, duration) sent to POST /ai-training. Appears in training history

1.42 Device App — Other Features

ID Task Repo Branch Status Done When
AD-016 Device configuration screen — equipment type, mirror, power, theme app-device feature/AD-016-device-config-screen [ ] Settings screen with all config options from device_config.dart. Changes saved to SharedPreferences. Applied on next equipment connection
AD-017 10-step onboarding flow completes and saves app-device feature/AD-017-onboarding-flow [ ] All 10 steps navigable. Data collected and sent to PUT /profile on completion. Skippable with defaults
AD-018 Join live coaching session from home screen app-device feature/AD-018-join-live-session [ ] "Live Sessions" section shows upcoming sessions from GET /sessions. Tap "Join" → video call (Chime) opens. Equipment metrics visible during call

Coach App

Repo: coach-app Timeline: Mar 6 — Mar 20

1.43 Coach Application

ID Task Repo Branch Status Done When
CA-001 Application form — bio, specializations, certifications, docs coach-app feature/CA-001-application-form [ ] All form fields editable. File upload for certifications works. Submit → POST /coaches/apply. Status shows "Pending"
CA-002 Application status tracking coach-app feature/CA-002-application-status [ ] After submit, /coach/application shows current status: pending/approved/rejected. Approved → redirect to dashboard

1.44 Session Management

ID Task Repo Branch Status Done When
CA-003 Create session form — title, date, time, duration, price, max participants coach-app feature/CA-003-create-session-form [ ] All fields validated. Date picker only allows future dates. Submit → POST /coach/sessions. Success toast + redirect to dashboard
CA-004 Dashboard tabs — Upcoming, Live, Pending, History coach-app feature/CA-004-dashboard-tabs [ ] 4 tabs correctly filter sessions by status. Counts in tab badges match. Real-time update when session goes live
CA-005 Edit upcoming session coach-app feature/CA-005-edit-session [ ] Tap session → edit screen. Change title/time/price. Save → PUT /coach/sessions/{id}. Changes reflected in dashboard
CA-006 Cancel/delete session coach-app feature/CA-006-cancel-session [ ] Swipe or tap delete. Confirm dialog. DELETE /coach/sessions/{id}. Removed from upcoming list. Participants notified (if any)

1.45 Live Video Session

ID Task Repo Branch Status Done When
CA-007 Start session — initiate Chime meeting coach-app feature/CA-007-start-chime-session [ ] "Start" button on upcoming session → calls Chime SDK to create meeting. Status changes to "live". Video preview shows
CA-008 Video/audio during session — both directions coach-app feature/CA-008-video-audio-session [ ] Coach and participant see/hear each other. Mute/unmute, camera on/off toggles work. Quality stable for 60 min
CA-009 End session — close for all participants coach-app feature/CA-009-end-session [ ] "End Session" button → confirm dialog → Chime meeting ended → all participants disconnected. Session status → "ended"

1.46 Client Data View

ID Task Repo Branch Status Done When
CA-010 Client list — show connected clients coach-app feature/CA-010-client-list [ ] List screen from GET /coach/clients. Shows name, avatar, last activity date
CA-011 Client health summary — HR, sleep, activity, body comp coach-app feature/CA-011-client-health-summary [ ] Tap client → health summary from GET /coach/clients/{id}/health/summary. Shows metric cards. Pull-to-refresh
CA-012 Permission-denied state — "No permission" for restricted metrics coach-app feature/CA-012-permission-denied-state [ ] When permission flag is false, show locked card: "Health data — No permission. Request access from client."

1.47 Coach Dashboard Stats

ID Task Repo Branch Status Done When
CA-013 Stats cards — total sessions, participants, revenue, live count coach-app feature/CA-013-dashboard-stats [ ] 4 stat cards at top of dashboard. Values computed from session data. Refresh on pull-down. All match backend data

1.48 Coach Push Notifications

ID Task Repo Branch Status Done When
CA-014 Register FCM token on coach login coach-app feature/CA-014-fcm-register [ ] After auth, FCM token sent to POST /push/register. Token refreshed on change
CA-015 Handle session-related pushes coach-app feature/CA-015-session-push-handler [ ] Receives: "Session starts in 30 min", "New participant joined", "Session about to start". Tap → opens relevant session

1.49 Managed Clients

ID Task Repo Branch Status Done When
CA-016 Create managed client — name, goals, notes coach-app feature/CA-016-create-managed-client [ ] Form creates offline client via POST /coach/managed-clients. Client appears in separate "Managed" tab
CA-017 Log metrics for managed client coach-app feature/CA-017-log-managed-metrics [ ] Coach enters weight, body fat, measurements for client → POST /coach/managed-clients/{id}/metrics. Saved and viewable
CA-018 Edit and delete managed client coach-app feature/CA-018-edit-delete-managed [ ] Edit form updates name/goals/notes. Delete with confirmation. Both work via API

1.50 SDK Migration

ID Task Repo Branch Status Done When
CA-019 Replace api_client.dart Dio calls with athion_sdk calls coach-app feature/CA-019-sdk-migration [ ] All HTTP calls in lib/services/api/ use AthionSDK instead of raw Dio. api_client.dart deleted. App compiles
CA-020 Auth token management via SDK coach-app feature/CA-020-sdk-auth-token [ ] Login stores token in SDK via sdk.setAuthToken(). Token refresh handled by SDK interceptor. No manual token management
CA-021 Verify all screens still work after migration coach-app feature/CA-021-sdk-migration-verify [ ] Manual test: login → dashboard → create session → client list → video call. All work. No regressions

Champion Stats Hub (Web)

Repo: champion-stats-hub Timeline: Mar 6 — Mar 20

1.51 Dashboard Widgets — Real Data

ID Task Repo Branch Status Done When
WEB-001 Replace hardcoded values in widget components with Supabase queries champion-stats-hub feature/WEB-001-widgets-real-data [ ] Each of 28 widgets calls supabase.from('health_metrics').select(...). No hardcoded numbers when user is logged in
WEB-002 Add empty states for all widgets champion-stats-hub feature/WEB-002-widget-empty-states [ ] Widget with no data shows: icon + "No data yet" + brief description of what will appear. Not a crash or blank space
WEB-003 Demo mode preserves mock data champion-stats-hub feature/WEB-003-demo-mode [ ] When isDemo flag is true (from AuthContext), widgets show mock data. Real user → real data. Demo → mock. Both paths work

1.52 Smart Ring Page

ID Task Repo Branch Status Done When
WEB-004 Connection status from user_devices table champion-stats-hub feature/WEB-004-ring-connection-status [ ] /smart-ring shows: "Connected" / "Disconnected", battery %, last sync time. Real-time Supabase subscription updates status
WEB-005 Today's ring metrics — HR, HRV, SpO2, sleep, steps, temp champion-stats-hub feature/WEB-005-ring-today-metrics [ ] 6 metric cards showing today's values from health_metrics where device_type = ring. Loading skeletons while fetching
WEB-006 7-day trend charts for ring metrics champion-stats-hub feature/WEB-006-ring-trend-charts [ ] Line charts for HR, HRV, SpO2, sleep score. 7 data points. Recharts components. Responsive on mobile

1.53 Smart Band Page

ID Task Repo Branch Status Done When
WEB-007 Band-specific metrics — SOS, strain, workout modes champion-stats-hub feature/WEB-007-band-metrics [ ] /smart-band shows band metrics + strain score + workout mode history. Same real-data pattern as ring page

1.54 Sleep Analysis Page

ID Task Repo Branch Status Done When
WEB-008 Last night's sleep display — score, duration, stages chart champion-stats-hub feature/WEB-008-sleep-display [ ] /sleep-analysis shows sleep score circle, duration, bed/wake times, stages as stacked bar chart. From health_metrics
WEB-009 Weekly sleep trend champion-stats-hub feature/WEB-009-weekly-sleep-trend [ ] 7-night bar chart with score color coding. Tapping night shows detail panel
WEB-010 Sleep insights text champion-stats-hub feature/WEB-010-sleep-insights [ ] Text insights below chart: "Deep sleep up 12%", "Consistent bedtime this week". From API or computed client-side

1.55 Health Intelligence Page

ID Task Repo Branch Status Done When
WEB-011 Readiness, strain, recovery, fitness score gauges champion-stats-hub feature/WEB-011-health-score-gauges [ ] /health-intelligence shows 4 gauge components with scores. Colors: green >70, yellow 40-70, red <40
WEB-012 Trend arrows and deltas champion-stats-hub feature/WEB-012-trend-arrows-deltas [ ] Each score shows up/down arrow + delta vs yesterday. "Recovery: 85 (+7)"
WEB-013 Score breakdown on click champion-stats-hub feature/WEB-013-score-breakdown [ ] Clicking score opens panel: component factors (sleep quality 80%, HRV trend +5%, resting HR good). Explains the score

1.56 Device Pairing

ID Task Repo Branch Status Done When
WEB-014 Generate QR code from backend session champion-stats-hub feature/WEB-014-qr-code-generation [ ] /pairing creates QR session via API. Displays QR code that encodes session token. QR refreshes every 60s
WEB-015 Poll for scan completion champion-stats-hub feature/WEB-015-qr-poll-completion [ ] After QR displayed, poll every 3s for session status. When scanned by app → show "Device paired successfully!" Auto-navigate to device page

1.57 Activity Hub

ID Task Repo Branch Status Done When
WEB-016 Today's activity from Supabase champion-stats-hub feature/WEB-016-today-activity [ ] /activity-hub shows steps, calories, distance, active minutes from real data. Activity ring component animated
WEB-017 Weekly bar chart and calendar heatmap champion-stats-hub feature/WEB-017-weekly-chart-heatmap [ ] 7-day bar chart for steps. Calendar heatmap showing activity intensity per day. From health_metrics activity records
WEB-018 Workout history list champion-stats-hub feature/WEB-018-workout-history [ ] List of past workouts from workouts table. Each: date, type, duration, calories. Paginated
WEB-029 GPS activity list with route maps champion-stats-hub feature/WEB-029-gps-activity-list [ ] Activity hub shows GPS activities: run/cycle/walk cards with mini route map, distance, pace, duration. From GET /activities
WEB-030 Activity detail page with full map champion-stats-hub feature/WEB-030-activity-detail-map [ ] Click activity → full route on map, splits table, HR/elevation charts. From GET /activities/{id}
WEB-031 Activity stats dashboard champion-stats-hub feature/WEB-031-activity-stats-dashboard [ ] Weekly/monthly mileage bar charts, personal records, activity type breakdown pie chart. From GET /activities/stats

1.58 CornerMan AI Coach

ID Task Repo Branch Status Done When
WEB-019 Chat sends to ai-coach Edge Function champion-stats-hub feature/WEB-019-ai-coach-chat [ ] User types message → sent to supabase.functions.invoke('ai-coach'). Response displayed in chat bubble
WEB-020 Conversation history persistence champion-stats-hub feature/WEB-020-chat-history [ ] Messages saved to ai_coaching_messages. Page reload → previous messages loaded. New conversation button starts fresh
WEB-021 Context includes user health data champion-stats-hub feature/WEB-021-chat-health-context [ ] Message payload includes recent health summary (last 7 days). AI can reference: "Your sleep was only 5 hours last night..."

1.59 Coach Portal

ID Task Repo Branch Status Done When
WEB-022 Client list from Supabase champion-stats-hub feature/WEB-022-coach-client-list [ ] /coach-portal shows clients from coach_client_permissions join with profiles. Name, last session, status
WEB-023 Client health summary view champion-stats-hub feature/WEB-023-client-health-view [ ] Click client → see health dashboard (subset of main dashboard). Respects permission flags
WEB-024 Session schedule and management champion-stats-hub feature/WEB-024-session-management [ ] Coach can view/create/edit sessions. Calendar view. Session cards with participant count
WEB-025 Revenue dashboard champion-stats-hub feature/WEB-025-revenue-dashboard [ ] Shows total revenue, monthly breakdown, per-session earnings. From wallet_transactions + session data

1.60 PWA

ID Task Repo Branch Status Done When
WEB-026 "Add to Home Screen" works on iOS Safari champion-stats-hub feature/WEB-026-pwa-ios [ ] Manifest configured. App icon appears. Opens full-screen (no browser chrome). Tested on iPhone
WEB-027 "Add to Home Screen" works on Android Chrome champion-stats-hub feature/WEB-027-pwa-android [ ] Install prompt appears. App installs. Opens full-screen. Tested on Android device
WEB-028 Offline fallback page champion-stats-hub feature/WEB-028-offline-fallback [ ] Service worker caches shell. No internet → shows "You're offline. Connect to sync your data." instead of browser error

Gorillas Device Integration

Expected arrival: March 30, 2026 Integration timeline: 2 days Repos: backend-api, app-user, champion-stats-hub

1.61 Gorillas Device Integration

ID Task Repo Branch Status Done When
GOR-001 Gorillas BLE protocol analysis — identify characteristics, data format, command structure backend-api + app-user feature/GOR-001-ble-protocol-analysis [ ] BLE services documented: HR, SpO2, activity, sleep characteristics identified. Data packet format decoded. Command set for reading metrics documented
GOR-002 Add Gorillas device type to backend — update device_type enum and auto-detection backend-api feature/GOR-002-device-type-backend [ ] Migration adds "gorillas" to device_type. POST /devices with name containing "Gorillas" auto-sets device_type = "gorillas". Existing device tests pass
GOR-003 Gorillas BLE service in app-user — scan, connect, read metrics app-user feature/GOR-003-ble-service [ ] New gorillas_ble_service.dart handles: scan for Gorillas device, connect, subscribe to health characteristic notifications. Metrics parsed into CreateHealthMetricPayload
GOR-004 Gorillas data mapping — map device metrics to health_metrics schema backend-api + app-user feature/GOR-004-data-mapping [ ] Gorillas HR, SpO2, sleep, steps, temperature mapped to correct health_metrics columns. Unit conversions applied if needed. Test with real device data
GOR-005 Gorillas device screen in app-user app-user feature/GOR-005-device-screen [ ] Device screen shows Gorillas-specific UI: battery level, firmware version, connection status, last sync. Metrics cards match device capabilities
GOR-006 Gorillas web dashboard page champion-stats-hub feature/GOR-006-web-dashboard [ ] /gorillas page shows device status, today's metrics, 7-day trends. Same pattern as ring/band pages
GOR-007 Gorillas integration test — end-to-end sync flow backend-api + app-user feature/GOR-007-integration-test [ ] Test: pair Gorillas → sync 24h of data → verify in backend → display on dashboard. All metrics arrive correctly. Dedup works