Activity Fields
FitRepo extracts 25+ fields from each FIT file. Fields that aren’t present in a given activity are stored as null.
Identity
Section titled “Identity”| Field | Type | Description |
|---|---|---|
id | UUID | FitRepo internal ID |
user_id | UUID | Owner |
source | string | How the activity was received: wahoo_webhook or wahoo_backfill |
wahoo_id | string | Wahoo workout summary ID |
name | string | Activity name |
sport | string | Sport category (e.g. cycling, running) |
sport_type | string | Detailed sport type from FIT file (e.g. road, trail) |
started_at | timestamptz | Activity start time (UTC) |
created_at | timestamptz | When FitRepo received the activity |
Duration & Distance
Section titled “Duration & Distance”| Field | Type | Unit | Description |
|---|---|---|---|
duration_secs | integer | seconds | Total elapsed time |
timer_secs | integer | seconds | Moving time (excludes pauses) |
distance_meters | real | metres | Total distance |
ascent_meters | real | metres | Total ascent |
| Field | Type | Unit | Description |
|---|---|---|---|
avg_power | real | watts | Average power |
normalized_power | real | watts | Normalised Power (NP) — accounts for variability |
max_power | real | watts | Peak 1-second power |
intensity_factor | real | — | IF = NP ÷ FTP (requires FTP to be set) |
tss | real | — | Training Stress Score from FIT file |
threshold_power | integer | watts | FTP value stored in the FIT file |
variability_index | real | — | VI = NP ÷ avg_power (measure of pacing consistency) |
Heart Rate
Section titled “Heart Rate”| Field | Type | Unit | Description |
|---|---|---|---|
avg_heart_rate | real | bpm | Average heart rate |
max_heart_rate | real | bpm | Peak heart rate |
Cadence
Section titled “Cadence”| Field | Type | Unit | Description |
|---|---|---|---|
avg_cadence | real | rpm | Average cadence |
max_cadence | real | rpm | Peak cadence |
Speed, Calories & Temperature
Section titled “Speed, Calories & Temperature”| Field | Type | Unit | Description |
|---|---|---|---|
avg_speed | real | m/s | Average speed (multiply by 3.6 for km/h) |
max_speed | real | m/s | Peak speed |
calories | real | kcal | Total energy expenditure |
avg_temperature | real | °C | Average ambient temperature |
Training Effect
Section titled “Training Effect”| Field | Type | Description |
|---|---|---|
training_load | real | Garmin/Wahoo training load score (if present in FIT) |
aerobic_te | real | Aerobic training effect (0–5 scale) |
anaerobic_te | real | Anaerobic training effect (0–5 scale) |
Best Efforts (MMP)
Section titled “Best Efforts (MMP)”| Field | Type | Description |
|---|---|---|
best_efforts | JSONB | Mean-maximal power map: duration (seconds) → best watts |
Example value:
{ "5": 520, "10": 480, "30": 420, "60": 390, "300": 318, "600": 295, "1200": 268, "1800": 252, "3600": 238}See Best Efforts (MMP) for methodology.
Storage
Section titled “Storage”| Field | Type | Description |
|---|---|---|
storage_key | text | Path of the raw FIT file in R2 object storage (may be null if upload failed) |
filename | text | Original FIT filename |
sha256 | text | SHA-256 hash of the FIT file bytes |
Notes on nulls
Section titled “Notes on nulls”- Power fields (
avg_power,normalized_power, etc.) arenullfor activities without a power meter. intensity_factorandtssarenullwhen not present in the FIT file.best_effortsisnullfor non-cycling activities or very short rides with insufficient data.- Temperature is
nullwhen the device didn’t record it.