Nguyen Trong Lap
Recreate history without binary blobs
eeb0f9c
"""
Health Data Models - SQLAlchemy ORM models for persistent health data storage
"""
from datetime import datetime
from typing import List, Optional, Dict, Any
import json
import uuid
# Note: This file defines the data models
# In production, use SQLAlchemy with proper database setup
# For now, we'll use a simple dictionary-based approach with JSON serialization
class UserHealthProfile:
"""User's health profile - persistent across sessions"""
def __init__(self, user_id: str):
self.user_id = user_id
self.age: Optional[int] = None
self.gender: Optional[str] = None
self.weight: Optional[float] = None # kg
self.height: Optional[float] = None # cm
self.bmi: Optional[float] = None
self.activity_level: Optional[str] = None # low/moderate/high
self.fitness_level: Optional[str] = None # beginner/intermediate/advanced
self.health_conditions: List[str] = []
self.medications: List[str] = []
self.allergies: List[str] = []
self.dietary_restrictions: List[str] = []
self.created_at: datetime = datetime.now()
self.updated_at: datetime = datetime.now()
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary for JSON serialization"""
return {
'user_id': self.user_id,
'age': self.age,
'gender': self.gender,
'weight': self.weight,
'height': self.height,
'bmi': self.bmi,
'activity_level': self.activity_level,
'fitness_level': self.fitness_level,
'health_conditions': self.health_conditions,
'medications': self.medications,
'allergies': self.allergies,
'dietary_restrictions': self.dietary_restrictions,
'created_at': self.created_at.isoformat(),
'updated_at': self.updated_at.isoformat()
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'UserHealthProfile':
"""Create from dictionary"""
profile = cls(data['user_id'])
profile.age = data.get('age')
profile.gender = data.get('gender')
profile.weight = data.get('weight')
profile.height = data.get('height')
profile.bmi = data.get('bmi')
profile.activity_level = data.get('activity_level')
profile.fitness_level = data.get('fitness_level')
profile.health_conditions = data.get('health_conditions', [])
profile.medications = data.get('medications', [])
profile.allergies = data.get('allergies', [])
profile.dietary_restrictions = data.get('dietary_restrictions', [])
profile.created_at = datetime.fromisoformat(data.get('created_at', datetime.now().isoformat()))
profile.updated_at = datetime.fromisoformat(data.get('updated_at', datetime.now().isoformat()))
return profile
class HealthRecord:
"""Individual health record - tracks interactions and data"""
def __init__(self, user_id: str, record_type: str, data: Dict[str, Any]):
self.record_id = str(uuid.uuid4())
self.user_id = user_id
self.record_type = record_type # symptom/nutrition/exercise/mental/general
self.data = data
self.timestamp = datetime.now()
self.agent_name: Optional[str] = None
self.confidence: float = 0.5
def to_dict(self) -> Dict[str, Any]:
return {
'record_id': self.record_id,
'user_id': self.user_id,
'record_type': self.record_type,
'data': self.data,
'timestamp': self.timestamp.isoformat(),
'agent_name': self.agent_name,
'confidence': self.confidence
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'HealthRecord':
record = cls(data['user_id'], data['record_type'], data['data'])
record.record_id = data['record_id']
record.timestamp = datetime.fromisoformat(data['timestamp'])
record.agent_name = data.get('agent_name')
record.confidence = data.get('confidence', 0.5)
return record
class UserPreferences:
"""User preferences for personalization"""
def __init__(self, user_id: str):
self.user_id = user_id
self.preferred_exercise_types: List[str] = []
self.dietary_preferences: List[str] = []
self.communication_style: str = 'friendly' # friendly/formal/casual
self.notification_preferences: Dict[str, Any] = {}
self.goals: List[str] = []
self.updated_at: datetime = datetime.now()
def to_dict(self) -> Dict[str, Any]:
return {
'user_id': self.user_id,
'preferred_exercise_types': self.preferred_exercise_types,
'dietary_preferences': self.dietary_preferences,
'communication_style': self.communication_style,
'notification_preferences': self.notification_preferences,
'goals': self.goals,
'updated_at': self.updated_at.isoformat()
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'UserPreferences':
prefs = cls(data['user_id'])
prefs.preferred_exercise_types = data.get('preferred_exercise_types', [])
prefs.dietary_preferences = data.get('dietary_preferences', [])
prefs.communication_style = data.get('communication_style', 'friendly')
prefs.notification_preferences = data.get('notification_preferences', {})
prefs.goals = data.get('goals', [])
prefs.updated_at = datetime.fromisoformat(data.get('updated_at', datetime.now().isoformat()))
return prefs
class FitnessProgress:
"""Fitness workout record"""
def __init__(self, user_id: str):
self.progress_id = str(uuid.uuid4())
self.user_id = user_id
self.workout_date: datetime = datetime.now()
self.workout_type: str = '' # cardio/strength/flexibility/sports
self.duration_minutes: int = 0
self.intensity: str = 'medium' # low/medium/high
self.exercises_completed: int = 0
self.exercises_total: int = 0
self.notes: str = ''
self.timestamp: datetime = datetime.now()
def to_dict(self) -> Dict[str, Any]:
return {
'progress_id': self.progress_id,
'user_id': self.user_id,
'workout_date': self.workout_date.isoformat(),
'workout_type': self.workout_type,
'duration_minutes': self.duration_minutes,
'intensity': self.intensity,
'exercises_completed': self.exercises_completed,
'exercises_total': self.exercises_total,
'notes': self.notes,
'timestamp': self.timestamp.isoformat()
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'FitnessProgress':
progress = cls(data['user_id'])
progress.progress_id = data['progress_id']
progress.workout_date = datetime.fromisoformat(data['workout_date'])
progress.workout_type = data.get('workout_type', '')
progress.duration_minutes = data.get('duration_minutes', 0)
progress.intensity = data.get('intensity', 'medium')
progress.exercises_completed = data.get('exercises_completed', 0)
progress.exercises_total = data.get('exercises_total', 0)
progress.notes = data.get('notes', '')
progress.timestamp = datetime.fromisoformat(data['timestamp'])
return progress
class HealthMetrics:
"""Health measurement record"""
def __init__(self, user_id: str, metric_type: str, value: float, unit: str):
self.metric_id = str(uuid.uuid4())
self.user_id = user_id
self.metric_type = metric_type # weight/bp/glucose/heart_rate/etc
self.value = value
self.unit = unit
self.recorded_date: datetime = datetime.now()
self.timestamp: datetime = datetime.now()
def to_dict(self) -> Dict[str, Any]:
return {
'metric_id': self.metric_id,
'user_id': self.user_id,
'metric_type': self.metric_type,
'value': self.value,
'unit': self.unit,
'recorded_date': self.recorded_date.isoformat(),
'timestamp': self.timestamp.isoformat()
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'HealthMetrics':
metric = cls(data['user_id'], data['metric_type'], data['value'], data['unit'])
metric.metric_id = data['metric_id']
metric.recorded_date = datetime.fromisoformat(data['recorded_date'])
metric.timestamp = datetime.fromisoformat(data['timestamp'])
return metric