# Fitbit Integration Specification **Status**: Implemented **Version**: 1.0.0 **Last Updated**: 2026-01-12 ## 1. Overview This specification documents the current implementation of the Fitbit integration within the FitTrack2 ecosystem. The primary goal is to authenticate with the Fitbit API using OAuth 2.0 and synchronize health metrics—specifically body weight and BMI—into the local database for analysis and visualization. ## 2. Authentication (OAuth 2.0) ### 2.1 Credentials Management - **Storage**: Client ID and Client Secret are stored in the `configuration` table. - **Tokens**: Access and Refresh tokens are stored in the `api_tokens` table with `token_type='fitbit'`. ### 2.2 Authorization Flow 1. **Initiation**: - Endpoint: `POST /setup/fitbit` - Input: `client_id`, `client_secret`, `redirect_uri` - Process: Generates an Authorization URL using the `fitbit` Python library. - Scopes Requested: `['weight', 'nutrition', 'activity', 'sleep', 'heartrate', 'profile']` 2. **Callback**: - Endpoint: `POST /setup/fitbit/callback` - Input: `code` (Authorization Code) - Process: Exchanges code for Access and Refresh tokens. - Output: Saves tokens to `api_tokens` table. ### 2.3 Token Refresh - **Mechanism**: The `FitbitClient` handles token expiration. - **Note**: Current implementation of `refresh_access_token` in `FitbitClient` contains mock logic and requires finalization for production use. ## 3. Data Synchronization ### 3.1 Supported Metrics Currently, only **Weight** and **BMI** are synchronized. ### 3.2 Sync Strategy - **On-Demand**: Triggered via API or UI. - **Scopes**: - `30d`: Syncs the last 30 days. - `all`: Syncs all history starting from 2015-01-01. - **Chunking**: Requests are chunked into 30-day intervals to respect API limits. - **Rate Limiting**: Custom handling for `HTTP 429 Too Many Requests`. The system parses `Retry-After` headers and sleeps automatically before retrying a chunk. ### 3.3 Data Storage Data is stored in the `weight_records` table. | Column | Type | Description | | :--- | :--- | :--- | | `id` | Integer | Primary Key | | `fitbit_id` | String | Unique Log ID from Fitbit | | `weight` | Float | Weight in Kg | | `bmi` | Float | Calculated BMI | | `unit` | String | Unit (default 'kg') | | `date` | DateTime | Timestamp of measurement | | `sync_status` | String | Status for downstream sync (e.g. 'unsynced') | ### 3.4 Logic (Deduplication) - Incoming records are matched against existing records by `fitbit_id`. - **Updates**: If `weight` differs by > 0.01 or `bmi` was missing, the record is updated. - **Inserts**: New records are created if no match is found. ## 4. API Endpoints ### 4.1 Configuration & Auth - `POST /setup/fitbit`: Save credentials and get Auth URL. - `POST /setup/fitbit/callback`: Exchange code for token. - `POST /setup/fitbit/test-token`: Verify current token validity and fetch user profile. ### 4.2 Synchronization - `POST /api/sync/fitbit/weight`: Trigger sync. - Body: `{ "scope": "30d" | "all" }` - `GET /api/jobs/{job_id}`: Check sync status (if run as background job). ### 4.3 Data Access - `GET /api/metrics/query`: - Params: `source=fitbit`, `metric_type=weight`, `start_date`, `end_date`. - Returns: serialized `WeightRecord` objects. - `POST /api/sync/compare-weight`: Compares Fitbit weight dates vs Garmin weight dates to find gaps. ## 5. Frontend UI The UI is split between configuration (setup) and visualization (health dashboard). ### 5.1 Authentication UI (`backend/templates/setup.html`) The setup page handles the OAuth 2.0 flow: 1. **Credentials Form**: Inputs for `Client ID`, `Client Secret`, and `Redirect URI` (defaulting to `http://localhost:8000/fitbit_callback`). 2. **Actions**: - `Test Fitbit Credentials`: Validates inputs and generates the Authorization URL. - `Save Fitbit Credentials`: Persists credentials to the database. - `Test Current Fitbit Token`: Checks if the stored token is valid. 3. **OAuth Flow**: - After validation, a link "Authorize with Fitbit" is displayed. - User clicks link, authorizes on Fitbit, and is redirected to the `fitbit_callback` URL (localhost). - **Manual Step**: User copys the full URL (including code) and pastes it into the "Paste full callback URL" input. - `Complete OAuth Flow` button sends the code to the backend. ### 5.2 Health Dashboard (`backend/templates/fitbit_health.html`) Located at `backend/templates/fitbit_health.html`. #### Features - **Sync Controls**: Buttons to trigger "Sync Recent (30d)" and "Sync All". - **Comparison**: "Compare vs Garmin" modal showing counts and missing dates. - **Data Table**: Displays Date, Weight, BMI, and Source. - **Filtering**: Date range pickers (Start/End) and quick toggles (30d, 1y, All). ## 6. Dependencies - **Libraries**: - `fitbit` (Python client for interaction) - `sqlalchemy` (ORM) - `pydantic` (Data validation) ## 7. Future Considerations - **Token Refresh**: Implement real token refresh logic in `FitbitClient`. - **Additional Metrics**: Expand sync to cover Heart Rate, Sleep, and Activities using the already authorized scopes.