tracktabs — Deep Architecture Map

Real-time race day dashboard for backyard ultra runners. Lap logging, nutrition tracking, crew coordination, offline-first PWA with Supabase backend.

What Is tracktabs?

A web-based race day command center for backyard ultra running.

tracktabs is a comprehensive race day dashboard that helps backyard ultra runners log laps, track nutrition intake, manage pace targets, coordinate crew activities, and analyze race performance. Built as an offline-first Progressive Web App, it works seamlessly on unreliable race day networks with IndexedDB caching and automatic sync when connectivity returns. The backend uses Supabase (PostgreSQL + Realtime) for live crew alerts, runner status broadcasts, and social feed commentary. The UI is component-driven with reusable base, shell, and specialized components powering 42 HTML pages across 10 page modules. Everything is styled with a design token system (primitives.css → semantic.css → 21 CSS files). The application works both as a web app and as a mobile-first PWA, with offline data queuing, conflict resolution, and sync reconciliation built into the core.

User Roles

Three primary user types with different access patterns and capabilities.

Runner

Primary user. Logs completed laps with nutrition data (carbs, fluids, sodium, caffeine, protein, fiber). Tracks mood, run time, and pace targets. Views real-time dashboard with pace totals, cumulative nutrition bars, and remaining race time. Can end race and view race recap. Sees crew alerts and social feed cheers.

Crew Member

Supports the runner. Receives "runner in" notifications via Realtime broadcasts. Runs crew checklist, triggers crew alerts, views decision tree troubleshooting flowchart. Can manually log nutrition if runner forgets. Handles admin tasks like adjusting targets for weather conditions. Views crew dashboard with alerts and progress tracking.

Spectator

Read-only observer. Sees live race feed with lap completions, nutrition summaries, and milestone updates. Can send cheers and emojis for encouragement. Views public race progress, finisher status, and live commentary. No data entry capabilities. Gets basic spectator privacy controls.

By the Numbers

A quick snapshot of the system at a glance.

42
HTML Pages
10
Page Modules
41
Services
65+
Components
21
CSS Files
11
SQL Migrations
7
Vendor Libraries
~35K
Lines of JS

Glossary of Terms

Backyard Ultra
Race format where runners complete ~4.167mi loops every hour until one remains.
Loop / Lap
One circuit of the course, typically 60 minutes of running time.
Runner In
Signal that runner has returned to aid station and completed their lap.
Fuel Menu
Pre-configured nutrition items for quick logging during races.
Pace Totals
Cumulative nutrition vs. targets, shown as progress bars.

Map Navigation

1 System Layers

Six horizontal architecture layers: HTML Pages (UI entry points) → Page Modules (logic bundles) → Services (API, data, business logic) → Components (65+ reusable UI elements) → Utilities & Data (helpers, calculations, reference data) → Backend & Vendors (Supabase, Vue 3, Three.js, Leaflet, Chart.js, Barlow font).
Look here to understand how the pieces stack. Every layer has dependencies flowing downward. This is the cross-section view — like cutting the app in half and looking at how everything connects.

2 Pages & Modules

All 42 HTML pages grouped by category: Active V3 pages (9 core interfaces), Specialized pages (bibboard, crew decision tree, fuel menu, GPS planner, monitoring, live race spectator, admin), and Legacy pages (v1/v2 interfaces still deployed). Shows line counts, module mappings, and purposes.
Look here to find where a specific page lives, what module powers it, and how many lines of code it contains. This is the table of contents — the complete surface area of what users see.

3 Services

All 41 services organized by domain: Core Backend (API, auth, settings), Race Day (nutrition targets, runner arrival, roles, lap timing, speech), Nutrition & Planning (race plans, profiles, products, conditions, weather), Social & Crew (feed, cheers, alerts, checklists, links), Analysis (grades, insights, metrics, milestones), Offline & Sync (IndexedDB queue, Realtime), Visualization (maps, images, photos, privacy), and Math (nutrition calculations, decision tree).
Look here when you need to find what service handles a specific feature. Each service has a line count and brief description. This is the "wiring diagram" for business logic — what handles what.

4 Data Layer

All database tables with schemas: Core (users, race_plans, laps, fuel_items), Supporting (race_profiles, conditions, crew_members, practice sessions), and Realtime channels (laps broadcasts, runner in signals, social feed). Shows column names, data types, and relationships. Includes data flow diagrams and sync architecture.
Look here when you need to understand the database schema, trace a bug through the data model, or figure out how realtime subscriptions work. This is the data truth table — what gets stored where and how it flows through the system.

5 CSS & Design

Design token architecture showing how primitives.css, semantic.css, and typography cascade into 21 CSS files. Shows color scales, semantic token mappings, and line counts for each stylesheet. Includes the design token system (colors, spacing, typography) that unifies the entire visual appearance.
Look here when you need to modify styling, understand the design token hierarchy, or find which CSS file handles a specific component. This is the design truth — the color palette, spacing system, and typography definitions that drive visual consistency.

6 Gap Analysis

Known issues and risks organized by severity. Critical issues (authentication, RLS policies, data isolation), Warnings (plan wizard auto-save, offline queue testing, backup strategy, service worker caching), and Informational items (legacy pages, stale bundles, testing gaps, missing TypeScript).
Look here when you want to know what's broken, what's risky, and what should be fixed next. This is the prioritized to-do list derived from actual code inspection. It's the honest assessment of technical debt.

System Architecture Layers

Six horizontal layers, top to bottom. Each depends on the layer below it. Data flows down through requests, back up through responses.

1
HTML Pages (User Interface)
The 42 HTML pages that users see. Entry points for all application flows. Render page-specific UI, manage user interactions, and delegate to page modules.
index-v3.html
race-day-v3.html (1,321L)
plan-v3.html
analysis-v3.html
compare-v3.html
practice-v3.html
conditions-v3.html
settings-v3.html
profile-select-v3.html
bibboard.html
crew-troubleshoot.html
+ 31 more...
2
Page Modules (Logic Bundles)
10 page module files that bundle business logic for specific features. Each module is imported by multiple HTML pages and contains initialization, state management, event binding, and orchestration logic.
race-day-v3.js (2,794L)
analysis-v3.js (991L)
compare-v3.js (846L)
bibboard.js (708L)
practice-v3.js (663L)
profile-select-v3.js (663L)
conditions-v3.js (586L)
plan-v3.js (410L)
settings-v3.js (344L)
index-v3.js (232L)
3
Services (Business Logic & Data)
41 services providing core functionality: API communication, offline data sync, race day operations, nutrition tracking, crew coordination, social features, analysis, and utility math. Each service encapsulates a specific domain.
api-service.js (789L)
offline-data-service.js (1,123L)
analysis-service.js (913L)
active-targets-service.js (404L)
plan-data-service.js (415L)
runner-in-service.js
social-feed-service.js
role-service.js
+ 33 more services
4
Components (UI Building Blocks)
65+ reusable Vue 3 components organized into tiers: Base components (inputs, buttons, modals, cards, spinners), Shell components (AppShell, sidebar, topbar, tabs), Shared components (FuelCard, StepperInput, ChipSelect), and Specialized components (lapMountain, course3DModel, raceReplayTheater, paceChart).
Base: 28 components
Shell: 8 components
Shared: 8 components
Specialized: 20+ components
lapMountain.vue (881L)
course3DModel.vue (845L)
raceReplayTheater.vue (824L)
5
Utilities & Reference Data
Helper functions and reference datasets: 14 utility modules (calculations, formatters, validation, GPX parsing), sweat-data.js (5,433 lines of nutrition reference), statsEngine.js (799L), caffeine.js metabolism model (265L).
sweat-data.js (5,433L)
statsEngine.js (799L)
caffeine.js (265L)
Validators
Formatters
Calculations
+ 8 more utility modules
6
Backend & Vendors
External services and framework infrastructure: Supabase (PostgREST API, Realtime subscriptions, Storage), Vue 3 (global and ESM builds), Three.js + A-Frame (3D models), Leaflet (map rendering), Chart.js (data visualization), Barlow font.
Supabase PostgREST
Supabase Realtime
Vue 3
Three.js
A-Frame
Leaflet
Chart.js

Pages & Modules Inventory

42 HTML pages grouped by category. Active V3 pages are production interfaces. Specialized pages handle specific workflows. Legacy pages are v1/v2 interfaces still deployed.

Active V3 Pages (Core Interfaces)
FileModuleLinesPurpose
index-v3.htmlindex-v3.js (232L)~560Command Center dashboard
race-day-v3.htmlrace-day-v3.js (2,794L)~1,321Core race logging interface with dashboard, crew alerts, nutrition tracking, social feed
plan-v3.htmlplan-v3.js (410L)~787Race plan wizard with nutrition targets, pacing strategy, fuel menu setup
analysis-v3.htmlanalysis-v3.js (991L)~650Post-race analysis charts and insights
compare-v3.htmlcompare-v3.js (846L)~500Multi-race comparison and historical analysis
practice-v3.htmlpractice-v3.js (663L)~500Training session tracker for practice runs
conditions-v3.htmlconditions-v3.js (586L)~400Weather adjustments and target recalculation
settings-v3.htmlsettings-v3.js (344L)~830User settings and profile configuration
profile-select-v3.htmlprofile-select-v3.js (663L)~560Profile selection and role switching
Specialized Pages (Feature-Specific)
FilePurpose
bibboard.htmlBib number and race number display, often used on secondary monitor
crew-troubleshoot.htmlCrew troubleshooting decision tree (decision-tree.js, 2,010L)
fuel-menu.htmlQuick fuel button setup and customization
gps-planner.htmlGPS route planning and course mapping
monitor.htmlLive race monitoring dashboard for organizers
live-race.htmlSpectator view with read-only race progress
admin.htmlAdmin panel for system management
Legacy Pages (V1/V2)

Approximately 21 legacy pages from earlier versions still deployed. These are gradually being replaced by v3 interfaces but remain for backward compatibility.

Services Architecture

41 services organized by domain. Each service encapsulates specific business logic, data operations, and integrations.

Core Backend
api-service.js
789 lines
Primary Supabase CRUD — users, laps, race plans, crew, conditions, images
supabase-client.js
45 lines
Initialized Supabase client and configuration
user-manager.js
509 lines
Auth state, user switching, athlete profiles
settings-service.js
587 lines
User settings persistence
Race Day Operations
active-targets-service.js
404 lines
Per-lap nutrition targets from plan + conditions
runner-in-service.js
~200 lines
Runner arrival signals via Realtime broadcast
role-service.js
~200 lines
Role detection (runner/crew/spectator)
lap-clock-service.js
~150 lines
Lap timer state management
speech-service.js
~200 lines
Web Speech API for voice notes
Nutrition & Planning
plan-data-service.js
415 lines
Race plan CRUD and templates
race-profile-service.js
478 lines
Runner profiles with sweat rate and sensitivity
product-database-service.js
~150 lines
Local fuel product catalog with fiber values
conditions-service-v3.js
471 lines
Weather-based target adjustments
weather-provider-service.js
351 lines
Open-Meteo API integration
Social & Crew
social-feed-service.js
~200 lines
Race timeline entries via Realtime
cheer-service.js
~200 lines
Cheer/encouragement system
crew-alerts-service.js
~200 lines
Crew alert monitoring
crew-checklist-service.js
~200 lines
Pre-race crew checklist
crew-link-service.js
~200 lines
Crew authorization and linking
crew-service.js
~200 lines
Crew member management
reaction-service.js
275 lines
Race reactions (emojis)
Analysis & Data
analysis-service.js
913 lines
Grades, consistency scoring, mood analysis
practice-session-service.js
401 lines
Practice session CRUD
custom-metrics-service.js
~200 lines
User-defined custom metrics
milestone-service.js
269 lines
Milestone tracking
Offline & Sync
offline-data-service.js
1,123 lines
IndexedDB queue & sync with conflict resolution
live-race-service.js
571 lines
Realtime lap updates
Visualization
gpx-map-service.js
394 lines
GPX route parsing and Leaflet maps
image-storage-service.js
~150 lines
Supabase Storage uploads
photo-upload-service.js
~150 lines
Photo capture workflow
spectator-privacy-service.js
~150 lines
Spectator visibility controls
Math & Models
sweat-math.js / statsEngine.js
709 + 799 lines
Nutrition calculations and caffeine metabolism
decision-tree.js
2,010 lines
Crew troubleshooting flowchart

Data Layer & Database Schema

11 SQL migrations create the database structure. Tables are organized into core (runtime), supporting (configuration), and social (community) domains.

Core Tables (Runtime Data)
users
user_id, name, email, weight_kg, caffeine_half_life, profile_image, banner_image, password_hash, settings (JSONB), flavor_text, bib_number
race_plans
id, user_id, race_name, plan_data (JSONB: race_status, targets, pacing, caffeine schedule), created_at
laps
id, user_id, lap_number, timestamp, carbs, fluids, sodium, caffeine, protein, fiber, mood, notes, run_time, runner_in_timestamps (JSONB), created_at
fuel_items
id, user_id, name, category, carbs, fluids, sodium, caffeine, protein, fiber, notes, created_at
Supporting Tables (Configuration)
race_profiles
id, user_id, name, sweat_rate, sweat_sodium, caffeine_sensitivity, custom_fields (JSONB)
condition_snapshots
id, user_id, temp_f, humidity, wind_speed, heat_index, adjusted_carbs/fluids/sodium, weather_api_raw (JSONB)
crew_members
id, user_id, crew_user_id, name, role, crew_code, status
practice_sessions
id, user_id, start_time, end_time, target_duration_hours, loop_minutes, status
practice_laps
id, session_id, lap_number, timestamp, carbs/fluids/sodium/caffeine/protein/fiber, mood, run_time
race_comparisons
id, user_id, name, race_plan_ids, comparison_data (JSONB)
lap_clock_entries
id, user_id, lap_number, completion_time, elapsed_seconds
Realtime Channels
Laps Channel
postgres_changes on laps table, filtered by user_id. Broadcasts lap completions to dashboard in real-time.
Runner In Channel
broadcast channel per race_id. Crew receives "runner in" signals when runner returns to aid station.
Social Feed Channel
postgres_changes on race_timeline table. Broadcasts cheers, reactions, and milestone updates to spectators.
Data Flow: From Fuel Menu to Logged Lap

1. Product DB (sweat-data.js) → 2. Race Plan Wizard creates templates → 3. fuel_items table stores custom items → 4. Race Day UI loads items via loadFuelItems() → 5. Fuel tap builds selectionTotals → 6. confirmAndLog validates nutrition targets → 7. logLap writes to laps table → 8. getLaps retrieves for dashboard → 9. Dashboard bars display cumulative totals

CSS & Design Tokens

21 CSS files organized by feature area. All styling flows from a unified token system: primitives.css → semantic.css → specialized feature stylesheets.

Design Token Architecture
Token Hierarchy
tokens.css (main entry point)
├── primitives.css (color scales 50-950)
│ ├── Violet scale (--p-violet-500: #9B3DE6)
│ ├── Cyan scale (--p-cyan-500: primary)
│ ├── Green, Amber, Red, Blue scales
│ └── Gray/neutral scale
├── semantic.css (semantic mappings)
│ ├── --primary: var(--p-cyan-500)
│ ├── --surface, --surface-alt, --surface-raised
│ ├── --text, --text-secondary, --text-muted
│ ├── --border, --border-strong
│ ├── --success, --warning, --danger, --info
│ └── Color overrides by page (e.g., profile-select: --primary = violet)
├── typography.css (font families and sizes)
└── spacing.css (scale from --space-xs to --space-xl)
Stylesheet Inventory (21 files)

Listed by line count. Larger stylesheets handle more complex UI areas.

FileLinesDomain
crew-dashboard.css4,365Crew monitoring and alerts
race-day-v3.css2,511Main race day interface
components.css1,426Component base styles
features.css960Feature-specific styles
analysis.css946Analysis and charts
accessibility.css782A11y and contrast rules
monitor.css791Race monitoring view
planner.css666Race plan wizard
layout.css607Layout primitives and grid
experimental.css585Experimental features
debrief.css567Post-race debrief UI
realtime.css379Realtime update animations
skeletons.css337Loading skeleton screens
conditions.css312Weather conditions UI
index.css253Command center dashboard
fonts.css54Font declarations
Semantic Color Mappings
Surface Colors
--surface: background (--bg), --surface-alt: secondary (--bg2), --surface-raised: elevated (--bg3)
Text Colors
--text: primary text (e1e4eb), --text-secondary: secondary (8b90a0), --text-muted: muted (5c6070)
Status Colors
--success: green, --warning: amber, --danger: red, --info: blue
Border Colors
--border: primary (2a2e3a), --border-strong: emphasized (353a4a)

Gap Analysis & Known Issues

Every known limitation, risk, and missing feature organized by severity. Derived from actual code inspection, not guesswork.

Critical Issues (Production Risk)
CRITICAL No Authentication Layer
Using plain text user_id with anon key. No Supabase Auth, no JWT validation, no session management. Any user can read/write any other user's data by changing their user_id parameter. This is a complete security breach waiting to happen.
CRITICAL Row-Level Security (RLS) is Permissive
All database tables have open RLS policies for demo purposes. Production needs proper row-level security rules that enforce user_id scoping at the database level. Without this, data isolation between users is broken.
CRITICAL No Data Backup Strategy
All race data lives in a single Supabase project with no export automation, no backup snapshots, and no disaster recovery plan. A single database failure means total data loss.
Warnings (Scale & Reliability Risks)
WARNING Plan Wizard Doesn't Auto-Save Fuel Items
The race plan form only persists fuel items when you submit the entire plan (submitPlan()). If you navigate away mid-edit, you lose your work. Should auto-save on each fuel item change.
WARNING Offline Queue Untested at Scale
offline-data-service.js has conflict resolution logic but hasn't been stress-tested with multi-hour offline periods or high-volume lap logging. Queue may corrupt or lose laps under extreme conditions.
WARNING Service Worker Cache Strategy Needs Review
Cache-bust params work around staleness issues, but the service worker cache strategy (what files get cached, for how long, update frequency) is not well documented and may serve stale JavaScript.
WARNING Bundle Files May Be Stale
shell-bundle.js, features-bundle.js, and other pre-compiled bundles are manually compiled. No build pipeline exists to keep them in sync with source. Easy to ship old code by accident.
Informational (Technical Debt)
INFO Legacy Pages Still Deployed
~20 legacy HTML pages from v1/v2 are still live in production, creating confusion about which interface is current. Should be cleaned up or clearly marked as deprecated.
INFO No Automated Testing
Zero test files. All QA is manual. No unit tests, no E2E tests, no integration tests. Should invest in basic test coverage for critical paths (lap logging, offline sync, nutrition calculations).
INFO Missing TypeScript
Pure JavaScript with no type checking. Service interfaces are informal (no JSDoc type hints, no schema validation). Adding TypeScript or JSDoc would prevent many runtime errors.
INFO No Monitoring or Error Tracking
No Sentry, no error logging, no performance monitoring. When something breaks in production, you won't know until a user complains.