Files
ai-worker-platform/backend/app/services/task_service.py
T

117 lines
3.7 KiB
Python

"""Task service: CRUD + assignment + status management."""
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from app.models.task import Task
from app.schemas.task import TaskCreate, TaskUpdate, TaskAssign
class TaskService:
@staticmethod
def list_tasks(
db: Session,
tenant_id: int,
project_id: Optional[int] = None,
status: Optional[str] = None,
assignee_id: Optional[int] = None,
skip: int = 0,
limit: int = 100,
) -> List[Task]:
q = db.query(Task).filter(Task.tenant_id == tenant_id)
if project_id:
q = q.filter(Task.project_id == project_id)
if status:
q = q.filter(Task.status == status)
if assignee_id:
q = q.filter(Task.assignee_id == assignee_id)
return q.order_by(Task.created_at.desc()).offset(skip).limit(limit).all()
@staticmethod
def get_task(db: Session, tenant_id: int, task_id: int) -> Optional[Task]:
return (
db.query(Task)
.filter(Task.id == task_id, Task.tenant_id == tenant_id)
.first()
)
@staticmethod
def create_task(
db: Session, tenant_id: int, project_id: int, req: TaskCreate
) -> Task:
task = Task(
tenant_id=tenant_id,
project_id=project_id,
title=req.title,
description=req.description,
status="pending",
priority=req.priority,
task_type=req.task_type,
input_data=req.input_data,
requires_review=req.requires_review,
assignee_id=req.assignee_id,
worker_id=req.worker_id,
due_date=req.due_date,
depends_on=req.depends_on,
)
db.add(task)
db.commit()
db.refresh(task)
return task
@staticmethod
def update_task(
db: Session, tenant_id: int, task_id: int, req: TaskUpdate
) -> Task:
task = TaskService.get_task(db, tenant_id, task_id)
if not task:
raise ValueError(f"Task #{task_id} not found")
for field, value in req.model_dump(exclude_unset=True).items():
setattr(task, field, value)
db.commit()
db.refresh(task)
return task
@staticmethod
def delete_task(db: Session, tenant_id: int, task_id: int) -> bool:
task = TaskService.get_task(db, tenant_id, task_id)
if not task:
return False
db.delete(task)
db.commit()
return True
@staticmethod
def assign_task(
db: Session, tenant_id: int, task_id: int, req: TaskAssign
) -> Task:
task = TaskService.get_task(db, tenant_id, task_id)
if not task:
raise ValueError(f"Task #{task_id} not found")
if req.assignee_id is not None:
task.assignee_id = req.assignee_id
if req.worker_id is not None:
task.worker_id = req.worker_id
if task.status == "pending":
task.status = "assigned"
db.commit()
db.refresh(task)
return task
@staticmethod
def mark_status(
db: Session, tenant_id: int, task_id: int, status: str, output: str = ""
) -> Task:
task = TaskService.get_task(db, tenant_id, task_id)
if not task:
raise ValueError(f"Task #{task_id} not found")
task.status = status
if output:
task.output_data = output
if status == "in_progress":
task.started_at = datetime.utcnow()
elif status in ("done", "review", "rejected", "cancelled"):
task.completed_at = datetime.utcnow()
db.commit()
db.refresh(task)
return task