feat: Initial implementation of FitTrack Report Generator

This commit introduces the initial version of the FitTrack Report Generator, a FastAPI application for analyzing workout files.

Key features include:
- Parsing of FIT, TCX, and GPX workout files.
- Analysis of power, heart rate, speed, and elevation data.
- Generation of summary reports and charts.
- REST API for single and batch workout analysis.

The project structure has been set up with a `src` directory for core logic, an `api` directory for the FastAPI application, and a `tests` directory for unit, integration, and contract tests.

The development workflow is configured to use Docker and modern Python tooling.
This commit is contained in:
2025-10-11 09:54:13 -07:00
parent 6643a64ff0
commit 9e0bd322d3
152 changed files with 25695 additions and 49 deletions

View File

@@ -0,0 +1,51 @@
import pytest
from unittest.mock import MagicMock, patch
from src.core.file_parser import FitParser, WorkoutData, WorkoutMetadata, PowerData, HeartRateData, SpeedData, ElevationData
from datetime import datetime, timedelta
import pandas as pd
@pytest.fixture
def mock_fit_file():
with patch('fitparse.FitFile') as mock_fit_file_class:
mock_fit_file_instance = MagicMock()
mock_fit_file_class.return_value = mock_fit_file_instance
# Mocking get_messages to return some dummy records
mock_record1 = MagicMock()
mock_record1.as_dict.return_value = {
'timestamp': datetime(2023, 1, 1, 10, 0, 0),
'power': 150,
'heart_rate': 130,
'speed': 5.0,
'altitude': 100.0
}
mock_record2 = MagicMock()
mock_record2.as_dict.return_value = {
'timestamp': datetime(2023, 1, 1, 10, 1, 0),
'power': 160,
'heart_rate': 135,
'speed': 5.5,
'altitude': 105.0
}
mock_fit_file_instance.get_messages.return_value = [mock_record1, mock_record2]
yield mock_fit_file_class
def test_fit_parser_initialization():
parser = FitParser("dummy.fit")
assert parser.file_path == "dummy.fit"
def test_fit_parser_parse_method_returns_workout_data(mock_fit_file):
parser = FitParser("dummy.fit")
workout_data = parser.parse()
assert isinstance(workout_data, WorkoutData)
assert isinstance(workout_data.metadata, WorkoutMetadata)
assert workout_data.metadata.file_type == "FIT"
assert isinstance(workout_data.time_series_data, pd.DataFrame)
assert not workout_data.time_series_data.empty
assert "power" in workout_data.time_series_data.columns
assert "heart_rate" in workout_data.time_series_data.columns
assert "speed" in workout_data.time_series_data.columns
assert "altitude" in workout_data.time_series_data.columns
assert workout_data.metadata.start_time == datetime(2023, 1, 1, 10, 0, 0)
assert workout_data.metadata.duration == timedelta(minutes=1)