Files
2026-07-13 13:32:32 +08:00

116 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Legacy 兼容路由 — 通过旧版 task_id (JJC-xxx) 操作任务。
旧版 kanban_update.py 使用自定义 ID (JJC-20260301-007)
Edict 使用 UUID。此路由通过 tags 或 meta.legacy_id 映射。from __future__ import annotations"""
import logging
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from ..db import get_db
from ..models.task import Task, TaskState
from ..services.event_bus import get_event_bus
from ..services.task_service import TaskService
log = logging.getLogger("edict.api.legacy")
router = APIRouter()
async def _find_by_legacy_id(db: AsyncSession, legacy_id: str) -> Task | None:
"""通过旧版 ID 查找任务(在 tags 或 meta.legacy_id 中搜索)。"""
# 方式1: tags 包含 legacy_id
stmt = select(Task).where(Task.tags.contains([legacy_id]))
result = await db.execute(stmt)
task = result.scalars().first()
if task:
return task
# 方式2: meta->legacy_id
stmt2 = select(Task).where(Task.meta["legacy_id"].astext == legacy_id)
result2 = await db.execute(stmt2)
return result2.scalars().first()
class LegacyTransition(BaseModel):
new_state: str
agent: str = "system"
reason: str = ""
class LegacyProgress(BaseModel):
agent: str
content: str
class LegacyTodoUpdate(BaseModel):
todos: list[dict]
@router.post("/by-legacy/{legacy_id}/transition")
async def legacy_transition(
legacy_id: str,
body: LegacyTransition,
db: AsyncSession = Depends(get_db),
):
task = await _find_by_legacy_id(db, legacy_id)
if not task:
raise HTTPException(status_code=404, detail=f"Legacy task not found: {legacy_id}")
bus = await get_event_bus()
svc = TaskService(db, bus)
try:
new_state = TaskState(body.new_state)
except ValueError:
raise HTTPException(status_code=400, detail=f"Invalid state: {body.new_state}")
try:
t = await svc.transition_state(task.task_id, new_state, body.agent, body.reason)
return {"task_id": str(t.task_id), "state": t.state.value}
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@router.post("/by-legacy/{legacy_id}/progress")
async def legacy_progress(
legacy_id: str,
body: LegacyProgress,
db: AsyncSession = Depends(get_db),
):
task = await _find_by_legacy_id(db, legacy_id)
if not task:
raise HTTPException(status_code=404, detail=f"Legacy task not found: {legacy_id}")
bus = await get_event_bus()
svc = TaskService(db, bus)
await svc.add_progress(task.task_id, body.agent, body.content)
return {"message": "ok"}
@router.put("/by-legacy/{legacy_id}/todos")
async def legacy_todos(
legacy_id: str,
body: LegacyTodoUpdate,
db: AsyncSession = Depends(get_db),
):
task = await _find_by_legacy_id(db, legacy_id)
if not task:
raise HTTPException(status_code=404, detail=f"Legacy task not found: {legacy_id}")
bus = await get_event_bus()
svc = TaskService(db, bus)
await svc.update_todos(task.task_id, body.todos)
return {"message": "ok"}
@router.get("/by-legacy/{legacy_id}")
async def legacy_get(
legacy_id: str,
db: AsyncSession = Depends(get_db),
):
task = await _find_by_legacy_id(db, legacy_id)
if not task:
raise HTTPException(status_code=404, detail=f"Legacy task not found: {legacy_id}")
return task.to_dict()