This commit is contained in:
203
services/nutrition_service/schemas.py
Normal file
203
services/nutrition_service/schemas.py
Normal file
@@ -0,0 +1,203 @@
|
||||
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] = []
|
||||
Reference in New Issue
Block a user