Files
chat/services/nutrition_service/schemas.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

203 lines
5.0 KiB
Python

from datetime import date
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, Field, root_validator
class MealType(str, Enum):
BREAKFAST = "breakfast"
LUNCH = "lunch"
DINNER = "dinner"
SNACK = "snack"
class ActivityIntensity(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class GoalType(str, Enum):
LOSE_WEIGHT = "lose_weight"
MAINTAIN = "maintain"
GAIN_WEIGHT = "gain_weight"
HEALTH = "health"
# Схемы для FoodItem
class FoodItemBase(BaseModel):
name: str
brand: Optional[str] = None
description: Optional[str] = None
food_type: Optional[str] = None
serving_size: Optional[str] = None
serving_weight_grams: Optional[float] = None
calories: Optional[float] = None
protein_grams: Optional[float] = None
fat_grams: Optional[float] = None
carbs_grams: Optional[float] = None
fiber_grams: Optional[float] = None
sugar_grams: Optional[float] = None
sodium_mg: Optional[float] = None
cholesterol_mg: Optional[float] = None
ingredients: Optional[str] = None
class FoodItemCreate(FoodItemBase):
fatsecret_id: Optional[str] = None
is_verified: bool = False
class FoodItemResponse(FoodItemBase):
id: int
uuid: str
fatsecret_id: Optional[str] = None
is_verified: bool
created_at: str
updated_at: Optional[str] = None
class Config:
from_attributes = True
# Схемы для UserNutritionEntry
class UserNutritionEntryBase(BaseModel):
entry_date: date
meal_type: MealType
quantity: float = Field(gt=0)
unit: Optional[str] = None
notes: Optional[str] = None
class UserNutritionEntryCreate(UserNutritionEntryBase):
food_item_id: Optional[int] = None
custom_food_name: Optional[str] = None
calories: Optional[float] = None
protein_grams: Optional[float] = None
fat_grams: Optional[float] = None
carbs_grams: Optional[float] = None
@root_validator(skip_on_failure=True)
def check_food_info(cls, values):
food_item_id = values.get("food_item_id")
custom_food_name = values.get("custom_food_name")
if food_item_id is None and not custom_food_name:
raise ValueError("Either food_item_id or custom_food_name must be provided")
return values
class UserNutritionEntryResponse(UserNutritionEntryBase):
id: int
uuid: str
user_id: int
food_item_id: Optional[int] = None
custom_food_name: Optional[str] = None
calories: Optional[float] = None
protein_grams: Optional[float] = None
fat_grams: Optional[float] = None
carbs_grams: Optional[float] = None
created_at: str
class Config:
from_attributes = True
# Схемы для WaterIntake
class WaterIntakeBase(BaseModel):
entry_date: date
amount_ml: int = Field(gt=0)
notes: Optional[str] = None
class WaterIntakeCreate(WaterIntakeBase):
pass
class WaterIntakeResponse(WaterIntakeBase):
id: int
uuid: str
user_id: int
entry_time: str
class Config:
from_attributes = True
# Схемы для UserActivityEntry
class UserActivityEntryBase(BaseModel):
entry_date: date
activity_type: str
duration_minutes: int = Field(gt=0)
distance_km: Optional[float] = None
steps: Optional[int] = None
intensity: Optional[ActivityIntensity] = None
notes: Optional[str] = None
class UserActivityEntryCreate(UserActivityEntryBase):
calories_burned: Optional[float] = None
class UserActivityEntryResponse(UserActivityEntryBase):
id: int
uuid: str
user_id: int
calories_burned: Optional[float] = None
created_at: str
class Config:
from_attributes = True
# Схемы для NutritionGoal
class NutritionGoalBase(BaseModel):
daily_calorie_goal: Optional[int] = None
protein_goal_grams: Optional[int] = None
fat_goal_grams: Optional[int] = None
carbs_goal_grams: Optional[int] = None
water_goal_ml: Optional[int] = None
activity_goal_minutes: Optional[int] = None
weight_goal_kg: Optional[float] = None
goal_type: Optional[GoalType] = None
class NutritionGoalCreate(NutritionGoalBase):
pass
class NutritionGoalResponse(NutritionGoalBase):
id: int
user_id: int
created_at: str
updated_at: Optional[str] = None
class Config:
from_attributes = True
# Схемы для запросов к FatSecret API
class FoodSearchQuery(BaseModel):
query: str
page_number: int = 0
max_results: int = 10
class FoodDetailsQuery(BaseModel):
food_id: str
# Схемы для сводных данных
class DailyNutritionSummary(BaseModel):
date: date
total_calories: float = 0
total_protein_grams: float = 0
total_fat_grams: float = 0
total_carbs_grams: float = 0
total_water_ml: int = 0
total_activity_minutes: int = 0
estimated_calories_burned: float = 0
meals: List[UserNutritionEntryResponse] = []
water_entries: List[WaterIntakeResponse] = []
activity_entries: List[UserActivityEntryResponse] = []