49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
"""WorkoutSession SQLAlchemy model."""
|
|
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey
|
|
from sqlalchemy.orm import relationship
|
|
from backend.database import Base
|
|
|
|
|
|
# Zepp activity type mapping
|
|
ZEPP_ACTIVITY_TYPES = {
|
|
1: "Running",
|
|
6: "Walking",
|
|
8: "Cycling",
|
|
10: "Elliptical",
|
|
16: "Free Training",
|
|
23: "HIIT",
|
|
52: "Stretching",
|
|
60: "Yoga",
|
|
}
|
|
|
|
|
|
class WorkoutSession(Base):
|
|
"""Workout data model."""
|
|
__tablename__ = "workout_sessions"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
user_id = Column(Integer, ForeignKey("users.id"))
|
|
start_time = Column(DateTime, index=True)
|
|
end_time = Column(DateTime)
|
|
activity_type = Column(String) # Human readable name
|
|
activity_type_id = Column(Integer, nullable=True) # Original Zepp type ID
|
|
duration_seconds = Column(Integer, default=0)
|
|
distance_meters = Column(Float, default=0.0)
|
|
calories = Column(Float, default=0.0)
|
|
avg_pace = Column(Float, nullable=True) # seconds per meter
|
|
max_pace = Column(Float, nullable=True)
|
|
min_pace = Column(Float, nullable=True)
|
|
avg_hr = Column(Integer, nullable=True)
|
|
max_hr = Column(Integer, nullable=True)
|
|
min_hr = Column(Integer, nullable=True)
|
|
notes = Column(String, nullable=True)
|
|
|
|
# Data provenance tracking
|
|
data_source = Column(String(50), default="health_connect") # "health_connect", "manual"
|
|
|
|
user = relationship("User", back_populates="workouts")
|
|
|
|
@staticmethod
|
|
def get_activity_name(type_id: int) -> str:
|
|
return ZEPP_ACTIVITY_TYPES.get(type_id, f"Activity {type_id}")
|