from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from uuid import UUID from database import get_db import models from schemas import ItemCreate, ItemOut, TagIdPayload, TagOut from crud import generate_trip_items router = APIRouter(prefix="/items", tags=["items"]) @router.get("/", response_model=list[ItemOut]) def list_items(db: Session = Depends(get_db)): items = db.query(models.Item).options(joinedload(models.Item.tags)).all() return items def regenerate_all_trips(db): trips = db.query(models.Trip).all() for trip in trips: generate_trip_items( db, trip=trip, selected_tag_ids=[t.id for t in trip.selected_tags], marked_tag_ids=[t.id for t in trip.marked_tags], ) db.commit() @router.post("/", response_model=ItemOut) def create_item(payload: ItemCreate, db: Session = Depends(get_db)): user = db.query(models.User).first() if not user: from uuid import uuid4 user = models.User(id=uuid4(), name="Demo") db.add(user) db.flush() item = models.Item(user_id=user.id, name=payload.name, trip_id=payload.trip_id) # Attach tags if provided if payload.tag_ids: tags = ( db.query(models.Tag) .filter(models.Tag.id.in_(payload.tag_ids), models.Tag.user_id == user.id) .all() ) item.tags.extend(tags) db.add(item) db.commit() db.refresh(item) regenerate_all_trips(db) return item @router.post("/{item_id}/tags", response_model=ItemOut) def add_tag_to_item(item_id: UUID, payload: TagIdPayload, db: Session = Depends(get_db)): tag_id = payload.tag_id item = db.get(models.Item, item_id) if not item: raise HTTPException(status_code=404, detail="Item not found") tag = db.get(models.Tag, tag_id) if not tag or tag.user_id != item.user_id: raise HTTPException(status_code=404, detail="Tag not found") if tag in item.tags: raise HTTPException(status_code=400, detail="Tag already associated with item") item.tags.append(tag) db.commit() db.refresh(item) regenerate_all_trips(db) return item @router.delete("/{item_id}/tags/{tag_id}", response_model=ItemOut) def remove_tag_from_item(item_id: UUID, tag_id: UUID, db: Session = Depends(get_db)): item = db.get(models.Item, item_id) if not item: raise HTTPException(status_code=404, detail="Item not found") tag = db.get(models.Tag, tag_id) if not tag or tag.user_id != item.user_id: raise HTTPException(status_code=404, detail="Tag not found") item.tags.remove(tag) db.commit() db.refresh(item) regenerate_all_trips(db) return item @router.delete("/{item_id}", status_code=204) def delete_item(item_id: UUID, db: Session = Depends(get_db)): item = db.get(models.Item, item_id) if not item: raise HTTPException(status_code=404, detail="Item not found") db.delete(item) db.commit() regenerate_all_trips(db) @router.put("/{item_id}", response_model=ItemOut) def update_item_name(item_id: UUID, payload: dict, db: Session = Depends(get_db)): item = db.get(models.Item, item_id) if not item: raise HTTPException(status_code=404, detail="Item not found") name = payload.get("name") if not name or not isinstance(name, str): raise HTTPException(status_code=400, detail="Missing or invalid name") item.name = name db.commit() db.refresh(item) regenerate_all_trips(db) return item