summaryrefslogtreecommitdiff
path: root/routers/menus.py
diff options
context:
space:
mode:
Diffstat (limited to 'routers/menus.py')
-rw-r--r--routers/menus.py68
1 files changed, 67 insertions, 1 deletions
diff --git a/routers/menus.py b/routers/menus.py
index 9ec1d1d..db56d73 100644
--- a/routers/menus.py
+++ b/routers/menus.py
@@ -4,7 +4,7 @@ from datetime import datetime, timedelta, date
import json
from database import get_db
-from schemas import MenuPlanRead
+from schemas import MenuPlanRead, RecipeRead
from models import MenuPlan, Recipe
from services import pantry_service, ai_service
from config import settings
@@ -78,6 +78,7 @@ async def generate_menu(request: dict = None, db: Session = Depends(get_db)):
estimated_time_minutes=recipe_data.get("time_minutes", 30),
servings=recipe_data.get("serves", 2),
source="ai",
+ description=recipe_data.get("description", ""),
)
db.add(new_recipe)
db.flush()
@@ -234,6 +235,71 @@ async def swap_recipe_in_menu(recipe_id: int, request: dict = Body(default={}),
}
+@router.post("/current/recipes")
+async def add_recipe_to_menu(request: dict = Body(default={}), db: Session = Depends(get_db)):
+ """Generate and add a single recipe by description."""
+ description = (request.get("description") or "").strip()
+ if not description:
+ raise HTTPException(status_code=400, detail="Description is required")
+
+ monday = _current_monday()
+ menu_plan = db.query(MenuPlan).filter(MenuPlan.week_start == monday).first()
+
+ # Get existing recipe names to avoid duplicates
+ existing_names = []
+ if menu_plan:
+ try:
+ plan_ids = json.loads(menu_plan.plan)
+ existing = db.query(Recipe).filter(Recipe.id.in_(plan_ids)).all() if plan_ids else []
+ existing_names = [r.name for r in existing]
+ except Exception:
+ pass
+
+ pantry_context = pantry_service.build_pantry_context(db)
+
+ try:
+ result = await ai_service.generate_single_recipe(description, existing_names, pantry_context)
+ except ValueError as e:
+ raise HTTPException(status_code=503, detail=str(e))
+ except Exception as e:
+ raise HTTPException(status_code=503, detail=f"Ollama error: {str(e)}")
+
+ recipe_data = result.get("recipe", {})
+ if not recipe_data.get("name"):
+ raise HTTPException(status_code=503, detail="AI returned invalid recipe")
+
+ new_recipe = Recipe(
+ name=recipe_data["name"],
+ description=recipe_data.get("description", ""),
+ meal_type=recipe_data.get("meal_type", "dinner"),
+ ingredients=json.dumps(recipe_data.get("ingredients", [])),
+ instructions=recipe_data.get("instructions", ""),
+ estimated_time_minutes=recipe_data.get("time_minutes"),
+ servings=recipe_data.get("serves", 2),
+ source="ai",
+ )
+ db.add(new_recipe)
+ db.flush()
+
+ if menu_plan:
+ try:
+ plan_ids = json.loads(menu_plan.plan)
+ except Exception:
+ plan_ids = []
+ plan_ids.append(new_recipe.id)
+ menu_plan.plan = json.dumps(plan_ids)
+ else:
+ menu_plan = MenuPlan(
+ week_start=monday,
+ plan=json.dumps([new_recipe.id]),
+ )
+ db.add(menu_plan)
+
+ db.commit()
+ db.refresh(new_recipe)
+ return {"recipe": RecipeRead.from_orm(new_recipe)}
+
+
@router.delete("/{id}")
async def delete_menu(id: int, db: Session = Depends(get_db)):
"""Delete a menu plan."""