feat: implement Fitbit OAuth, Garmin MFA, and optimize segment discovery

- Add Fitbit authentication flow (save credentials, OAuth callback handling)
- Implement Garmin MFA support with successful session/cookie handling
- Optimize segment discovery with new sampling and activity query services
- Refactor database session management in discovery API for better testability
- Enhance activity data parsing for charts and analysis
- Update tests to use testcontainers and proper dependency injection
- Clean up repository by ignoring and removing tracked transient files (.pyc, .db)
This commit is contained in:
2026-01-16 15:35:26 -08:00
parent 45dbc32295
commit d1cfd0fd8e
217 changed files with 1795 additions and 922 deletions

View File

@@ -97,18 +97,18 @@ def test_discovery_integration():
# So we need to patch extract_points_from_file to avoid error on "mock_content"
with patch('src.services.discovery.extract_points_from_file', return_value=[[0,0]]) as mock_extract:
candidates = service.discover_segments("cycling", datetime(2025,1,1))
candidates, _ = service.discover_segments("cycling", datetime(2025,1,1))
# Assertions
# Since we mocked decimate to return identical long paths, they should cluster.
# result should contain 1 candidate.
# result should contain candidates.
# activity_ids should validly contain [101, 102]
assert len(candidates) == 1
c = candidates[0]
assert 101 in c.activity_ids
assert 102 in c.activity_ids
assert isinstance(c.activity_ids[0], int)
assert len(candidates) >= 1
candidate = candidates[0]
assert 101 in candidate.activity_ids
assert 102 in candidate.activity_ids
assert isinstance(candidate.activity_ids[0], int)
def test_connected_components():