From 2e0a94e88c847a5ed8dc6ad5fa49715cd631bdfe Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Fri, 8 May 2026 01:58:48 -0700 Subject: Initial commit — Commis personal chef app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AI-powered local chef tool: pantry tracking, meal logging, rotating weekly menu generation, and grocery list optimization via Ollama (llama3). FastAPI backend, SQLite, vanilla JS frontend. Co-Authored-By: Claude Sonnet 4.6 --- schemas.py | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 schemas.py (limited to 'schemas.py') diff --git a/schemas.py b/schemas.py new file mode 100644 index 0000000..0d16826 --- /dev/null +++ b/schemas.py @@ -0,0 +1,203 @@ +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 + 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] + + 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 -- cgit v1.3-2-g0d8e