Files
chat/services/nutrition_service/models.py
Andrew K. Choi 537e7b363f
All checks were successful
continuous-integration/drone/push Build is passing
main commit
2025-10-16 16:30:25 +09:00

146 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import uuid
from sqlalchemy import Boolean, Column, Date, Float, Integer, String, Text, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from sqlalchemy.sql.expression import text
from sqlalchemy.sql.sqltypes import TIMESTAMP
from shared.database import BaseModel
class FoodItem(BaseModel):
"""Модель для хранения информации о продуктах питания"""
__tablename__ = "food_items"
uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
# Основная информация о продукте
fatsecret_id = Column(String(50), unique=True, index=True, nullable=True) # ID продукта в FatSecret
name = Column(String(255), nullable=False)
brand = Column(String(255), nullable=True)
description = Column(Text, nullable=True)
food_type = Column(String(50), nullable=True) # generic, branded, etc.
serving_size = Column(String(100), nullable=True) # e.g. "1 cup" or "100g"
serving_weight_grams = Column(Float, nullable=True)
# Пищевая ценность на порцию
calories = Column(Float, nullable=True) # kcal
protein_grams = Column(Float, nullable=True)
fat_grams = Column(Float, nullable=True)
carbs_grams = Column(Float, nullable=True)
fiber_grams = Column(Float, nullable=True)
sugar_grams = Column(Float, nullable=True)
sodium_mg = Column(Float, nullable=True)
cholesterol_mg = Column(Float, nullable=True)
# Дополнительная информация
ingredients = Column(Text, nullable=True)
is_verified = Column(Boolean, default=False) # Проверенные данные или пользовательские
created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
def __repr__(self):
return f"<FoodItem {self.name}>"
class UserNutritionEntry(BaseModel):
"""Модель для хранения записей пользователя о потреблении пищи"""
__tablename__ = "user_nutrition_entries"
uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
user_id = Column(Integer, nullable=False, index=True) # Связь с таблицей пользователей
# Информация о приеме пищи
entry_date = Column(Date, nullable=False, index=True)
meal_type = Column(String(50), nullable=False) # breakfast, lunch, dinner, snack
food_item_id = Column(Integer, ForeignKey("food_items.id"), nullable=True)
custom_food_name = Column(String(255), nullable=True) # Если продукт не из базы
# Количество
quantity = Column(Float, nullable=False, default=1.0)
unit = Column(String(50), nullable=True) # g, ml, oz, piece, etc.
# Рассчитанная пищевая ценность для данного количества
calories = Column(Float, nullable=True)
protein_grams = Column(Float, nullable=True)
fat_grams = Column(Float, nullable=True)
carbs_grams = Column(Float, nullable=True)
# Метаданные
notes = Column(Text, nullable=True)
created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
def __repr__(self):
return f"<UserNutritionEntry user_id={self.user_id} date={self.entry_date} meal={self.meal_type}>"
class WaterIntake(BaseModel):
"""Модель для отслеживания потребления воды"""
__tablename__ = "water_intake"
uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
user_id = Column(Integer, nullable=False, index=True) # Связь с таблицей пользователей
entry_date = Column(Date, nullable=False, index=True)
amount_ml = Column(Integer, nullable=False) # Количество в миллилитрах
entry_time = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
notes = Column(Text, nullable=True)
def __repr__(self):
return f"<WaterIntake user_id={self.user_id} date={self.entry_date} amount={self.amount_ml}ml>"
class UserActivityEntry(BaseModel):
"""Модель для отслеживания физической активности"""
__tablename__ = "user_activity_entries"
uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
user_id = Column(Integer, nullable=False, index=True) # Связь с таблицей пользователей
entry_date = Column(Date, nullable=False, index=True)
activity_type = Column(String(100), nullable=False) # walking, running, yoga, etc.
duration_minutes = Column(Integer, nullable=False)
calories_burned = Column(Float, nullable=True) # Расчетное количество сожженных калорий
# Дополнительные параметры активности
distance_km = Column(Float, nullable=True) # Для активностей с расстоянием
steps = Column(Integer, nullable=True) # Для ходьбы
intensity = Column(String(20), nullable=True) # low, medium, high
notes = Column(Text, nullable=True)
created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
def __repr__(self):
return f"<UserActivityEntry user_id={self.user_id} date={self.entry_date} activity={self.activity_type}>"
class NutritionGoal(BaseModel):
"""Модель для хранения целей пользователя по питанию и активности"""
__tablename__ = "nutrition_goals"
user_id = Column(Integer, nullable=False, index=True, unique=True) # Связь с таблицей пользователей
# Цели по калориям и макронутриентам
daily_calorie_goal = Column(Integer, nullable=True)
protein_goal_grams = Column(Integer, nullable=True)
fat_goal_grams = Column(Integer, nullable=True)
carbs_goal_grams = Column(Integer, nullable=True)
# Цели по воде и активности
water_goal_ml = Column(Integer, nullable=True, default=2000) # Стандартно 2 литра
activity_goal_minutes = Column(Integer, nullable=True, default=30) # Минимум 30 минут активности
# Цель по весу и предпочтения
weight_goal_kg = Column(Float, nullable=True)
goal_type = Column(String(50), nullable=True) # lose_weight, maintain, gain_weight, health
created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
def __repr__(self):
return f"<NutritionGoal user_id={self.user_id} calories={self.daily_calorie_goal}>"