"""Service layer for CoordWorkItem.""" from typing import Optional from uuid import UUID from fastapi import HTTPException, status from sqlalchemy.orm import Session from api.models.coord_work_item import CoordWorkItem from api.models.coord_workflow import CoordWorkflow from api.schemas.coord_work_item import CoordWorkItemCreate, CoordWorkItemUpdate def get_work_items( db: Session, workflow_id: Optional[str] = None, project_key: Optional[str] = None, status_filter: Optional[str] = None, assigned_session: Optional[str] = None, skip: int = 0, limit: int = 100, ) -> tuple[list[CoordWorkItem], int]: """Return paginated work items with optional filters.""" q = db.query(CoordWorkItem) if workflow_id: q = q.filter(CoordWorkItem.workflow_id == workflow_id) if project_key: q = q.filter(CoordWorkItem.project_key == project_key) if status_filter: q = q.filter(CoordWorkItem.status == status_filter) if assigned_session: q = q.filter(CoordWorkItem.assigned_session == assigned_session) total = q.count() items = q.order_by(CoordWorkItem.priority.desc(), CoordWorkItem.created_at.asc()).offset(skip).limit(limit).all() return items, total def get_work_item_by_id(db: Session, item_id: UUID) -> CoordWorkItem: """Return a single work item or raise 404.""" item = db.query(CoordWorkItem).filter(CoordWorkItem.id == str(item_id)).first() if not item: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Work item {item_id} not found" ) return item def create_work_item(db: Session, data: CoordWorkItemCreate) -> CoordWorkItem: """Create and persist a new work item, validating the parent workflow exists.""" workflow = db.query(CoordWorkflow).filter(CoordWorkflow.id == data.workflow_id).first() if not workflow: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Workflow {data.workflow_id} not found" ) try: item = CoordWorkItem(**data.model_dump()) db.add(item) db.commit() db.refresh(item) return item except Exception as e: db.rollback() raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to create work item: {e}" ) def update_work_item(db: Session, item_id: UUID, data: CoordWorkItemUpdate) -> CoordWorkItem: """Apply partial update to a work item.""" item = get_work_item_by_id(db, item_id) try: for field, value in data.model_dump(exclude_unset=True).items(): setattr(item, field, value) db.commit() db.refresh(item) return item except Exception as e: db.rollback() raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to update work item: {e}" ) def delete_work_item(db: Session, item_id: UUID) -> dict: """Delete a work item by ID.""" item = get_work_item_by_id(db, item_id) try: db.delete(item) db.commit() return {"message": "Work item deleted", "item_id": str(item_id)} except Exception as e: db.rollback() raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to delete work item: {e}" )