This commit is contained in:
146
services/nutrition_service/models.py
Normal file
146
services/nutrition_service/models.py
Normal file
@@ -0,0 +1,146 @@
|
||||
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}>"
|
||||
Reference in New Issue
Block a user