diff --git a/src/api/blackboard_routes.py b/src/api/blackboard_routes.py index 1eed571..43c8ac4 100644 --- a/src/api/blackboard_routes.py +++ b/src/api/blackboard_routes.py @@ -91,9 +91,39 @@ async def claim_task(project_id: str, task_id: str, body: Dict[str, Any]): async def update_status(project_id: str, task_id: str, body: Dict[str, Any]): bb = _bb(project_id) old_task = bb.get_task(task_id) - if not bb.update_task_status(task_id, body["status"], + if not old_task: + raise HTTPException(404, { + "error": "not_found", + "detail": f"Task {task_id} not found in project {project_id}", + }) + + new_status = body.get("status") + if not new_status: + raise HTTPException(422, { + "error": "validation_failed", + "detail": "Missing required field: status", + "valid_values": {"status": sorted(VALID_STATUSES)}, + }) + + # 检查转换是否合法 + from src.blackboard.db import VALID_TRANSITIONS + current = old_task.status + allowed = VALID_TRANSITIONS.get(current, set()) + if new_status not in allowed: + raise HTTPException(409, { + "error": "invalid_transition", + "detail": f"Cannot transition from {current} to {new_status}", + "valid_transitions": {current: sorted(allowed)}, + "hint": f"From '{current}', valid targets are: {sorted(allowed)}", + }) + + if not bb.update_task_status(task_id, new_status, agent=body.get("agent")): - raise HTTPException(409, f"Invalid transition to {body['status']}") + raise HTTPException(409, { + "error": "transition_failed", + "detail": f"Status update failed for {task_id}", + }) + # SSE 推送 try: from src.api.sse_routes import get_broker @@ -101,13 +131,13 @@ async def update_status(project_id: str, task_id: str, body: Dict[str, Any]): broker.publish_sync("task_updated", { "project_id": project_id, "task_id": task_id, - "old_status": old_task.status if old_task else None, - "new_status": body["status"], + "old_status": current, + "new_status": new_status, "agent": body.get("agent"), }) except Exception: - pass # SSE 是可选的,不影响主流程 - return {"ok": True} + pass + return {"ok": True, "old_status": current, "new_status": new_status} # --- Comments ---