Files
FitTrack_GarminSync/specs/010-specification-overview-the/quickstart.md
sstent 846725a81e feat(plan): create implementation plan for persisted auth
Adds the technical plan, data model, API contracts, and research for the persisted Garmin authentication feature.
2025-12-22 07:24:47 -08:00

3.0 KiB

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.