feat: Phase 3-5 - workflow, labeling, reports, dashboard enhancement, tests
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
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
|
||||
Reference in New Issue
Block a user