mirror of
https://github.com/joaovitoriasilva/endurain.git
synced 2026-01-09 15:57:59 -05:00
3.9 KiB
3.9 KiB
Personal Records (PRs) Module
This module implements automatic tracking of personal records (PRs) for fitness activities.
Features
Supported Activity Types
🏃 Running (activity_type: 1, 2, 3, 34)
- fastest_1km: Fastest time to complete 1km
- fastest_5km: Fastest time to complete 5km
- fastest_10km: Fastest time to complete 10km
- fastest_half_marathon: Fastest time to complete 21.097km
- fastest_marathon: Fastest time to complete 42.195km
- longest_distance: Longest running distance
- best_average_pace: Best average pace (lower is better)
🚴 Cycling (activity_type: 4, 5, 6, 7, 27, 28, 29, 35, 36)
- fastest_5km: Fastest time to complete 5km
- fastest_20km: Fastest time to complete 20km
- fastest_40km: Fastest time to complete 40km
- longest_distance: Longest cycling distance
- max_power: Maximum power output (watts)
- best_normalized_power: Best normalized power (FTP indicator)
🏊 Swimming (activity_type: 8, 9)
- fastest_50m: Fastest time to complete 50m
- fastest_100m: Fastest time to complete 100m
- fastest_200m: Fastest time to complete 200m
- fastest_400m: Fastest time to complete 400m
- fastest_1500m: Fastest time to complete 1500m
- longest_distance: Longest swimming distance
🏋️ Strength Training (activity_type: 19, 20)
- Placeholder for future implementation (requires activity_sets parsing)
How It Works
Automatic PR Detection
PRs are automatically checked and updated whenever:
- A new activity is uploaded (GPX, TCX, or FIT file)
- An activity is synced from Strava
- An activity is synced from Garmin Connect
Distance Tolerance
To ensure accurate PR tracking, distance-based PRs use a tolerance threshold:
- Running/Cycling: 2% tolerance (e.g., 4.9-5.1km counts as 5km)
- Swimming: 5% tolerance (pool distances can vary)
This prevents false PRs from longer activities where we don't have split data.
Database Schema
class PersonalRecord:
id: int # Primary key
user_id: int # Foreign key to users table
activity_id: int # Foreign key to activities table
activity_type: int # Activity type (1=run, 4=ride, etc.)
pr_date: datetime # When the PR was set
metric: str # PR metric name (e.g., 'fastest_5km')
value: Decimal # PR value (time in seconds, distance in meters, etc.)
unit: str # Unit of measurement ('seconds', 'meters', 'watts', etc.)
API Endpoints
GET /personal_records/user/{user_id}
Get all personal records for a user.
Response:
[
{
"id": 1,
"user_id": 123,
"activity_id": 456,
"activity_type": 1,
"pr_date": "2025-10-11T10:30:00",
"metric": "fastest_5km",
"value": "1200.50",
"unit": "seconds"
}
]
POST /personal_records/user/{user_id}/recalculate
Recalculate all personal records for a user from scratch.
Response:
{
"message": "Personal records recalculated successfully"
}
Initial Data Migration
To calculate PRs for existing activities, use the migration script:
# Migrate all users
cd backend/app
python -m activities.personal_records.migration
# Migrate specific user
python -m activities.personal_records.migration 123
Database Migration
Run Alembic migration to create the personal_records table:
cd backend/app
alembic upgrade head
Future Enhancements
- Strength Training PRs: Parse activity_sets to track 1RM for specific exercises
- Segment PRs: Track best times for specific route segments (like Strava segments)
- Power-based PRs: Add 1-min, 5-min, 20-min power PRs for cycling
- Notifications: Alert users when they set a new PR
- PR History: Track historical PRs to see progression over time
- Stream-based PRs: Calculate split times from activity streams for more accurate distance PRs