from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from uuid import UUID from backend.database import get_db from backend import models from backend.schemas import ItemCreate, ItemOut, TagIdPayload, TagOut 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 @router.post("/", response_model=ItemOut) def create_item(payload: ItemCreate, db: Session = Depends(get_db)): # Demo: use first user or create one if none exists 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() # Create the item item = models.Item(user_id=user.id, name=payload.name) # 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) 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) 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) 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() @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) return item