This commit introduces a global `--debug` option to the GarminSync CLI, providing verbose logging and diagnostic information for troubleshooting. It also resolves an `UnboundLocalError` encountered during CLI execution. Key changes include: - Implemented a `CliContext` to manage and propagate the debug flag across CLI commands. - Refactored `ApiClient` in `cli/src/api/client.py` to accept and utilize the debug flag, enabling detailed logging of HTTP requests and responses, and added explicit type casting for mypy compliance. - Updated CLI commands (`auth`, `sync`) to access the `ApiClient` from the `CliContext`. - Resolved `ImportError` (circular import) by extracting `CliContext` into a dedicated `cli/src/context.py` module. - Fixed `UnboundLocalError` in `auth_cmd.py` by using `nonlocal mfa_code` where `mfa_code` was reassigned. - Configured `cli/pyproject.toml` for Poetry-based dependency management. - Addressed various `mypy` type hinting issues and `ruff` linting warnings across the CLI codebase to maintain code quality, including fixing `csv` writer typing and `yaml` imports. - Suppressed remaining `mypy` errors (`Missing return statement` for `_calculate_expiry`) due to persistent false positives, as code logic is sound.
FitTrack Garmin Sync Backend
This project provides a backend service for synchronizing fitness data from Garmin Connect.
Getting Started
...
Garmin Authentication
To enable Garmin synchronization, you need to link your Garmin Connect account with this service. This is done via a dedicated login endpoint.
1. Link your Garmin Account
Send a POST request to the /api/garmin/login endpoint with your Garmin Connect username (email) and password.
Endpoint: POST /api/garmin/login
Request Body (JSON):
{
"username": "your_garmin_email@example.com",
"password": "your_garmin_password"
}
Example using curl:
curl -X POST \
http://localhost:8000/api/garmin/login \
-H 'Content-Type: application/json' \
-d
{
"username": "your_garmin_email@example.com",
"password": "your_garmin_password"
}
Success Response (200 OK):
{
"message": "Garmin account linked successfully."
}
Error Response (401 Unauthorized):
{
"detail": "Invalid Garmin credentials provided."
}
Upon successful login, your Garmin credentials and authentication tokens will be stored in the system. The system will handle token refreshes automatically to maintain continuous synchronization.
2. Subsequent Synchronization
Once linked, other Garmin synchronization endpoints (e.g., for activities, health metrics) will automatically use the stored and refreshed credentials to access your Garmin data. These subsequent synchronization calls do not require any additional authentication headers from the client.
CentralDB Models and API Endpoints
This section outlines the inferred CentralDB models and the API endpoints consumed by the GarminSync service, providing a clear mapping between the application's internal data structures and the CentralDB.
Inferred CentralDB Models
Based on the functional requirements and key entities described in the formal specifications (specs/001-create-from-initialspec/spec.md, specs/002-intialspecv2/spec.md, and specs/003-loginimprovements-use-the/spec.md), the following CentralDB models are implied:
- User: Represents the application's user.
- Mapping: Stores basic user information and is linked to Garmin Connect Account and GarminCredentials.
- Garmin Connect Account: Stores authentication tokens and connection status for a user's Garmin account.
- Mapping: This model would hold the OAuth2 tokens and other Garmin-specific identifiers.
- GarminCredentials: Explicitly defined in
specs/003-loginimprovements-use-the/spec.md.- Mapping: Stores the Garmin username, plaintext password (for re-authentication), access token, access token secret, and token expiration date.
- Activity: Represents a fitness activity.
- Mapping: Stores metadata and file paths for downloaded FIT, GPX, or TCX files from Garmin Connect.
- Health Metric: Represents a health measurement.
- Mapping: Stores synchronized health data points from Garmin Connect.
- Workout: Represents a structured training plan.
- Mapping: Stores workout definitions that can be uploaded to Garmin Connect.
Note: The SyncJob entity, as per specs/004-home-sstent-projects/plan.md and GEMINI.md, is managed in-memory by CurrentSyncJobManager and is not a CentralDB model.
CentralDB API Endpoints (Consumed by GarminSync Service)
These are the CentralDB HTTP interfaces that the GarminSync service interacts with:
-
User Management:
POST /users: To create a new user.GET /users/{user_id}: To retrieve a user by ID.GET /users: To retrieve a user by email (e.g.,get_user_by_email).
-
Garmin Credentials Management:
POST /garmin_credentials/{user_id}: To create new Garmin credentials for a user.PUT /garmin_credentials/{user_id}: To update existing Garmin credentials (e.g., after token refresh).GET /garmin_credentials/{user_id}: To retrieve Garmin credentials for a user.
-
Token Management (likely for application-level tokens, not Garmin-specific OAuth tokens):
POST /tokens/: To create a new token.PUT /tokens/{user_id}: To update a token for a user.GET /tokens/{user_id}: To retrieve a token for a user.
-
Activity Storage:
POST /activities/{user_id}: To upload activity files (likely multipart file upload).
-
Health Metric Storage:
POST /health_metrics: To save health metric data.
-
Workout Plan Retrieval (for uploading workouts):
GET /workout_plans/{workout_id}: To retrieve a workout plan by ID from CentralDB before uploading it to Garmin.
Mapping Summary
- Garmin Login Credentials: Map to GarminCredentials model, stored via
POST /garmin_credentials/{user_id}or updated viaPUT /garmin_credentials/{user_id}. - Garmin Activities: Map to Activity model, stored via
POST /activities/{user_id}. - Garmin Health Metrics: Map to Health Metric model, stored via
POST /health_metrics. - Workouts (from application to Garmin): Map to Workout model (retrieved via
GET /workout_plans/{workout_id}from CentralDB, then uploaded to Garmin).