from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.database import get_db from app.models import HomePantry, Ingredient, FamilyProfile from app.schemas import ( HomePantryResponse, HomePantryCreate, HomePantryBulkCreate, HomePantryBulkResult, HomePantryBulkResultItem, ) from app.security import require_session from uuid import UUID from typing import List router = APIRouter() @router.get("", response_model=List[HomePantryResponse]) def get_pantry_items(db: Session = Depends(get_db)): profile = db.query(FamilyProfile).first() if not profile: raise HTTPException(status_code=404, detail="Family profile not found") items = db.query(HomePantry).filter( HomePantry.family_profile_id == profile.id ).all() return items @router.post("", response_model=HomePantryResponse, dependencies=[Depends(require_session)]) def add_pantry_item(item: HomePantryCreate, db: Session = Depends(get_db)): profile = db.query(FamilyProfile).first() if not profile: raise HTTPException(status_code=404, detail="Family profile not found") existing = db.query(HomePantry).filter( HomePantry.family_profile_id == profile.id, HomePantry.ingredient_id == item.ingredient_id ).first() if existing: existing.quantity = item.quantity existing.unit = item.unit existing.expires_at = item.expires_at db.commit() db.refresh(existing) return existing db_item = HomePantry( family_profile_id=profile.id, ingredient_id=item.ingredient_id, quantity=item.quantity, unit=item.unit, expires_at=item.expires_at ) db.add(db_item) db.commit() db.refresh(db_item) return db_item @router.post("/bulk", response_model=HomePantryBulkResult, dependencies=[Depends(require_session)]) def add_pantry_items_bulk(payload: HomePantryBulkCreate, db: Session = Depends(get_db)): """Add or upsert many pantry items in a single call. Used by the Shopping List "Add checked to pantry" bulk action. Each item follows the same semantics as POST /api/pantry (insert or overwrite). Items missing an ingredient link or with an unknown ingredient id are reported as "skipped" rather than aborting the batch, so the user gets a precise count of what actually went into their pantry. """ profile = db.query(FamilyProfile).first() if not profile: raise HTTPException(status_code=404, detail="Family profile not found") results: List[HomePantryBulkResultItem] = [] added = updated = skipped = 0 for item in payload.items: # Validate the ingredient id before touching the DB. ingredient = db.query(Ingredient).filter(Ingredient.id == item.ingredient_id).first() if not ingredient: results.append(HomePantryBulkResultItem( ingredient_id=item.ingredient_id, status="skipped", reason="Unknown ingredient", )) skipped += 1 continue existing = db.query(HomePantry).filter( HomePantry.family_profile_id == profile.id, HomePantry.ingredient_id == item.ingredient_id, ).first() if existing: existing.quantity = item.quantity existing.unit = item.unit existing.expires_at = item.expires_at db.flush() results.append(HomePantryBulkResultItem( ingredient_id=item.ingredient_id, id=existing.id, status="updated", )) updated += 1 else: db_item = HomePantry( family_profile_id=profile.id, ingredient_id=item.ingredient_id, quantity=item.quantity, unit=item.unit, expires_at=item.expires_at, ) db.add(db_item) db.flush() results.append(HomePantryBulkResultItem( ingredient_id=item.ingredient_id, id=db_item.id, status="added", )) added += 1 db.commit() return HomePantryBulkResult( added=added, updated=updated, skipped=skipped, results=results, ) @router.delete("/{item_id}", dependencies=[Depends(require_session)]) def remove_pantry_item(item_id: UUID, db: Session = Depends(get_db)): item = db.query(HomePantry).filter(HomePantry.id == item_id).first() if not item: raise HTTPException(status_code=404, detail="Pantry item not found") db.delete(item) db.commit() return {"message": "Pantry item removed"} @router.put("/{item_id}", response_model=HomePantryResponse, dependencies=[Depends(require_session)]) def update_pantry_item(item_id: UUID, update: HomePantryCreate, db: Session = Depends(get_db)): item = db.query(HomePantry).filter(HomePantry.id == item_id).first() if not item: raise HTTPException(status_code=404, detail="Pantry item not found") item.ingredient_id = update.ingredient_id item.quantity = update.quantity item.unit = update.unit item.expires_at = update.expires_at db.commit() db.refresh(item) return item