import uuid from fastapi import APIRouter, HTTPException, status from app.core.dependencies import CurrentUser, DbSession from app.schemas.box import BoxCreate, BoxRead, BoxSummary, BoxUpdate from app.services import boxes as boxes_service router = APIRouter(prefix="/api/v1/boxes", tags=["boxes"]) @router.get("", response_model=list[BoxSummary]) async def list_boxes( db: DbSession, search: str | None = None, root_only: bool = False ) -> list[BoxSummary]: items = await boxes_service.list_boxes(db, search=search, root_only=root_only) return [BoxSummary.model_validate(b) for b in items] @router.post("", response_model=BoxRead, status_code=status.HTTP_201_CREATED) async def create_box(db: DbSession, _: CurrentUser, data: BoxCreate) -> BoxRead: box = await boxes_service.create_box(db, data) return await boxes_service.build_box_read(db, box) @router.get("/{box_id}", response_model=BoxRead) async def get_box(db: DbSession, box_id: uuid.UUID) -> BoxRead: box = await boxes_service.get_box(db, box_id) if box is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Box not found") return await boxes_service.build_box_read(db, box) @router.put("/{box_id}", response_model=BoxRead) async def update_box(db: DbSession, _: CurrentUser, box_id: uuid.UUID, data: BoxUpdate) -> BoxRead: box = await boxes_service.get_box(db, box_id) if box is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Box not found") try: box = await boxes_service.update_box(db, box, data) except ValueError as exc: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) return await boxes_service.build_box_read(db, box) @router.delete("/{box_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_box(db: DbSession, _: CurrentUser, box_id: uuid.UUID) -> None: box = await boxes_service.get_box(db, box_id) if box is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Box not found") try: await boxes_service.delete_box(db, box) except ValueError as exc: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc))