from pydantic import BaseModel, ConfigDict from datetime import datetime, date from typing import Optional, List, Dict # Ingredient Schemas class IngredientCreate(BaseModel): name: str quantity: float = 1.0 unit: str = "" category: Optional[str] = None expiry_date: Optional[date] = None class IngredientRead(BaseModel): id: int name: str quantity: float unit: str category: Optional[str] expiry_date: Optional[date] added_at: datetime updated_at: datetime model_config = ConfigDict(from_attributes=True) class IngredientUpdate(BaseModel): name: Optional[str] = None quantity: Optional[float] = None unit: Optional[str] = None category: Optional[str] = None expiry_date: Optional[date] = None # MealIngredient Schemas class MealIngredientCreate(BaseModel): ingredient_name: str quantity_used: Optional[float] = None unit: Optional[str] = None class MealIngredientRead(BaseModel): id: int meal_log_id: int ingredient_name: str quantity_used: Optional[float] unit: Optional[str] model_config = ConfigDict(from_attributes=True) class MealIngredientUpdate(BaseModel): ingredient_name: Optional[str] = None quantity_used: Optional[float] = None unit: Optional[str] = None # MealLog Schemas class MealLogCreate(BaseModel): meal_name: str meal_type: str eaten_at: Optional[datetime] = None notes: Optional[str] = None servings: int = 1 ingredients: Optional[List[MealIngredientCreate]] = None class MealLogRead(BaseModel): id: int meal_name: str meal_type: str eaten_at: datetime notes: Optional[str] servings: int ingredients: List[MealIngredientRead] model_config = ConfigDict(from_attributes=True) class MealLogUpdate(BaseModel): meal_name: Optional[str] = None meal_type: Optional[str] = None eaten_at: Optional[datetime] = None notes: Optional[str] = None servings: Optional[int] = None # Recipe Schemas class RecipeCreate(BaseModel): name: str meal_type: str ingredients: str instructions: Optional[str] = None estimated_time_minutes: Optional[int] = None servings: int = 2 source: str = "ai" class RecipeRead(BaseModel): id: int name: str meal_type: str ingredients: str instructions: Optional[str] estimated_time_minutes: Optional[int] servings: int source: str created_at: datetime model_config = ConfigDict(from_attributes=True) class RecipeUpdate(BaseModel): name: Optional[str] = None meal_type: Optional[str] = None ingredients: Optional[str] = None instructions: Optional[str] = None estimated_time_minutes: Optional[int] = None servings: Optional[int] = None source: Optional[str] = None # MenuPlan Schemas class MenuPlanCreate(BaseModel): week_start: date plan: str model_used: Optional[str] = None class MenuPlanRead(BaseModel): id: int week_start: date plan: str generated_at: datetime model_used: Optional[str] notes: Optional[str] = None model_config = ConfigDict(from_attributes=True) class MenuPlanUpdate(BaseModel): week_start: Optional[date] = None plan: Optional[str] = None model_used: Optional[str] = None # GroceryList Schemas class GroceryListCreate(BaseModel): generated_for: date items: str total_estimate: Optional[float] = None notes: Optional[str] = None class GroceryListRead(BaseModel): id: int generated_for: date items: str total_estimate: Optional[float] generated_at: datetime is_purchased: bool notes: Optional[str] model_config = ConfigDict(from_attributes=True) class GroceryListUpdate(BaseModel): generated_for: Optional[date] = None items: Optional[str] = None total_estimate: Optional[float] = None is_purchased: Optional[bool] = None notes: Optional[str] = None # Complex domain schemas class GroceryItem(BaseModel): name: str quantity: float unit: str store_section: Optional[str] = None estimated_cost: Optional[float] = None used_in_meals: List[str] = [] reason: Optional[str] = None class PantryContext(BaseModel): available_ingredients: List[IngredientRead] = [] expiring_soon: List[IngredientRead] = [] recent_meals: List[MealLogRead] = [] meal_frequency: Dict[str, int] = {} class WeeklyMenuSlot(BaseModel): name: str ingredients: List[str] = [] instructions: Optional[str] = None time_minutes: Optional[int] = None class WeeklyMenuDay(BaseModel): breakfast: Optional[WeeklyMenuSlot] = None lunch: Optional[WeeklyMenuSlot] = None dinner: Optional[WeeklyMenuSlot] = None