# Data Model: Fitbit-Garmin Local Sync ## Overview This document defines the data models for the Fitbit-Garmin Local Sync application based on the key entities identified in the feature specification. ## Entity: Configuration **Description**: Application settings including API credentials, sync settings, and database connection parameters **Fields**: - `id` (Integer): Unique identifier for the configuration record - `fitbit_client_id` (String): Fitbit API client ID - `fitbit_client_secret` (String): Fitbit API client secret (encrypted) - `garmin_username` (String): Garmin Connect username - `garmin_password` (String): Garmin Connect password (encrypted) - `sync_settings` (JSON): Sync preferences and settings - `created_at` (DateTime): Timestamp of creation - `updated_at` (DateTime): Timestamp of last update ## Entity: Weight Record **Description**: Individual weight entries with timestamps, values, and sync status with unique identifiers to prevent duplicate processing **Fields**: - `id` (Integer): Unique identifier for the weight record - `fitbit_id` (String): Original Fitbit ID for the weight entry - `weight` (Float): Weight value in user's preferred units - `unit` (String): Weight unit (e.g., 'kg', 'lbs') - `date` (Date): Date of the weight measurement - `timestamp` (DateTime): Exact timestamp of the measurement - `sync_status` (String): Sync status ('unsynced', 'synced', 'failed') - `garmin_id` (String, nullable): ID of the record if synced to Garmin - `created_at` (DateTime): Timestamp of record creation - `updated_at` (DateTime): Timestamp of last update ## Entity: Activity Metadata **Description**: Information about Garmin activities including download status, file content stored in database, and activity details **Fields**: - `id` (Integer): Unique identifier for the activity record - `garmin_activity_id` (String): Original Garmin ID for the activity - `activity_name` (String): Name of the activity - `activity_type` (String): Type of activity (e.g., 'running', 'cycling') - `start_time` (DateTime): Start time of the activity - `duration` (Integer): Duration in seconds - `file_content` (LargeBinary, nullable): Activity file content stored in database (base64 encoded) - `file_type` (String): File type (.fit, .gpx, .tcx, etc.) - `download_status` (String): Download status ('pending', 'downloaded', 'failed') - `downloaded_at` (DateTime, nullable): Timestamp when downloaded - `created_at` (DateTime): Timestamp of record creation - `updated_at` (DateTime): Timestamp of last update ## Entity: Health Metric **Description**: Comprehensive health data including type, timestamp, values across categories (steps, calories, heart rate, sleep, etc.) **Fields**: - `id` (Integer): Unique identifier for the health metric record - `metric_type` (String): Type of metric (e.g., 'steps', 'heart_rate', 'sleep', 'calories') - `metric_value` (Float): Value of the metric - `unit` (String): Unit of measurement - `timestamp` (DateTime): When the metric was recorded - `date` (Date): Date of the metric - `source` (String): Source of the metric ('garmin') - `detailed_data` (JSON, nullable): Additional details specific to the metric type - `created_at` (DateTime): Timestamp of record creation - `updated_at` (DateTime): Timestamp of last update ## Entity: Sync Log **Description**: Operation logs with timestamps, status, and results for monitoring and troubleshooting **Fields**: - `id` (Integer): Unique identifier for the sync log entry - `operation` (String): Type of sync operation ('weight_sync', 'activity_archive', 'metrics_download') - `status` (String): Status of the operation ('started', 'in_progress', 'completed', 'failed') - `message` (String): Status message or error details - `start_time` (DateTime): When the operation started - `end_time` (DateTime, nullable): When the operation completed - `records_processed` (Integer): Number of records processed - `records_failed` (Integer): Number of records that failed - `user_id` (Integer, nullable): Reference to user (if applicable) ## Entity: API Token **Description**: OAuth tokens for Fitbit and Garmin with expiration tracking and refresh mechanisms **Fields**: - `id` (Integer): Unique identifier for the token record - `token_type` (String): Type of token ('fitbit', 'garmin') - `access_token` (String): Access token (encrypted) - `refresh_token` (String): Refresh token (encrypted) - `expires_at` (DateTime): When the token expires - `scopes` (String): OAuth scopes granted - `last_used` (DateTime): When the token was last used - `created_at` (DateTime): Timestamp of record creation - `updated_at` (DateTime): Timestamp of last update - `garth_oauth1_token` (String, nullable): Garmin OAuth1 token (encrypted) - `garth_oauth2_token` (String, nullable): Garmin OAuth2 token (encrypted) - `mfa_state` (String, nullable): MFA state information for Garmin authentication - `mfa_expires_at` (DateTime, nullable): When MFA state expires ## Entity: Auth Status **Description**: Current authentication state for both Fitbit and Garmin, including token expiration times and last login information **Fields**: - `id` (Integer): Unique identifier for the auth status record - `service_type` (String): Type of service ('fitbit', 'garmin') - `username` (String): Username for the service (masked for security display) - `authenticated` (Boolean): Whether currently authenticated - `token_expires_at` (DateTime): When the current token expires - `last_login` (DateTime): When the last successful login occurred - `is_china` (Boolean): Whether using garmin.cn domain (Garmin only) - `last_check` (DateTime): When status was last checked - `created_at` (DateTime): Timestamp of record creation - `updated_at` (DateTime): Timestamp of last update ## Relationships - Configuration has many API Tokens - Authentication Status references API Tokens - Sync Logs reference Configuration - Weight Records may reference API Tokens for sync operations - Activity Metadata may reference API Tokens for download operations - Health Metrics may reference API Tokens for retrieval operations ## Validation Rules - Configuration records must have valid API credentials before sync operations - Weight Records must have unique fitbit_id to prevent duplicates - Activity Metadata records must have unique garmin_activity_id - Health Metric records must have valid metric_type from allowed list - Sync Log records must have valid operation and status values - API Token records must be refreshed before expiration - Authentication status must be updated when tokens are refreshed