from typing import Optional, List, Tuple from sqlalchemy.orm import Session from fastapi import HTTPException, status from app.models.project import ClassificationTask, ClassificationProject, ClassificationResult, TaskStatus, ResultStatus from app.models.metadata import DataColumn, DataTable, Database as MetaDatabase def get_task(db: Session, task_id: int) -> Optional[ClassificationTask]: return db.query(ClassificationTask).filter(ClassificationTask.id == task_id).first() def list_tasks( db: Session, project_id: Optional[int] = None, assignee_id: Optional[int] = None, status: Optional[str] = None, page: int = 1, page_size: int = 20, ) -> Tuple[List[ClassificationTask], int]: query = db.query(ClassificationTask) if project_id: query = query.filter(ClassificationTask.project_id == project_id) if assignee_id: query = query.filter(ClassificationTask.assignee_id == assignee_id) if status: query = query.filter(ClassificationTask.status == status) total = query.count() items = query.order_by(ClassificationTask.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all() return items, total def create_task( db: Session, project_id: int, name: str, assigner_id: int, assignee_id: int, target_type: str = "column", target_ids: Optional[str] = None, deadline: Optional[str] = None, ) -> ClassificationTask: from datetime import datetime db_obj = ClassificationTask( project_id=project_id, name=name, assigner_id=assigner_id, assignee_id=assignee_id, target_type=target_type, target_ids=target_ids, status=TaskStatus.PENDING.value, deadline=datetime.fromisoformat(deadline) if deadline else None, ) db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj def update_task_status(db: Session, task: ClassificationTask, status: str) -> ClassificationTask: task.status = status if status == TaskStatus.COMPLETED.value: from datetime import datetime task.completed_at = datetime.utcnow() db.commit() db.refresh(task) return task def assign_columns_to_task(db: Session, project_id: int, task_id: int, column_ids: List[int]) -> None: """Assign columns to a task by creating/updating classification results.""" from app.services.project_service import list_results for col_id in column_ids: result = db.query(ClassificationResult).filter( ClassificationResult.project_id == project_id, ClassificationResult.column_id == col_id, ).first() if not result: result = ClassificationResult( project_id=project_id, column_id=col_id, status=ResultStatus.AUTO.value, source="auto", confidence=0.0, ) db.add(result) db.commit() def get_task_label_items(db: Session, project_id: int, keyword: Optional[str] = None) -> List[dict]: """Get all label items for a project (used in task labeling view).""" query = db.query(ClassificationResult).filter(ClassificationResult.project_id == project_id) results = query.all() items = [] for r in results: col = r.column if not col: continue table = col.table database = table.database if table else None source = database.source if database else None items.append({ "result_id": r.id, "column_id": col.id, "column_name": col.name, "data_type": col.data_type, "comment": col.comment, "table_name": table.name if table else None, "database_name": database.name if database else None, "source_name": source.name if source else None, "category_id": r.category_id, "category_name": r.category.name if r.category else None, "level_id": r.level_id, "level_name": r.level.name if r.level else None, "level_color": r.level.color if r.level else None, "source": r.source, "confidence": r.confidence, "status": r.status, }) return items