feat: Strava support — bulk-export .gz/.tcx import fix + .tcx parser; full Strava API OAuth live sync (activities via streams) with Profile connect UI; colour gym/no-GPS sports red
This commit is contained in:
@@ -45,6 +45,7 @@ class User(Base):
|
||||
named_routes = relationship("NamedRoute", back_populates="user", cascade="all, delete-orphan")
|
||||
weight_logs = relationship("WeightLog", back_populates="user", cascade="all, delete-orphan")
|
||||
garmin_connect_config = relationship("GarminConnectConfig", back_populates="user", uselist=False, cascade="all, delete-orphan")
|
||||
strava_config = relationship("StravaConfig", back_populates="user", uselist=False, cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class GarminConnectConfig(Base):
|
||||
@@ -67,6 +68,27 @@ class GarminConnectConfig(Base):
|
||||
user = relationship("User", back_populates="garmin_connect_config")
|
||||
|
||||
|
||||
class StravaConfig(Base):
|
||||
"""Per-user Strava OAuth tokens and sync state. Tokens are Fernet-encrypted
|
||||
(same SECRET_KEY scheme as Garmin credentials)."""
|
||||
__tablename__ = "strava_configs"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, unique=True, index=True)
|
||||
athlete_id = Column(String(64), nullable=True)
|
||||
athlete_name = Column(String(256), nullable=True)
|
||||
access_token_enc = Column(String(512), nullable=False)
|
||||
refresh_token_enc = Column(String(512), nullable=False)
|
||||
expires_at = Column(DateTime(timezone=True), nullable=True) # access-token expiry
|
||||
sync_enabled = Column(Boolean, default=True)
|
||||
sync_lookback_days = Column(Integer, default=30) # -1 = all-time, first sync only
|
||||
last_sync_at = Column(DateTime(timezone=True), nullable=True)
|
||||
last_sync_status = Column(String(512), nullable=True)
|
||||
created_at = Column(DateTime(timezone=True), default=now_utc)
|
||||
|
||||
user = relationship("User", back_populates="strava_config")
|
||||
|
||||
|
||||
class WeightLog(Base):
|
||||
"""Manual weight entries separate from health_metrics for easy tracking."""
|
||||
__tablename__ = "weight_logs"
|
||||
|
||||
Reference in New Issue
Block a user