from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from app.database import get_db from app.models import Recipe, FamilyProfile from app.schemas import RecipeResponse, RecipeCreate, IngredientCreate, IngredientResponse from uuid import UUID from typing import List, Optional router = APIRouter() @router.get("/", response_model=List[RecipeResponse]) def get_recipes( skip: int = 0, limit: int = 50, cuisine_tag: Optional[str] = None, dietary_tag: Optional[str] = None, protein_type: Optional[str] = None, db: Session = Depends(get_db) ): query = db.query(Recipe) if cuisine_tag: query = query.filter(Recipe.cuisine_tags.contains([cuisine_tag])) if dietary_tag: query = query.filter(Recipe.dietary_tags.contains([dietary_tag])) if protein_type: query = query.filter(Recipe.protein_type == protein_type) recipes = query.offset(skip).limit(limit).all() return recipes @router.get("/{recipe_id}", response_model=RecipeResponse) def get_recipe(recipe_id: UUID, db: Session = Depends(get_db)): recipe = db.query(Recipe).filter(Recipe.id == recipe_id).first() if not recipe: raise HTTPException(status_code=404, detail="Recipe not found") return recipe @router.post("/", response_model=RecipeResponse) def create_recipe(recipe: RecipeCreate, db: Session = Depends(get_db)): profile = db.query(FamilyProfile).first() db_recipe = Recipe( family_profile_id=profile.id if profile else None, name=recipe.name, description=recipe.description, image_url=recipe.image_url, image_source=recipe.image_source, prep_time_minutes=recipe.prep_time_minutes, cook_time_minutes=recipe.cook_time_minutes, servings=recipe.servings, servings_scaled=recipe.servings_scaled, cuisine_tags=recipe.cuisine_tags, dietary_tags=recipe.dietary_tags, protein_type=recipe.protein_type, spice_level=recipe.spice_level, ingredients=[ing.model_dump() for ing in recipe.ingredients], instructions=recipe.instructions, source_url=recipe.source_url, is_manually_added=recipe.is_manually_added ) db.add(db_recipe) db.commit() db.refresh(db_recipe) return db_recipe @router.delete("/{recipe_id}") def delete_recipe(recipe_id: UUID, db: Session = Depends(get_db)): recipe = db.query(Recipe).filter(Recipe.id == recipe_id).first() if not recipe: raise HTTPException(status_code=404, detail="Recipe not found") db.delete(recipe) db.commit() return {"message": "Recipe deleted"} @router.get("/ingredients/list", response_model=List[IngredientResponse]) def list_ingredients(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): from app.models import Ingredient ingredients = db.query(Ingredient).offset(skip).limit(limit).all() return ingredients @router.post("/ingredients", response_model=IngredientResponse) def create_ingredient(ingredient: IngredientCreate, db: Session = Depends(get_db)): from app.models import Ingredient existing = db.query(Ingredient).filter(Ingredient.name_lower == ingredient.name_lower).first() if existing: raise HTTPException(status_code=400, detail="Ingredient with this name already exists") db_ingredient = Ingredient( name=ingredient.name, name_lower=ingredient.name_lower, plural_name=ingredient.plural_name, aisle=ingredient.aisle, typical_price=ingredient.typical_price, unit=ingredient.unit, season_months=ingredient.season_months ) db.add(db_ingredient) db.commit() db.refresh(db_ingredient) return db_ingredient