Components
0. Configuration Layer (config.py)
Purpose: Centralized configuration management for the entire application
Key Features:
- Single point of configuration for MongoDB connection details
- Environment variable support with
.envfile integration - Application settings (file size limits, validation thresholds)
For configuration details, see Platform Overview.
1. Web Layer (Flask Application)
Purpose: Handle HTTP requests, routing, and response formatting
Key Components:
app.py- Application entry pointapp/__init__.py- Flask application factoryapp/routes.py- RESTful API endpoints
Responsibilities:
- Request validation
- Response serialization
- Session management
- CORS handling
2. Service Layer
Purpose: Business logic and data processing
File Processor (file_processor.py)
- Handles FIT file parsing using Garmin SDK
- Manages ZIP file extraction
- Implements duplicate detection
- Stores raw data in GridFS
Statistics Processor (statistics_processor.py)
- Calculates session metrics (pace, heart rate, power)
- Computes training zones using Critical Speed
- Tracks personal bests
- Generates efficiency metrics including rTSS based on Critical Speed
- Automatically triggers Critical Speed recalculation when PBs improve
Runner History Processor (runner_history_processor.py)
- Calculates CTL (Chronic Training Load)
- Calculates ATL (Acute Training Load)
- Calculates TSB (Training Stress Balance)
- Implements Banister model calculations
Training Plan Generator (training_plan_generator.py)
- Creates periodized training plans
- Assigns workouts to training blocks
- Calculates progressive overload
- Manages tapering periods
Job Manager (job_manager.py)
Purpose: Manages all asynchronous background processing to prevent UI blocking and database contention.
Key Features:
- Thread-based execution: Spawns daemon threads for background jobs
- Job tracking: Stores job status in
background_jobscollection - Progress updates: Updates job progress percentage in real-time
- Automatic chaining: File processing jobs automatically queue analysis jobs
- Error handling: Graceful failure handling with error logging
Job Types:
file_processing: Unzip, validate, convert FIT→Parquet, store in GridFSsession_analysis: Calculate statistics, update PBs, recalculate critical speedtraining_plan_generation: Generate personalized training plans
Job Status Flow:
pending → running → completed
→ failed
Implementation Details:
- No polling from frontend (eliminates database "busy" errors)
- Jobs tracked in
background_jobscollection with timestamps - Progress updates: 0% (created) → 100% (completed/failed)
- Old jobs cleaned up after 7 days
- Results stored in job document for retrieval
Critical Speed Calculator (critical_speed.py)
- Calculates Critical Speed (CS) using linear regression model
- Implements D = W' + CS * T relationship
- Validates personal best times for consistency
- Returns CS (m/s), W' (anaerobic capacity in meters), and R² value
- Uses scikit-learn for regression analysis
- Automatically triggered during session analysis when PBs are updated
Heart Rate Calculator (heart_rate_calculator.py)
- Calculates maximum heart rate using HUNT formula: Max HR = 211 - (0.64 × age)
- Automatically calculates five training zones based on configurable percentages
- Zone 1 (Recovery): 60% of max HR
- Zone 2 (Endurance): 70% of max HR
- Zone 3 (Tempo): 80% of max HR
- Zone 4 (Threshold): 90% of max HR
- Zone 5 (VO2 Max): 100% of max HR
- Provides validation functions for heart rate zone consistency
- Integrates with frontend for automatic calculation during runner registration
Runner Service (services/runner_service.py)
Purpose: Ensures consistent runner creation across all application entry points
Key Features:
- Centralized default values: All runners receive complete defaults from
defaults.py - Multiple creation paths unified: Coaches, admins, and user registration use same logic
- Consistent data integrity: PBs, Banister parameters, and zones always present
Core Functions:
create_runner_with_defaults()- Creates new runner with full default templatecreate_minimal_runner_for_user()- Creates runner during user registrationupdate_runner_with_defaults()- Updates runner while preserving defaultsensure_runner_has_defaults()- Backfills missing defaults for existing runners
Default Values Applied:
- Personal Bests: Default times for multiple distances
- Physiological Model: Model-specific parameters
- Training Load: Default training load ranges
- Heart Rate Zones: Age-based defaults for 5 zones
- Training Schedule: 4 blocks, 4 weeks/block, 2 taper weeks
3. Data Access Layer
Purpose: Database operations and data persistence
Key Components:
database.py- Centralized MongoDB connection manager (Singleton)config.py- Centralized configuration managementmodels.py- Data model definitionsdefaults.py- Default configuration values
Database Connection Architecture:
- Single Point of Configuration: All MongoDB connections managed through
Configclass - Singleton Pattern:
Databaseclass provides application-wide connection sharing - Environment-Based: Connection details configurable via
.envfile - GridFS Integration: File storage centrally managed through singleton
Collections Structure:
The database uses 11 MongoDB collections:
- runner - Athlete profiles with physiological parameters
- sessionsFIT / sessionsParquet - Raw and processed session data
- sessionStatistics - Aggregated session metrics
- runnerHistory - Daily training load progression metrics
- trainingplan / trainingplanschema - Training plans (flat and nested)
- workouts - Workout library
- background_jobs - Async job tracking
- fs.files / fs.chunks - GridFS binary file storage
For complete schema documentation, see Database Schema.
4. External Integration Layer
Garmin FIT SDK (garmin_fit_sdk/)
- Custom implementation for FIT file parsing
- Handles various FIT message types
- Provides data validation and error handling
Components:
decoder.py- Main decoding logicprofile.py- FIT profile definitionsstream.py- Byte stream handlingbitstream.py- Bit-level operationscrc_calculator.py- Checksum validation