任务看板与自动化
看板把「想做的事」变成「会被执行的事」:卡片带项目、智能体或工作流配置,进入待办后由执行器接手;状态推进、运行记录与评论回流都走同一条服务链路。前端没有专用 SSE,靠条件轮询把运行中的变化拉回来。
状态机
| 状态 | 允许迁移到 |
|---|---|
Backlog | Todo · Archived |
Todo | InProgress · Backlog · Blocked |
InProgress | InReview · Todo · Blocked |
InReview | Done · InProgress · Blocked |
Blocked | Todo · InProgress |
Done | Archived · InReview |
Archived | (终态) |
迁移表是硬编码白名单,非法跳转直接拒绝。时间戳由统一逻辑维护:进入 Done 写 CompletedAt、离开则清空;进入 Archived 写 ArchivedAt、离开则清空;进入 Blocked 保留或写入 BlockedReason,离开时清空。优先级枚举是 Low / Medium / High / Urgent。
卡片数据模型
| 分组 | 字段 |
|---|---|
| 基本 | Id · Title · Description · Status · Priority · Assignee · Tags · DueDate · SortOrder · BlockedReason · CompletedAt · ArchivedAt |
| 配置 | ProjectId / ProjectName · AgentId / AgentName · AgentPrompt / AgentPromptName · WorkflowId / WorkflowName |
| 运行与协作 | HasAutomation · LastRunStatus · LastRunId · CommentCount |
| 评论 | KanbanTaskCommentDto:AuthorType · AuthorName · Content · RunId · CreatedAt |
| 运行记录 | KanbanTaskRunDto:Kind · Trigger · Status · Input · Output · Error · WorkflowRunId · StartedAt · CompletedAt |
| 详情聚合 | KanbanTaskDetailDto = 任务 + 评论 + 运行记录 + 步骤(Steps) |
HasAutomation 的判定是「配了项目智能体 或 工作流 或 自定义提示词」三者之一。AgentPrompt / AgentPromptName 只在没有选项目智能体(AgentId 为空)时保存——这就是「从项目 .github 里选智能体」与「手填提示词」两条路径的落库差异。
端点
| 端点 | 用途 |
|---|---|
GET /api/kanban-tasks | 看板数据:七列 + 统计(Archived 列只回最近 7 天归档的任务) |
POST /api/kanban-tasks · PUT /api/kanban-tasks/{id} | 新建 / 更新;保存后若状态是 Todo 会尝试触发自动化 |
PUT /api/kanban-tasks/{id}/move | 拖拽换列:先校验迁移白名单,再维护时间戳,进入 Todo 时触发自动化 |
GET /api/kanban-tasks/{id}/detail | 详情聚合(任务 + 评论 + 运行 + 步骤) |
POST /api/kanban-tasks/{id}/comments | 评论;在 InReview / Blocked 且开启「评论触发自动化」时把任务拉回 InProgress 并重跑(触发原因是 Comment) |
POST /api/kanban-tasks/{id}/rerun | 仅 Todo 状态允许重跑 |
GET /api/kanban-tasks/{id} · DELETE /api/kanban-tasks/{id} | 单卡查询 / 删除 |
自动化与状态推进
- 触发点在三处:新建后、更新后(状态变更)、换列到
Todo;另有评论回流与手动重跑。 - 真正执行只有一个门槛:状态必须是
Todo且有自动化配置;否则只改状态不执行。 - 执行前写入一条运行记录(
Trigger标明来源:创建 / 移动 / 评论 / 重跑),执行过程产生步骤与评论。 - 状态推进由服务层完成;运行失败写入运行记录的
Error与任务上的LastRunStatus。
「看板会自动更新状态吗」的准确回答是:状态推进由后端在触发点写入(换列、评论回流、执行器回写),前端负责把变化拉回来显示。手动把卡片拖到
InProgress 只是改状态,不会自行开始执行。详情回填与前端刷新
| 项 | 规则 |
|---|---|
| 名称回填 | 列表与详情都会补 ProjectName(受管项目)、AgentName(项目智能体)、WorkflowName、LastRunStatus、CommentCount;列表用批量字典查询避免 N+1 |
| 展示回退 | 项目行:projectId ? projectName ?? projectId;智能体行:agentId || agentPromptName 任一存在即展示 agentName ?? agentPromptName ?? agentId,都没有才显示「未指定」;工作流行同理 |
| 详情排序 | 步骤按 Sequence 再按创建时间;运行记录按创建时间倒序;评论按创建时间正序 |
| 轮询条件 | 看板与详情都在「存在 Running / WaitingAnswer 的运行,或任务有自动化且状态是 Todo / InProgress」时每 3000ms 轮询一次;条件不成立即停止 |
| 刷新通道 | React Query 轮询 + 失效重取;没有任务看板专用 SSE 事件 |
「配置了项目和智能体但详情不展示」这类问题通常出在展示回退上:卡片是从项目 .github 里选的智能体时,落库的是 AgentPrompt / AgentPromptName 而非 AgentId,只看 AgentId 就会显示为空。当前实现已把两种来源都纳入展示(选择项目后自动加载该项目 .github 智能体列表并写回提示词字段)。
统计与归档
- 统计字段:
Total/Active/Done/Archived/Overdue/DueSoon。 - 归档列只保留 7 天窗口内的任务,避免看板无限膨胀;完整历史要靠运行记录与评论。
实作要点
- 自动化只在
Todo触发:想让卡片跑起来,就把它放进待办列,而不是拖到进行中。 - 评论是「回路」而不是备注:在评审 / 阻塞列评论会带着上下文重跑,等于把反馈写回 agent。
- 轮询有条件、不是常开:页面长时间不动是设计如此(没有运行中任务时不该持续请求)。
- 项目智能体与自定义提示词二选一:选了智能体,手填的提示词不会保存。