mirror of
https://github.com/sstent/FitTrack_GarminSync.git
synced 2026-01-25 16:41:41 +00:00
Adds the technical plan, data model, API contracts, and research for the persisted Garmin authentication feature.
52 lines
3.0 KiB
Markdown
52 lines
3.0 KiB
Markdown
# Quickstart: Implementing Persisted Garmin Authentication
|
|
|
|
**Date**: 2025-12-22
|
|
|
|
This guide provides a high-level overview for developers implementing the `Persist Garmin Authentication for Stateless Sync` feature.
|
|
|
|
## 1. Database Model
|
|
|
|
- **Action**: Implement the `GarminAuthenticationState` model as defined in `data-model.md`.
|
|
- **File**: Create a new model in `src/models/garmin_auth_state.py`.
|
|
- **Details**: Ensure the model includes `user_id`, `session_data`, `mfa_pending`, and `last_validated` fields. Use SQLAlchemy and create a corresponding Alembic migration script.
|
|
|
|
## 2. API Endpoints
|
|
|
|
- **Action**: Implement the three new endpoints defined in `contracts/garmin_auth_session.json`.
|
|
- **Files**: Add a new router in `src/api/v1/auth.py`.
|
|
- **Logic**:
|
|
- `POST /api/v1/garmin/session/login`:
|
|
- Initialize `garth`.
|
|
- Call `garth.login(username, password)`.
|
|
- If `garth.MFARequired` is raised, create/update the `GarminAuthenticationState` record with `mfa_pending=True` and return `{"status": "MFA_REQUIRED"}`.
|
|
- If successful, `dumps()` the session, save it to `session_data`, set `mfa_pending=False`, and return `{"status": "SUCCESS"}`.
|
|
- `POST /api/v1/garmin/session/mfa`:
|
|
- Load the pending `garth` client state.
|
|
- Call `garth.enter_mfa(mfa_code)`.
|
|
- On success, `dumps()` the completed session and persist it to the database.
|
|
- `GET /api/v1/garmin/session/status`:
|
|
- Query the `GarminAuthenticationState` for the current user.
|
|
- Perform a lightweight validation call with the loaded session (e.g., `garth.connectapi.get_user_settings()`).
|
|
- Return the status (`VALID`, `MISSING`, `EXPIRED`, `MFA_PENDING`).
|
|
|
|
## 3. Update Background Sync Services
|
|
|
|
- **Action**: Modify the existing background sync services (`GarminActivityService`, `GarminHealthService`) to use the persisted session.
|
|
- **Files**: Update the relevant service files in `src/services/`.
|
|
- **Pattern: Load-Use-Update**:
|
|
1. **Load**: At the start of the job, fetch the `session_data` from the database.
|
|
2. **Initialize**: Call `garth.client.loads(session_data)` to initialize the client.
|
|
3. **Use**: Perform the sync operations. `garth` will handle automatic token refreshes.
|
|
4. **Update**: Before the job finishes, check if the session was modified (refreshed). If so, `dumps()` the new session and update the `session_data` field in the database. This is critical for maintaining a fresh session for the next job.
|
|
|
|
## 4. Error Handling
|
|
|
|
- Implement logic to catch `garth` exceptions for invalid sessions.
|
|
- If a session is invalid and cannot be refreshed, update the sync job status to `AUTH_EXPIRED` and clear the `session_data` from the database.
|
|
|
|
## 5. Testing
|
|
|
|
- Write unit tests for the new API endpoints and the Load-Use-Update pattern.
|
|
- Write integration tests that cover the full login (including MFA) and background sync flow.
|
|
- Mock the `garth` library to simulate different scenarios: successful login, MFA required, invalid session, and token refresh.
|