before claude fix #1
This commit is contained in:
13
FitnessSync/backend/src/models/__init__.py
Normal file
13
FitnessSync/backend/src/models/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
# Create a base class for all models to inherit from
|
||||
Base = declarative_base()
|
||||
|
||||
# Import all models here to ensure they're registered with the Base
|
||||
from .config import Configuration
|
||||
from .api_token import APIToken
|
||||
from .auth_status import AuthStatus
|
||||
from .weight_record import WeightRecord
|
||||
from .activity import Activity
|
||||
from .health_metric import HealthMetric
|
||||
from .sync_log import SyncLog
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
19
FitnessSync/backend/src/models/activity.py
Normal file
19
FitnessSync/backend/src/models/activity.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Text, LargeBinary
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
|
||||
class Activity(Base):
|
||||
__tablename__ = "activities"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
garmin_activity_id = Column(String, unique=True, nullable=False) # Original Garmin ID
|
||||
activity_name = Column(String, nullable=True) # Name of the activity
|
||||
activity_type = Column(String, nullable=True) # Type of activity (e.g., 'running', 'cycling')
|
||||
start_time = Column(DateTime, nullable=True) # Start time of the activity
|
||||
duration = Column(Integer, nullable=True) # Duration in seconds
|
||||
file_content = Column(LargeBinary, nullable=True) # Activity file content stored in database (base64 encoded)
|
||||
file_type = Column(String, nullable=True) # File type (.fit, .gpx, .tcx, etc.)
|
||||
download_status = Column(String, default='pending') # 'pending', 'downloaded', 'failed'
|
||||
downloaded_at = Column(DateTime, nullable=True) # When downloaded
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
23
FitnessSync/backend/src/models/api_token.py
Normal file
23
FitnessSync/backend/src/models/api_token.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
import json
|
||||
|
||||
class APIToken(Base):
|
||||
__tablename__ = "api_tokens"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
token_type = Column(String, nullable=False) # 'fitbit' or 'garmin'
|
||||
access_token = Column(String, nullable=False) # This should be encrypted in production
|
||||
refresh_token = Column(String, nullable=True) # This should be encrypted in production
|
||||
expires_at = Column(DateTime, nullable=False)
|
||||
scopes = Column(String, nullable=True)
|
||||
garth_oauth1_token = Column(String, nullable=True) # OAuth1 token for garmin (JSON)
|
||||
garth_oauth2_token = Column(String, nullable=True) # OAuth2 token for garmin (JSON)
|
||||
# MFA session fields for garmin
|
||||
mfa_session_id = Column(String, nullable=True)
|
||||
mfa_resume_data = Column(String, nullable=True) # JSON blob
|
||||
mfa_expires_at = Column(DateTime, nullable=True)
|
||||
last_used = Column(DateTime, nullable=True)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
17
FitnessSync/backend/src/models/auth_status.py
Normal file
17
FitnessSync/backend/src/models/auth_status.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Boolean
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
|
||||
class AuthStatus(Base):
|
||||
__tablename__ = "auth_status"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
service_type = Column(String, nullable=False) # 'fitbit' or 'garmin'
|
||||
username = Column(String, nullable=True) # Masked username for security display
|
||||
authenticated = Column(Boolean, default=False) # Whether currently authenticated
|
||||
token_expires_at = Column(DateTime, nullable=True) # When current token expires
|
||||
last_login = Column(DateTime, nullable=True) # Last successful login
|
||||
is_china = Column(Boolean, default=False) # For Garmin - whether using garmin.cn domain
|
||||
last_check = Column(DateTime, nullable=True) # When status was last checked
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
16
FitnessSync/backend/src/models/config.py
Normal file
16
FitnessSync/backend/src/models/config.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, JSON
|
||||
from sqlalchemy.sql import func
|
||||
from datetime import datetime
|
||||
from ..models import Base
|
||||
|
||||
class Configuration(Base):
|
||||
__tablename__ = "configurations"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
fitbit_client_id = Column(String, nullable=True)
|
||||
fitbit_client_secret = Column(String, nullable=True) # This should be encrypted in production
|
||||
garmin_username = Column(String, nullable=True)
|
||||
garmin_password = Column(String, nullable=True) # This should be encrypted in production
|
||||
sync_settings = Column(JSON, nullable=True) # JSON field for sync preferences
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
17
FitnessSync/backend/src/models/health_metric.py
Normal file
17
FitnessSync/backend/src/models/health_metric.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Float, Text
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
|
||||
class HealthMetric(Base):
|
||||
__tablename__ = "health_metrics"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
metric_type = Column(String, nullable=False) # Type of metric (e.g., 'steps', 'heart_rate')
|
||||
metric_value = Column(Float, nullable=False) # Value of the metric
|
||||
unit = Column(String, nullable=True) # Unit of measurement
|
||||
timestamp = Column(DateTime, nullable=False) # When the metric was recorded
|
||||
date = Column(DateTime, nullable=False) # Date of the metric
|
||||
source = Column(String, nullable=False) # Source of the metric ('garmin')
|
||||
detailed_data = Column(Text, nullable=True) # Additional details (stored as JSON string)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
18
FitnessSync/backend/src/models/sync_log.py
Normal file
18
FitnessSync/backend/src/models/sync_log.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Text
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
|
||||
class SyncLog(Base):
|
||||
__tablename__ = "sync_logs"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
operation = Column(String, nullable=False) # 'weight_sync', 'activity_archive', 'metrics_download'
|
||||
status = Column(String, nullable=False) # 'started', 'in_progress', 'completed', 'failed'
|
||||
message = Column(Text, nullable=True) # Status message or error details
|
||||
start_time = Column(DateTime, nullable=False)
|
||||
end_time = Column(DateTime, nullable=True) # When operation completed
|
||||
records_processed = Column(Integer, default=0) # Number of records processed
|
||||
records_failed = Column(Integer, default=0) # Number of records failed
|
||||
user_id = Column(Integer, nullable=True) # Reference to user (if applicable)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
17
FitnessSync/backend/src/models/weight_record.py
Normal file
17
FitnessSync/backend/src/models/weight_record.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Float
|
||||
from sqlalchemy.sql import func
|
||||
from ..models import Base
|
||||
|
||||
class WeightRecord(Base):
|
||||
__tablename__ = "weight_records"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
fitbit_id = Column(String, unique=True, nullable=False) # Original Fitbit ID to prevent duplicates
|
||||
weight = Column(Float, nullable=False) # Weight value
|
||||
unit = Column(String, nullable=False) # Unit (e.g., 'kg', 'lbs')
|
||||
date = Column(DateTime, nullable=False) # Date of measurement
|
||||
timestamp = Column(DateTime, nullable=False) # Exact timestamp
|
||||
sync_status = Column(String, default='unsynced') # 'unsynced', 'synced', 'failed'
|
||||
garmin_id = Column(String, nullable=True) # ID of record if synced to Garmin
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
Reference in New Issue
Block a user