任务看板与自动化

看板把「想做的事」变成「会被执行的事」:卡片带项目、智能体或工作流配置,进入待办后由执行器接手;状态推进、运行记录与评论回流都走同一条服务链路。前端没有专用 SSE,靠条件轮询把运行中的变化拉回来。

Backlog → Todo / Archived Todo 唯一会触发执行的状态 InProgress 执行器运行中 InReview 评论回流重跑 Done 写 CompletedAt 状态流转必须先过白名单校验 非法迁移直接拒绝 Blocked 进入写 BlockedReason,离开清空 前端刷新:当存在 Running / WaitingAnswer 或「有自动化且在 Todo / InProgress」时,每 3 秒轮询列表与详情;条件不成立则停止轮询
状态机是白名单式的:只有合法迁移会被接受;Todo 是唯一的自动化触发点,Done / Archived 只是写时间戳。

状态机

状态允许迁移到
BacklogTodo · Archived
TodoInProgress · Backlog · Blocked
InProgressInReview · Todo · Blocked
InReviewDone · InProgress · Blocked
BlockedTodo · InProgress
DoneArchived · 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}单卡查询 / 删除

自动化与状态推进

  1. 触发点在三处:新建后、更新后(状态变更)、换列到 Todo;另有评论回流与手动重跑。
  2. 真正执行只有一个门槛:状态必须是 Todo 且有自动化配置;否则只改状态不执行。
  3. 执行前写入一条运行记录(Trigger 标明来源:创建 / 移动 / 评论 / 重跑),执行过程产生步骤与评论。
  4. 状态推进由服务层完成;运行失败写入运行记录的 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。
  • 轮询有条件、不是常开:页面长时间不动是设计如此(没有运行中任务时不该持续请求)。
  • 项目智能体与自定义提示词二选一:选了智能体,手填的提示词不会保存。