新增: 文档(任务推进链实施路径+任务模块分析+审查报告+patch_file指南)
This commit is contained in:
516
docs/05-代码审查/任务执行与推进能力分析-2026-06-16.md
Normal file
516
docs/05-代码审查/任务执行与推进能力分析-2026-06-16.md
Normal file
@@ -0,0 +1,516 @@
|
||||
# 任务执行能力与推进能力分析
|
||||
|
||||
> **日期**: 2026-06-16
|
||||
> **范围**: 任务实体在 DevFlow 系统中的定位、执行链路、推进能力全景分析
|
||||
> **关联文档**: `任务推进构想-2026-06-14.md` / `业务系统设计-2026-06-12.md` / `AI对话引擎-2026-06-14.md` / `DAG引擎详解-2026-06-14.md` / `任务模块问题分析-2026-06-16.md`
|
||||
|
||||
---
|
||||
|
||||
## 〇、核对结论速览(2026-06-16 · Explore 代理并行取证)
|
||||
|
||||
> 本报告系架构分析,含密集代码事实断言。经 2 个代理逐项取证,12 项断言中 **10 真 / 1 部分真 / 1 假(重大)**。核心论点(任务能存不能推进 / nodes 未接入 / 无回调)成立,但**一处工具缺失论据错误**(见下方纠正)。
|
||||
|
||||
### 真伪矩阵
|
||||
|
||||
| # | 断言 | 核实 | 证据 |
|
||||
|---|------|------|------|
|
||||
| 1 | workflow.rs task_id 恒 None | ✅真 | `workflow.rs:56`,全局无写入点 |
|
||||
| 2 | workflow_def_id 从未写入 | ✅真 | `task.rs:73` None,crud 有 UPDATE 语句但无调用 |
|
||||
| 3 | AI 缺 update_task / run_command | ❌**假** | `update_task`(tool_registry.rs:348) + `run_command`(:468) **均存在**,仅缺 `advance_task` |
|
||||
| 4 | df-task crate 已删除 | ✅真 | `ARCHITECTURE.md:89-90`,crates/ 无 df-task |
|
||||
| 5 | DAG 完成无任务回调 | ✅真 | `executor.rs:169-172` 仅 emit WorkflowCompleted,无监听推进 task |
|
||||
| 6 | 任务无独立业务层 | ✅真 | `task.rs` 直连 Repository,无状态机/推进逻辑 |
|
||||
| 7 | AiNode 未接入任务推进 | ✅真 | `ai_node.rs:331`(~12.7KB)完整,无任务推进 DAG 模板 |
|
||||
| 8 | HumanNode 未接入任务推进 | ✅真 | `human_node.rs:640`(~27.7KB)完整,无任务审批 DAG 模板 |
|
||||
| 9 | ProjectDetail 工作流入口下线 | ✅真 | `ProjectDetail.vue:289-292` 注释 R-PD-2,script 节点不注册 |
|
||||
| 10 | 前端无推进入口 | ✅真 | Tasks.vue 纯展示 / TaskDetail.vue 纯只读 |
|
||||
| 11 | 状态枚举三方不一致 | ⚠️部分真 | 后端7态 / 前端5态(merged) / 构想5态(done);前端 vs 构想 `merged`≠`done` 微差 |
|
||||
| 12 | advance_task / can_transition_to / review_rounds 全未实现 | ✅真 | Rust+TS 全局搜零定义,TaskRecord 无 review_rounds 字段 |
|
||||
|
||||
### ⚠️ 关键纠正(影响多处结论)
|
||||
|
||||
报告第二章 2.2「缺失关键工具」、第四章断裂点 2/3 称 **「AI 缺 update_task / run_command 工具」——核实为假**:
|
||||
- `update_task`(tool_registry.rs:348)**存在**,AI 能改任务字段(含 status,经裸 update_field 非状态机收口)
|
||||
- `run_command`(tool_registry.rs:468)**存在且有完整 Shell 执行实现**,AI 能写代码也能跑命令
|
||||
- 真正缺失的仅 `advance_task`(推进链触发器)
|
||||
|
||||
**修正后结论**:AI **能**更新任务状态、**能**运行命令,但仍**不能**:① 触发三闘门推进链(无 advance_task)② 联动工作流(task_id=None + 无完成回调)。报告核心论点「任务能存不能(自动)执行/推进」成立,但「AI 缺 update_task/run_command」的具体论据错误,断裂点 2/3 已在正文中纠正标注。
|
||||
|
||||
---
|
||||
|
||||
## 一、任务在 DevFlow 中的设计定位
|
||||
|
||||
### 1.1 产品旅程中的位置
|
||||
|
||||
```
|
||||
想法池 ──晋升──▶ 项目 ──拆解──▶ 任务 ──执行──▶ 工作流(DAG)
|
||||
(Idea) (Project) (Task) (Workflow)
|
||||
第一公民 容器/上下文 执行单元 编排引擎
|
||||
```
|
||||
|
||||
DevFlow 的核心价值链是 **「想法 → 项目 → 任务 → 工作流」**,任务是从「规划」到「执行」的转折点:
|
||||
|
||||
- **想法**是「做什么」的候选池(评估/筛选/晋升)
|
||||
- **项目**是「在哪个上下文做」(目录绑定/技术栈/状态)
|
||||
- **任务**是「具体做什么」(标题/描述/状态/优先级/分支)
|
||||
- **工作流**是「怎么自动做」(DAG 编排 AI/Script/Human 节点)
|
||||
|
||||
### 1.2 设计意图:AI-First 推进链
|
||||
|
||||
`任务推进构想-2026-06-14.md` 定义了任务的终极形态:
|
||||
|
||||
```
|
||||
todo ──AI执行──▶ in_progress ──AI自审──▶ review_ready ──人工核对──▶ done
|
||||
AiNode AiNode HumanNode
|
||||
AI 干活 AI 审 AI 的活 人最终把关 AI 产出
|
||||
```
|
||||
|
||||
核心设计原则:
|
||||
- **人从「操作者」转为「审批者」** — 任务由 AI 执行,人监督 AI
|
||||
- **advance_task 默认 AI 触发** — AI 执行/自审完成自动推进
|
||||
- **三闸门必需** — AI 执行 / AI 自审 / 人工核对各有关卡
|
||||
- **拒绝 → 退回 AI 重做** — 不是退回给人干
|
||||
|
||||
### 1.3 实际现状:设计 vs 实现的巨大鸿沟
|
||||
|
||||
| 维度 | 设计意图 | 实际实现 |
|
||||
|------|---------|---------|
|
||||
| 状态推进 | advance_task 状态机 + 三闸门 DAG | ❌ 不存在 advance_task,status 可被任意修改 |
|
||||
| AI 执行 | AiNode/agent 读任务→写代码→跑测试→产出 diff | ❌ AiNode 存在但未接入任务推进链 |
|
||||
| AI 自审 | AiNode 结构化 verdict (pass/warn/block) | ❌ 未实现 |
|
||||
| 人工核对 | HumanNode 审批闭环 | ⚠️ HumanNode 存在但未接入任务推进链 |
|
||||
| 状态机收口 | status 白名单移除,advance_task 唯一入口 | ❌ status 仍在白名单,任意可改 |
|
||||
| 工作流联动 | task → workflow 双向关联 | ❌ workflow 的 task_id 恒为 None |
|
||||
| 前端推进 UI | 推进按钮 + 环节可视化 + diff 展示 | ❌ 纯只读,无任何推进入口 |
|
||||
|
||||
**结论:任务模块目前是一个「数据容器」,不是「执行单元」。它能存、能查、能删,但不能推进、不能执行、不能联动工作流。**
|
||||
|
||||
---
|
||||
|
||||
## 二、执行能力分析
|
||||
|
||||
### 2.1 任务「执行」的定义
|
||||
|
||||
在 DevFlow 的 AI-First 愿景中,「执行任务」意味着:
|
||||
|
||||
```
|
||||
1. 读取任务描述 + 项目上下文
|
||||
2. AI 写代码/改文件/跑测试(agent 多步)
|
||||
3. 产出 diff / 文件变更 / 测试结果
|
||||
4. AI 自审产出(code review,结构化结论)
|
||||
5. 人工最终核对
|
||||
```
|
||||
|
||||
### 2.2 当前执行能力盘点
|
||||
|
||||
#### ❌ 任务 → 工作流:无连接
|
||||
|
||||
```rust
|
||||
// commands/workflow.rs — run_workflow 中 task_id 恒为 None
|
||||
task_id: None, // 唯一引用点,硬编码 None
|
||||
```
|
||||
|
||||
工作流执行**完全不感知任务**。`WorkflowRecord` 有 `task_id` 字段(V2 迁移加的),但没有任何代码写入它。工作流是独立运行的,不知道自己在为哪个任务工作。
|
||||
|
||||
#### ❌ AI 对话 → 任务执行:无闭环
|
||||
|
||||
AI 对话引擎有 12 个工具,其中任务相关:
|
||||
- `list_tasks`(Low 风险,自动执行)— 只读
|
||||
- `create_task`(Medium 风险,需审批)— 只创建
|
||||
|
||||
**缺失的关键工具**:
|
||||
- ❌ 无 `update_task` 工具 — AI 不能推进任务状态
|
||||
- ❌ 无 `advance_task` 工具 — AI 不能触发推进链
|
||||
- ❌ 无 `run_command` 工具 — AI 能写代码但不能跑("能写不能跑")
|
||||
- ❌ `run_workflow` 工具是空壳 — AI 不能在对话中触发工作流
|
||||
|
||||
AI 可以 **创建任务**,但不能 **执行任务**、**推进任务**、**关联工作流**。
|
||||
|
||||
#### ❌ 工作流节点 → 任务状态:无联动
|
||||
|
||||
```
|
||||
DAG 执行完成
|
||||
│
|
||||
▼
|
||||
WorkflowRecord.status = "completed"
|
||||
│
|
||||
▼
|
||||
(结束 — 不回调任务状态,不触发 advance_task)
|
||||
```
|
||||
|
||||
DAG 引擎有完善的执行能力(拓扑排序/并发/状态机/事件总线),但执行结果**不回写任务**。一个工作流跑完了,关联的任务状态纹丝不动。
|
||||
|
||||
#### ⚠️ AiNode:有能力但没接入
|
||||
|
||||
```rust
|
||||
// ai_node.rs — 12.7KB,完整实现
|
||||
// 能力:调用 LLM(OpenAI/Anthropic),config 驱动,支持上游输入
|
||||
// 但:只在 DAG 内可用,没有「为某个任务执行」的入口
|
||||
```
|
||||
|
||||
AiNode 是通用的 LLM 调用节点,可以做分析/生成/审查。但当前没有任何 DAG 模板把 AiNode 接入任务推进链。
|
||||
|
||||
#### ⚠️ HumanNode:有能力但没接入
|
||||
|
||||
```rust
|
||||
// human_node.rs — 27.7KB,完整实现
|
||||
// 能力:阻塞等待人工审批(subscribe→send→select!),支持单选/多选
|
||||
// 但:只在 DAG 内可用,没有「为某个任务审批」的入口
|
||||
```
|
||||
|
||||
### 2.3 执行能力总结
|
||||
|
||||
| 执行环节 | 需要的能力 | 现状 | 缺口 |
|
||||
|---------|-----------|------|------|
|
||||
| 读取任务上下文 | 任务描述 + 项目目录 + 相关文件 | ✅ AI 工具可读 | — |
|
||||
| AI 写代码 | write_file 工具 | ✅ 有(需审批) | — |
|
||||
| AI 跑测试 | run_command 工具 | ❌ 不存在 | AI "能写不能跑" |
|
||||
| AI 自审 | AiNode verdict 结构化输出 | ❌ 未实现 | 需定义 prompt + 解析 |
|
||||
| 触发工作流 | run_workflow 工具 | ❌ 空壳 | 需实装 |
|
||||
| 工作流回写任务 | 完成回调 advance_task | ❌ 不存在 | 需实现回调链路 |
|
||||
| 人工审批 | HumanNode 审批 | ⚠️ 存在但未接入 | 需 DAG 模板 + 路由 |
|
||||
|
||||
**核心断链**:任务 ←✕→ 工作流 ←✕→ AI 执行。三个系统各自独立运行,没有形成闭环。
|
||||
|
||||
---
|
||||
|
||||
## 三、推进能力分析
|
||||
|
||||
### 3.1 当前推进机制:裸 status 字段 + 无保护
|
||||
|
||||
```rust
|
||||
// commands/task.rs — update_task
|
||||
// status 在白名单中,任意调用方可直接修改
|
||||
state.tasks.update_field(&id, "status", &value)
|
||||
```
|
||||
|
||||
任何人(AI/用户/脚本)可以一行代码把任务从 `todo` 直接改成 `done`,跳过所有闸门。这是 `任务推进构想` 文档中标注的 **P0 致命漏洞**。
|
||||
|
||||
### 3.2 设计中的推进机制:advance_task + 状态机
|
||||
|
||||
> ⚠️ **决策更新(2026-06-16)**:本节原设想 advance_task 落 IPC 层 / df-task 复活。**D-260616-03 已决策走 df-nodes Node**(对齐 D3「业务逻辑在 df-nodes 实现」):状态机落 `df-nodes/src/task_state_machine.rs`(F-01),advance_task 落 `df-nodes/src/task_advance_node.rs` 实现 Node trait(F-02),IPC 层 thin 入口调 df-nodes。又 **D-260616-01 已定前端对齐 7 态**,下文状态机示例的 5 态(ReviewReady/Abandoned)实施时按 7 态重设(激活 InReview/Testing/Blocked)。详见 [任务推进链实施路径](../../02-架构设计/任务推进链实施路径-2026-06-16.md)。
|
||||
|
||||
构想文档设计了完整的推进链,但**全部未实现**:
|
||||
|
||||
#### 状态机(can_transition_to)
|
||||
|
||||
```rust
|
||||
// 设计中 — 未实现
|
||||
(Todo, InProgress | Abandoned) => true,
|
||||
(InProgress, ReviewReady | Abandoned) => true,
|
||||
(ReviewReady, Done | Abandoned | InProgress) => true, // 可退回
|
||||
_ => false,
|
||||
```
|
||||
|
||||
#### 状态机下沉 SQL(防 TOCTOU)
|
||||
|
||||
```sql
|
||||
-- 设计中 — 未实现
|
||||
UPDATE tasks SET status=:new, updated_at=:now
|
||||
WHERE id=:id AND status=:expected -- affected_rows==0 即状态已变,拒绝
|
||||
```
|
||||
|
||||
#### advance_task 命令
|
||||
|
||||
```
|
||||
设计中 — 未实现
|
||||
1. 校验状态转换合法性(can_transition_to)
|
||||
2. 原子写入(下沉 SQL WHERE 前置)
|
||||
3. 触发对应闸门工作流(start/ready/merge)
|
||||
4. 工作流完成回调再推进状态
|
||||
5. 失败路径处理(退回/保持)
|
||||
```
|
||||
|
||||
#### loop 管理
|
||||
|
||||
```
|
||||
设计中 — 未实现
|
||||
review_rounds: i32 -- 退回时 +1,任务卡显示「第 N 轮 review」
|
||||
```
|
||||
|
||||
### 3.3 推进能力总结
|
||||
|
||||
| 推进环节 | 设计方案 | 实现状态 |
|
||||
|---------|---------|---------|
|
||||
| 状态机定义 | 7 态 / 5 态(待统一) | ❌ 无 can_transition_to |
|
||||
| 状态机收口 | 移除 status 白名单 | ❌ status 仍可任意改 |
|
||||
| advance_task 命令 | 唯一 status 写入路径 | ❌ 不存在 |
|
||||
| 状态机下沉 SQL | WHERE 前置防 TOCTOU | ❌ 不存在 |
|
||||
| AI 执行闸门 | AiNode 最小形态 | ❌ 未接入 |
|
||||
| AI 自审闸门 | AiNode verdict | ❌ 未实现 |
|
||||
| 人工核对闸门 | HumanNode 审批 | ❌ 未接入 |
|
||||
| 失败路径 | 退回/保持/重做 | ❌ 未实现 |
|
||||
| loop 管理 | review_rounds | ❌ 字段不存在 |
|
||||
| 并发护栏 | per-task 互斥锁 | ❌ 不存在 |
|
||||
| 崩溃恢复 | 孤儿清理 + 审批持久化 | ⚠️ 部分存在(审批持久化有,孤儿清理无) |
|
||||
| 前端推进 UI | 按钮 + 可视化 | ❌ 纯只读 |
|
||||
|
||||
**推进能力实现度:0%。全部停留在构想文档阶段。**
|
||||
|
||||
---
|
||||
|
||||
## 四、任务与其他系统的断裂点
|
||||
|
||||
### 4.1 断裂全景图
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ 想法池 │──✅晋升──│ 项目 │──✅拆解──│ 任务 │──✕✕✕──│ 工作流 │
|
||||
│ (Idea) │ │(Project) │ │ (Task) │ │(Workflow)│
|
||||
└──────────┘ └──────────┘ └────┬─────┘ └────┬─────┘
|
||||
│ │
|
||||
┌────┴─────┐ ┌────┴─────┐
|
||||
│ AI 对话 │ │ DAG 引擎 │
|
||||
│ (Agentic)│ │(Executor)│
|
||||
└──────────┘ └──────────┘
|
||||
│ │
|
||||
✕ 无 update_task ✕ task_id=None
|
||||
✕ 无 advance_task ✕ 无完成回调
|
||||
✕ 无 run_command ✕ 无状态回写
|
||||
✕ run_workflow=空壳 ✕ 无任务路由
|
||||
```
|
||||
|
||||
### 4.2 六大断裂点详解
|
||||
|
||||
#### 断裂点 1:任务 ↔ 工作流(task_id = None)
|
||||
|
||||
```rust
|
||||
// commands/workflow.rs:56
|
||||
task_id: None, // 硬编码
|
||||
```
|
||||
|
||||
工作流不知道为哪个任务执行,任务不知道被哪个工作流处理。`TaskRecord.workflow_def_id` 字段存在但从未被写入。
|
||||
|
||||
**影响**:工作流执行结果无法回写任务状态,无法实现「工作流完成 → 自动推进任务」。
|
||||
|
||||
#### 断裂点 2:AI 对话 ↔ 任务推进(无 advance_task 工具)
|
||||
|
||||
> ⚠️ **核对纠正**:原报告称「无 update_task 工具」——**核实为假**,`update_task`(tool_registry.rs:348)存在。AI 工具集实际仅缺 `advance_task`(推进链触发器)。AI 能经裸 `update_task` 改 status 字段(无状态机收口,B-260616-15/16 同源),但不能触发三闸门推进链。
|
||||
|
||||
AI 工具集有 `create_task` / `update_task` 但没有 `advance_task`。AI 能创建/改任务但不能触发推进链。
|
||||
|
||||
**影响**:AI 在对话中分析了任务、写了代码、跑了测试,但无法经「合法状态机路径」把任务从 `todo` 推进到 `done`,只能裸改 status(旁路闸门)。
|
||||
|
||||
#### 断裂点 3:~~AI 对话 ↔ 命令执行(无 run_command)~~ 【⚠️ 核对为假,本断裂点不成立】
|
||||
|
||||
> ⚠️ **核对纠正**:`run_command`(tool_registry.rs:468)**实际存在且有完整 Shell 执行实现**。AI 有 `write_file` 也有 `run_command`,能写代码也能跑命令,「写→跑→改」闭环成立。(注:`run_command` 属高危需审批工具,见 AE-2025-04 会话级授权;其 stdout/stderr 恒空问题见 B-260616 系列另报。)
|
||||
|
||||
~~AI 有 `write_file` 但没有 `run_command`。AI 写了代码但无法运行验证。~~
|
||||
|
||||
**影响**:~~AI 执行链断裂在「写→跑→改」的「跑」环节~~ **不成立**。AI 执行链在命令执行环节闭合。
|
||||
|
||||
#### 断裂点 4:AI 对话 ↔ 工作流(run_workflow 空壳)
|
||||
|
||||
```rust
|
||||
// tool_registry.rs — run_workflow 工具是 no-op 桩
|
||||
// 返回提示信息,不真正执行工作流
|
||||
```
|
||||
|
||||
**影响**:AI 不能在对话中触发工作流来自动化任务执行。对应已有任务 `R-PD-12`。
|
||||
|
||||
#### 断裂点 5:工作流完成 → 任务状态(无回调)
|
||||
|
||||
DAG 执行器有 `WorkflowCompleted` 事件,但没有回调机制把这个事件转化为任务状态推进。
|
||||
|
||||
**影响**:即使工作流成功执行了 AI 执行 + AI 自审,任务状态仍然是 `todo`。
|
||||
|
||||
#### 断裂点 6:前端 ↔ 推进操作(无 UI 入口)
|
||||
|
||||
Tasks.vue 是纯展示,TaskDetail.vue 是纯只读。没有任何按钮/操作可以推进任务状态。
|
||||
|
||||
**影响**:用户只能通过 AI 对话(如果 AI 有工具的话)或直接 API 调用来推进任务,但前者缺工具、后者不暴露 UI。
|
||||
|
||||
---
|
||||
|
||||
## 五、核心矛盾分析
|
||||
|
||||
### 矛盾 1:状态枚举三方不一致
|
||||
|
||||
| 层面 | 状态集 | 语义导向 |
|
||||
|------|--------|---------|
|
||||
| 后端 enum | todo/in_progress/in_review/testing/done/blocked/cancelled | 通用软件工程 |
|
||||
| 前端常量 | todo/in_progress/review_ready/merged/abandoned | Git 工作流 |
|
||||
| 推进构想 | todo/in_progress/review_ready/done/abandoned | AI-First 推进链 |
|
||||
|
||||
三方各执一词,且推进构想的 5 态与前端常量一致但与后端 enum 不一致。**在推进链实现前必须先统一状态集**,否则状态机无法定义。
|
||||
|
||||
### 矛盾 2:df-task crate 已删除但任务无独立业务层
|
||||
|
||||
```
|
||||
ARCHITECTURE.md: 5.3.1 ~~Task & Branch Manager (df-task)~~ — 已移除
|
||||
> 2026-06-14 零引用清理:df-task crate 已删除
|
||||
```
|
||||
|
||||
对比其他实体:
|
||||
- **Idea** → 有 `df-ideas` crate(评估/晋升/对抗)
|
||||
- **Project** → 有 `df-project` crate(扫描/管理)
|
||||
- **Task** → ❌ 无独立 crate,IPC 层直连 CRUD
|
||||
|
||||
任务没有业务逻辑层,`commands/task.rs` 直接调 `state.tasks.insert/query/update_field/delete`。这意味着:
|
||||
- 状态机逻辑无处安放(只能塞 IPC 层或重新建 crate)
|
||||
- 推进链编排无处安放
|
||||
- 与其他系统的联动逻辑无处安放
|
||||
|
||||
### 矛盾 3:工作流引擎完善但无业务消费
|
||||
|
||||
DAG 引擎功能完善(拓扑排序/并发执行/状态机/事件总线/审批闭环/取消机制),但**没有任何业务场景在使用它**:
|
||||
- ProjectDetail.vue 的工作流演示入口已下线(R-PD-2:script 节点不再注册)
|
||||
- run_workflow AI 工具是空壳
|
||||
- 任务推进链未接入
|
||||
|
||||
引擎是「准备好了但没有乘客的列车」。
|
||||
|
||||
### 矛盾 4:AI 能力在增长但无法触达任务
|
||||
|
||||
AI 对话引擎是系统中最活跃的模块(Agentic Loop / 12 工具 / 审批门控 / 知识库集成 / 多 Provider),但它的能力**无法触达任务执行**:
|
||||
- AI 能读项目代码、能写文件、能创建任务/项目/灵感
|
||||
- 但不能推进任务、不能触发工作流、不能运行命令
|
||||
- AI 的「手」伸到了文件系统,但伸不到任务状态机和工作流引擎
|
||||
|
||||
---
|
||||
|
||||
## 六、能力成熟度评估
|
||||
|
||||
### 按维度评分(满分 5 分)
|
||||
|
||||
| 维度 | 评分 | 说明 |
|
||||
|------|------|------|
|
||||
| **数据存储** | ⭐⭐⭐⭐ | CRUD 完整,SQLite 持久化,字段丰富 |
|
||||
| **数据查询** | ⭐⭐⭐ | 基本查询可用,缺分页/搜索/排序 |
|
||||
| **状态管理** | ⭐ | 裸字段无保护,无状态机,无收口 |
|
||||
| **执行能力** | ⭐ | 完全断裂,任务无法被执行 |
|
||||
| **推进能力** | ⭐ | 0% 实现,全停留在构想文档 |
|
||||
| **工作流联动** | ⭐ | task_id=None,无回调,无路由 |
|
||||
| **AI 集成** | ⭐⭐ | AI 能创建任务,但不能执行/推进 |
|
||||
| **前端体验** | ⭐⭐ | 列表展示可用,详情只读,无操作入口 |
|
||||
| **数据安全** | ⭐⭐ | 硬删除无恢复,字段保护不足 |
|
||||
| **架构设计** | ⭐⭐⭐⭐ | 构想文档非常完整(344 行),设计质量高 |
|
||||
|
||||
**综合评分:2.1/5** — 数据层及格,执行/推进层空白。
|
||||
|
||||
### 与其他实体对比
|
||||
|
||||
| 实体 | 存储 | 业务逻辑 | AI 集成 | 工作流联动 | 前端体验 | 综合 |
|
||||
|------|------|---------|---------|-----------|---------|------|
|
||||
| **Idea** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ (df-ideas) | ⭐⭐⭐ (评估/晋升) | ⚪ N/A | ⭐⭐⭐⭐ | **3.6** |
|
||||
| **Project** | ⭐⭐⭐⭐ | ⭐⭐⭐ (df-project) | ⭐⭐⭐ (创建/描述) | ⚪ N/A | ⭐⭐⭐⭐ | **3.5** |
|
||||
| **Task** | ⭐⭐⭐⭐ | ⭐ (无 crate) | ⭐ (仅创建) | ⭐ (断裂) | ⭐⭐ (只读) | **2.1** |
|
||||
| **Workflow** | ⭐⭐⭐ | ⭐⭐⭐⭐ (df-workflow) | ⭐⭐ (AiNode 可用) | ⭐ (无消费) | ⭐⭐ (已下线) | **2.4** |
|
||||
| **Knowledge** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ (提炼/注入) | ⚪ N/A | ⭐⭐⭐ | **3.4** |
|
||||
|
||||
**任务是系统中成熟度最低的实体。**
|
||||
|
||||
---
|
||||
|
||||
## 七、根因分析
|
||||
|
||||
### 为什么任务模块「能存不能执行」?
|
||||
|
||||
```
|
||||
根因链(从表层到深层):
|
||||
|
||||
表层:前端无推进入口,后端无 advance_task
|
||||
↑
|
||||
中层:任务 ↔ 工作流断裂(task_id=None),AI 工具缺 update_task/run_command
|
||||
↑
|
||||
深层:df-task crate 被删除后,任务没有业务逻辑层
|
||||
↑
|
||||
根因:任务推进链涉及跨系统编排(Task + Workflow + AI + Human),
|
||||
但系统设计是「引擎不绑定业务」(D3 决策),
|
||||
导致引擎和业务之间的「胶水层」始终没有建立
|
||||
```
|
||||
|
||||
### 架构决策 D3 的双刃剑
|
||||
|
||||
```markdown
|
||||
### D3: 引擎不绑定业务
|
||||
- DAG 引擎纯粹做编排,不感知具体业务语义
|
||||
- 业务逻辑在 df-nodes 实现(Node trait 是纯接口)
|
||||
```
|
||||
|
||||
这个决策本身是好的(关注点分离),但它留下了一个**架构空洞**:
|
||||
|
||||
```
|
||||
DAG 引擎(通用编排) ←——空洞——→ 任务业务(具体语义)
|
||||
df-workflow ???
|
||||
df-nodes
|
||||
```
|
||||
|
||||
谁来把「任务推进」这个业务语义映射到「DAG 工作流执行」?答案应该是 **advance_task 编排层**(构想文档中设计了但未实现),或者一个新 crate(df-task 的复活)。
|
||||
|
||||
---
|
||||
|
||||
## 八、建议:从「数据容器」到「执行单元」的路径
|
||||
|
||||
### 阶段 0:修复基础问题(前置条件)
|
||||
|
||||
参照 `任务模块问题分析-2026-06-16.md`:
|
||||
1. 统一状态枚举(前后端对齐)
|
||||
2. 注册 `/tasks/:id` 路由
|
||||
3. 补 updateTask store 错误处理
|
||||
4. 不可变字段保护
|
||||
|
||||
### 阶段 1:建立推进骨架(最小闭环)
|
||||
|
||||
```
|
||||
目标:任务状态能通过「合法路径」推进,而非裸字段修改
|
||||
|
||||
1. 实现 TaskStatus::can_transition_to(状态机定义)
|
||||
2. 实现 advance_task 推进逻辑(**df-nodes Node**,D-260616-03 已决策;IPC 层 thin 入口):校验+原子写入+状态机下沉 SQL
|
||||
3. 从 update_task 白名单移除 status(收口)
|
||||
4. 前端 TaskDetail 加推进按钮(手动推进,不接 AI)
|
||||
5. 补 review_rounds 字段
|
||||
```
|
||||
|
||||
此阶段不接 AI/工作流,纯人工推进,但状态机保护和收口到位。
|
||||
|
||||
### 阶段 2:接入工作流(单向联动)
|
||||
|
||||
```
|
||||
目标:工作流执行能回写任务状态
|
||||
|
||||
1. run_workflow 支持 task_id 参数(不再硬编码 None)
|
||||
2. 工作流完成回调 → 检查 task_id → 推进任务状态
|
||||
3. 定义任务推进 DAG 模板(AiNode 执行 + AiNode 自审 + HumanNode 核对)
|
||||
4. advance_task 触发对应闸门工作流
|
||||
5. 前端展示工作流执行进度
|
||||
```
|
||||
|
||||
### 阶段 3:AI 执行能力(闭环)
|
||||
|
||||
```
|
||||
目标:AI 能真正执行任务内容
|
||||
|
||||
1. 补 run_command AI 工具(或等 patch_file + run_command 完善)
|
||||
2. 补 update_task / advance_task AI 工具
|
||||
3. 实装 run_workflow AI 工具(不再是空壳)
|
||||
4. AiNode 接入任务上下文(读任务描述 + 项目目录)
|
||||
5. AI 自审 verdict 结构化输出 + 解析
|
||||
6. 失败路径完整处理(退回/重做/保持)
|
||||
```
|
||||
|
||||
### 阶段 4:Git 集成(增强)
|
||||
|
||||
```
|
||||
目标:代码类任务支持 Git 工作流
|
||||
|
||||
1. 加 kind 字段(code/doc/design/generic)
|
||||
2. code kind 闸门接 git 命令(worktree/commit/merge)
|
||||
3. BranchRecord 联动(加 worktree_path)
|
||||
4. on_task_advanced 钩子填充(分支联动 + 项目 completed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
### 一句话诊断
|
||||
|
||||
**任务是 DevFlow 系统中设计最完善(344 行构想文档)但实现最空白(0% 推进能力)的模块。它目前是一个「能存能查不能做」的数据容器,距离设计中的「AI-First 执行单元」还有阶段 1-3 的完整路径要走。**
|
||||
|
||||
### 最紧迫的事
|
||||
|
||||
不是写 AI 执行、不是接工作流,而是 **先建立 advance_task 状态机骨架 + 收口 status 字段**。因为:
|
||||
- 状态机是所有后续工作的基础(没有合法转换定义,AI 推进无从谈起)
|
||||
- status 旁路是 P0 安全漏洞(AI 能直接改 status = done,所有闸门形同虚设)
|
||||
- 这是投入最小(~200 行代码)但收益最大的改动(从 0% 推进能力到「手动推进闭环」)
|
||||
351
docs/05-代码审查/任务模块问题分析-2026-06-16.md
Normal file
351
docs/05-代码审查/任务模块问题分析-2026-06-16.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# 任务模块问题分析报告(核对版)
|
||||
|
||||
> **日期**: 2026-06-16
|
||||
> **范围**: 任务模块全栈(Rust 后端 + Tauri IPC + Vue 3 前端)
|
||||
> **审查文件**: `task.rs` / `tasks.ts` / `Tasks.vue` / `TaskDetail.vue` / `crud.rs` / `models.rs` / `types.rs` / `project.ts` / `state.rs` / `migrations.rs` / `router/index.ts`
|
||||
> **核对方法**: Explore 代理并行验源码,逐项 `file:line` 取证
|
||||
> **核对结论**: 原清单 18 项中 **真 bug 8 项**(P0×2 P1×6)、增强 5 项、假/部分假 3 项、与现有 todo 去重 3 项
|
||||
|
||||
---
|
||||
|
||||
## 〇、核对结论速览
|
||||
|
||||
| # | 原清单结论 | 核实 | 处置 |
|
||||
|---|-----------|------|------|
|
||||
| 1 | 状态枚举前后端不一致(5 vs 7) | ✅ 真 | 三方分裂,记 B-260616-12 |
|
||||
| 2 | DDL priority 默认(1) vs 代码(2) | ✅ 真 | 潜在非现患,记 B-260616-14 |
|
||||
| 3 | delete_task 硬删除无恢复 | ✅ 真 | 记 B-260616-13 |
|
||||
| 4 | priority 无值域校验 | ✅ 真 | 记 B-260616-15 |
|
||||
| 5 | id/created_at/project_id 可篡改 | ✅ 真 | 记 B-260616-16 |
|
||||
| 6 | updateTask 无 try/catch | ✅ 真 | 记 B-260616-17 |
|
||||
| 7 | TaskDetail 绕过 store | ✅ 真 | 记 B-260616-18 |
|
||||
| 8 | /tasks/:id 路由未注册 | ✅ 真 | 🔄 去重 = B-260616-09 已存在 |
|
||||
| 9 | 无分页全量加载 | 🔄 去重 | = F-260615-03 已立 |
|
||||
| 10 | watch 重复 IPC | 🔄 去重 | = B-260615-29 设计决策 |
|
||||
| 11 | 列表组件重复 | ❌ 假 | 两文件模板结构不同(.task-item vs .task-card),排除 |
|
||||
| 12 | project_id 无存在性校验 | ⚠️ 部分假 | `db.rs:22 PRAGMA foreign_keys=ON` 兜底拦截,降级 |
|
||||
| 13 | description 无长度限制 | 🟡 增强 | 待产品决策 |
|
||||
| 14 | branch_name 无格式校验 | 🟡 增强 | 待产品决策 |
|
||||
| 15 | TaskDetail 只读无编辑 | 🟡 增强 | 待产品决策 |
|
||||
| 16 | 无批量操作 | 🟡 增强 | 待产品决策 |
|
||||
| 17 | 无排序选项 | 🟡 增强 | 待产品决策 |
|
||||
| 18 | 无搜索能力 | 🔄 去重 | ≈ F-260615-07 思路 |
|
||||
|
||||
---
|
||||
|
||||
## 一、模块架构概览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 前端 (Vue 3 + TS) │
|
||||
│ Views │ Tasks.vue (列表) → TaskDetail.vue │
|
||||
│ Store │ stores/project/tasks.ts │
|
||||
│ API │ api/task.ts │
|
||||
│ Types │ api/types.ts → TaskRecord │
|
||||
│ Constants │ constants/project.ts (状态/优先级映射) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ IPC 层 (Tauri) │
|
||||
│ Commands │ commands/task.rs (5 个命令) │
|
||||
│ State │ state.rs → TaskRepo │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 后端 (Rust Crates) │
|
||||
│ df-core │ types.rs → TaskStatus 枚举 │
|
||||
│ df-storage │ models.rs → TaskRecord 结构体 │
|
||||
│ │ crud.rs → TaskRepo (CRUD 实现) │
|
||||
│ │ migrations.rs → tasks 表 DDL │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### IPC 命令(5 个)
|
||||
|
||||
| 命令 | 签名 | 说明 |
|
||||
|------|------|------|
|
||||
| `list_tasks` | `(project_id?) → Vec<TaskRecord>` | 列出任务,可按项目筛选 |
|
||||
| `get_task_by_id` | `(id) → TaskRecord` | 按 ID 查单个任务 |
|
||||
| `create_task` | `(input) → TaskRecord` | 创建任务,默认 status=todo, priority=2 |
|
||||
| `update_task` | `(id, field, value) → bool` | 更新单字段,status 值有枚举校验 |
|
||||
| `delete_task` | `(id) → bool` | 删除任务(硬删除) |
|
||||
|
||||
### TaskStatus 枚举(后端 7 种)
|
||||
|
||||
| 状态值 | 说明 |
|
||||
|--------|------|
|
||||
| `todo` | 待开始 |
|
||||
| `in_progress` | 进行中 |
|
||||
| `in_review` | 代码审查中 |
|
||||
| `testing` | 测试中 |
|
||||
| `done` | 已完成 |
|
||||
| `blocked` | 已阻塞 |
|
||||
| `cancelled` | 已取消 |
|
||||
|
||||
### 优先级映射
|
||||
|
||||
| 值 | 标签 | 样式 |
|
||||
|----|------|------|
|
||||
| 0 | P0 | critical(紧急) |
|
||||
| 1 | P1 | high(高) |
|
||||
| 2 | P2 | medium(中,默认) |
|
||||
| 3 | P3 | low(低) |
|
||||
|
||||
---
|
||||
|
||||
## 二、问题清单(含核对标注)
|
||||
|
||||
### 🔴 P0 — 数据一致性 / 功能断裂
|
||||
|
||||
#### 1. 前后端状态枚举完全不一致 【✅ 真 · 核对确认】
|
||||
|
||||
| 层 | 状态值集合 | 证据 |
|
||||
|----|-----------|------|
|
||||
| 后端枚举 `TaskStatus` | `todo, in_progress, in_review, testing, done, blocked, cancelled`(7) | `crates/df-core/src/types.rs:131-146` |
|
||||
| 前端类型注释 | 同后端 7 种 | `src/api/types.ts:88` |
|
||||
| 前端常量 `TASK_STATUS_LABELS` | `todo, in_progress, review_ready, merged, abandoned`(5) | `src/constants/project.ts:56-62` |
|
||||
| 前端 `taskStatusClass` | 同常量 5 种,未定义回退 `status-todo` | `src/constants/project.ts:76-78` |
|
||||
| 前端 i18n `tasks.ts` | 同常量 5 种 | `src/i18n/{en,zh-CN}/tasks.ts:47-54` |
|
||||
|
||||
**影响链**:
|
||||
- 后端 `update_task` 的 `TaskStatus::is_valid()`(`task.rs:96`)只接受 7 种;前端筛选器的 `review_ready/merged/abandoned` 后端全部拒绝
|
||||
- AI 工具或后端写入 `in_review/testing/blocked` 时,前端 `TASK_STATUS_LABELS` 查不到 → 回退显示原始 key(用户见 `in_review` 而非中文)
|
||||
- `taskStatusClass` 查不到 → 回退 `status-todo`,视觉无法区分
|
||||
- Dashboard 统计 `activeTasks` 仅查 `in_progress`,`testing/blocked` 不计入
|
||||
|
||||
**根因**:前端状态集是早期 Git 工作流导向(review_ready/merged/abandoned),后端枚举后来规范化为通用状态机,两者从未对齐。`types.ts` 注释随了后端,但常量/i18n/样式仍停在旧集。
|
||||
|
||||
**人定决策点**:前端对齐到后端 7 种纯状态机,还是保留 Git 工作流 5 种语义做映射?
|
||||
|
||||
---
|
||||
|
||||
#### 2. DDL 默认值与代码默认值矛盾 【✅ 真 · 潜在非现患】
|
||||
|
||||
| 来源 | `priority` 默认值 | 证据 |
|
||||
|------|-------------------|------|
|
||||
| DDL | `DEFAULT 1`(high) | `crates/df-storage/src/migrations.rs:304` |
|
||||
| Rust `default_priority()` | `2`(medium) | `src-tauri/src/commands/task.rs:26-28` |
|
||||
| 前端 `Tasks.vue` | `2`(medium) | `src/views/Tasks.vue:62` |
|
||||
|
||||
当前 `create_task` 显式传 `priority`(走代码默认 2),DDL 默认值不生效。但未来若有直连 SQL 写入路径或手动改库,`priority=1` 与应用层 `2` 不一致。低危,可并入下次 migration 对齐。
|
||||
|
||||
---
|
||||
|
||||
#### 3. `delete_task` 硬删除 — 无恢复机制 【✅ 真 · 核对确认】
|
||||
|
||||
```rust
|
||||
// src-tauri/src/commands/task.rs:113
|
||||
state.tasks.delete(&id).await.map_err(err_str) // 物理删
|
||||
// crates/df-storage/src/crud.rs:194 — DELETE FROM tasks WHERE id=?
|
||||
```
|
||||
|
||||
`TaskRecord`(`crates/df-storage/src/models.rs:53-66`)无 `deleted_at` 字段。对比 `ProjectRecord` 有完整软删除(`deleted_at` + `list_deleted` + `restore`)。
|
||||
|
||||
**风险**:误删永久丢失;关联 `branches.task_id` 外键变悬空(无 `ON DELETE CASCADE/SET NULL`)。
|
||||
|
||||
**人定决策点**:任务是否需要软删除 + 恢复(对标 projects),还是物理删除即可(任务粒度小、误删可重建)?
|
||||
|
||||
---
|
||||
|
||||
### 🟠 P1 — 安全 / 竞态 / 架构
|
||||
|
||||
#### 4. `update_task` 缺少 `priority` 值域校验 【✅ 真 · 核对确认】
|
||||
|
||||
```rust
|
||||
// src-tauri/src/commands/task.rs:96-102 — 仅 status 校验
|
||||
if field == "status" && !TaskStatus::is_valid(&value) { ... }
|
||||
// priority 直接透传 update_field,无范围检查
|
||||
```
|
||||
|
||||
`update_task(id, "priority", "999")` 或 `"abc"` 静默落库。前端 `PRIORITY_LABELS`(`constants/project.ts:82`,key 0-3)查不到 → 回退 `P999` + 样式 `priority-low`(`project.ts:95-97`)。
|
||||
|
||||
**修复**:`field == "priority"` 时校验 `value.parse::<i32>()` ∈ `0..=3`。
|
||||
|
||||
---
|
||||
|
||||
#### 5. `update_task` 缺少 `id` / `created_at` 等不可变字段保护 【✅ 真 · 核对确认】
|
||||
|
||||
```rust
|
||||
// crates/df-storage/src/crud.rs:324-327
|
||||
"tasks" => &["id", "project_id", "title", "description", "status", "priority",
|
||||
"branch_name", "assignee", "workflow_def_id", "base_branch",
|
||||
"created_at", "updated_at"],
|
||||
```
|
||||
|
||||
白名单含 `id` / `created_at` / `project_id` → AI 工具或恶意调用可改主键、篡改创建时间、把任务移到别的项目。前端未暴露,但 IPC 层无防护。
|
||||
|
||||
**修复**:tasks 白名单移除 `id`/`created_at`;`project_id` 若允许跨项目移动则保留但加目标项目存在性校验。
|
||||
|
||||
---
|
||||
|
||||
#### 6. 前端 `updateTask` store 无错误处理 【✅ 真 · 核对确认】
|
||||
|
||||
```typescript
|
||||
// src/stores/project/tasks.ts:29-35 — 无 try/catch
|
||||
async function updateTask(id, field, value) {
|
||||
await taskApi.update(id, field, value)
|
||||
const idx = state.tasks.findIndex(t => t.id === id)
|
||||
if (idx >= 0) (state.tasks[idx] as any)[field] = value
|
||||
}
|
||||
```
|
||||
|
||||
对比同文件 `loadTasks`(10-16) / `createTask`(18-27) / `deleteTask`(37-44) 都有 try/catch。IPC 失败(如非法 status 被后端拒)→ Promise reject 冒泡,错误不写 `state.error`,用户无提示。
|
||||
|
||||
**修复**:补 try/catch,失败写 `state.error` + toast。
|
||||
|
||||
---
|
||||
|
||||
#### 7. `TaskDetail.vue` 绕过 store 直接调 API 【✅ 真 · 核对确认】
|
||||
|
||||
```typescript
|
||||
// src/views/TaskDetail.vue:101 import { taskApi, projectApi } from '@/api'
|
||||
// src/views/TaskDetail.vue:137-141 直接 taskApi.get() / projectApi.list()
|
||||
```
|
||||
|
||||
其他视图走 `useProjectStore()`,TaskDetail 直调 API:
|
||||
- 不享受 AR-11 `df-data-changed` 联动刷新(其他窗口改任务,本页不自动刷新)
|
||||
- `projectApi.list()` 全量拉项目列表仅为解析 `project_id → name`
|
||||
|
||||
**修复**:改走 store.loadTasks/store.projects,或单独监听 `df-data-changed` 重载当前 task。
|
||||
|
||||
---
|
||||
|
||||
#### 8. `/tasks/:id` 路由未注册 【✅ 真 · 导航断裂 · 🔄 去重 = B-260616-09 已存在】
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts:45-49 — 只有 /tasks
|
||||
{ path: '/tasks', name: 'Tasks', component: () => import('../views/Tasks.vue') }
|
||||
// src/views/Tasks.vue:57 — 任务卡点击跳转
|
||||
router.push('/tasks/${task.id}') // 路由表无此路径 → 落空
|
||||
```
|
||||
|
||||
对比 `/ideas/:id`、`/projects/:id` 均已注册,唯独 `/tasks/:id` 遗漏。点击任务卡片匹配不到路由(落入 catch-all 或空白页)。1 行改动速赢。
|
||||
|
||||
---
|
||||
|
||||
### 🟡 P2 — 性能 / 体验 / 代码质量
|
||||
|
||||
#### 9. 无分页 — 全量加载所有任务 【🔄 去重 = F-260615-03】
|
||||
|
||||
```rust
|
||||
// src-tauri/src/commands/task.rs:32-41
|
||||
None => state.tasks.list_all().await, // 无 limit/offset,ORDER BY created_at DESC
|
||||
```
|
||||
|
||||
已有任务 **F-260615-03** 覆盖,不重复立项。
|
||||
|
||||
---
|
||||
|
||||
#### 10. `Tasks.vue` 筛选切换导致重复全量请求 【🔄 去重 = B-260615-29】
|
||||
|
||||
```typescript
|
||||
// src/views/Tasks.vue:229-233
|
||||
watch(activeProject, (key) => { store.loadTasks(key === 'all' ? undefined : key) })
|
||||
// src/views/Tasks.vue:165-192 filteredGroups computed 已做纯前端 filter
|
||||
```
|
||||
|
||||
这是 **B-260615-29** 的设计决策(避免跨项目视图不同步),代价是每次切换 IPC 往返。不重复立项。
|
||||
|
||||
---
|
||||
|
||||
#### 11. ~~`Tasks.vue` 和 `ProjectDetail.vue` 任务列表样式/逻辑重复~~ 【❌ 假 · 排除】
|
||||
|
||||
核对:`Tasks.vue:57-73` 用 `.task-item` 布局,`ProjectDetail.vue:137-151` 用 `.task-card` 布局,模板结构不同。两者引用相同常量函数(状态/优先级映射),但模板本身非重复。**排除**。
|
||||
|
||||
---
|
||||
|
||||
#### 12. `create_task` 无 `project_id` 存在性校验 【⚠️ 部分假 · 降级】
|
||||
|
||||
```rust
|
||||
// src-tauri/src/commands/task.rs:59-84 — create_task 不校验 project_id
|
||||
project_id: input.project_id, // 直接使用
|
||||
```
|
||||
|
||||
但 `crates/df-storage/src/db.rs:22` 已开 `PRAGMA foreign_keys=ON`,DB 层外键约束会拦截指向不存在 project 的 insert。代码层无显式校验,但风险被 DB 兜住。**降级为非漏洞**,仅留注释说明依赖外键。
|
||||
|
||||
---
|
||||
|
||||
#### 13. `description` 字段无长度限制 【🟡 增强】
|
||||
|
||||
`TaskRecord.description` 是 `String`,DDL 为 `TEXT NOT NULL DEFAULT ''`。无前后端长度校验,超大文本影响 Markdown 渲染性能。待产品决策加上限。
|
||||
|
||||
---
|
||||
|
||||
#### 14. `branch_name` / `base_branch` 无 Git 分支名格式校验 【🟡 增强】
|
||||
|
||||
允许任意字符串(空格/特殊字符/中文),可能与实际 Git 分支不兼容。待产品决策加格式校验。
|
||||
|
||||
---
|
||||
|
||||
### 🔵 P3 — 增强建议(均待产品决策)
|
||||
|
||||
| # | 项 | 说明 |
|
||||
|---|----|------|
|
||||
| 15 | TaskDetail 纯只读 | 无编辑/改状态/改优先级 UI;列表页也无内联编辑 → 当前无任何 UI 改任务状态,只能靠 AI 工具/API |
|
||||
| 16 | 无批量操作 | 无法批量改状态/删除/分配 |
|
||||
| 17 | 无排序选项 | 固定 `ORDER BY created_at DESC`,无法按优先级/状态/更新时间排 |
|
||||
| 18 | 无搜索能力 | ≈ F-260615-07 思路 |
|
||||
|
||||
---
|
||||
|
||||
## 三、问题汇总矩阵(含核对标注)
|
||||
|
||||
| # | 严重度 | 类型 | 问题 | 影响 | 核实 |
|
||||
|---|--------|------|------|------|------|
|
||||
| 1 | P0 | 数据一致性 | 前后端状态枚举不一致(5 vs 7 种) | 全局 | ✅ 真 |
|
||||
| 2 | P0 | 数据一致性 | DDL priority 默认值(1) vs 代码(2) | 数据层 | ✅ 真(潜在) |
|
||||
| 3 | P0 | 数据安全 | delete_task 硬删除无恢复 | 数据丢失 | ✅ 真 |
|
||||
| 4 | P1 | 安全校验 | priority 无值域校验 | 数据质量 | ✅ 真 |
|
||||
| 5 | P1 | 安全校验 | id/created_at/project_id 可被篡改 | 数据完整性 | ✅ 真 |
|
||||
| 6 | P1 | 健壮性 | updateTask store 无 try/catch | 用户体验 | ✅ 真 |
|
||||
| 7 | P1 | 架构 | TaskDetail 绕过 store | 数据同步 | ✅ 真 |
|
||||
| 8 | P1 | 功能缺陷 | /tasks/:id 路由未注册 | 导航断裂 | ✅ 真 |
|
||||
| 9 | P2 | 性能 | 无分页全量加载 | 扩展性 | 🔄 F-260615-03 |
|
||||
| 10 | P2 | 性能 | 筛选切换重复 IPC | 响应速度 | 🔄 B-260615-29 |
|
||||
| 11 | P2 | 代码质量 | 任务列表组件重复 | 可维护性 | ❌ 假 |
|
||||
| 12 | P2 | 安全校验 | project_id 无存在性校验 | 数据完整性 | ⚠️ 部分假(外键兜底) |
|
||||
| 13 | P2 | 安全校验 | description 无长度限制 | 性能 | 🟡 增强 |
|
||||
| 14 | P2 | 安全校验 | branch_name 无格式校验 | 数据质量 | 🟡 增强 |
|
||||
| 15 | P3 | 功能缺失 | TaskDetail 无编辑能力 | 用户体验 | 🟡 增强 |
|
||||
| 16 | P3 | 功能缺失 | 无批量操作 | 效率 | 🟡 增强 |
|
||||
| 17 | P3 | 功能缺失 | 无排序选项 | 用户体验 | 🟡 增强 |
|
||||
| 18 | P3 | 功能缺失 | 无搜索能力 | 用户体验 | 🔄 ≈F-260615-07 |
|
||||
|
||||
---
|
||||
|
||||
## 四、todo 编号映射
|
||||
|
||||
记入 `docs/todo.md`(B-260615-58 起,沿用 6.15 编号保连续):
|
||||
|
||||
| todo 号 | 原清单 # | 等级 | 摘要 |
|
||||
|---------|---------|------|------|
|
||||
| B-260616-12 | 1 | P0 | 状态枚举前后端分裂(7 vs 5),需人定:Git 工作流 vs 纯状态机 |
|
||||
| B-260616-13 | 3 | P0 | delete_task 硬删除无恢复,需人定:是否要任务软删除 |
|
||||
| B-260616-14 | 2 | P1 | DDL priority DEFAULT 1 vs 代码 2,migration 对齐 |
|
||||
| B-260616-15 | 4 | P1 | update_task priority 无值域校验(0..=3) |
|
||||
| B-260616-16 | 5 | P1 | allowed_columns 含 id/created_at/project_id 可篡改 |
|
||||
| B-260616-17 | 6 | P1 | updateTask store 无 try/catch |
|
||||
| B-260616-18 | 7 | P1 | TaskDetail 绕 store,不享受联动刷新 |
|
||||
| B-260616-09 | 8 | P1 | /tasks/:id 路由未注册 — **已存在去重**(todo 排查会话区块) |
|
||||
|
||||
> 编号沿用 B-260616 批次(与 B-260616-08~11 同批,今日 06-16 发现)。
|
||||
> 增强 #13-17 归 F- 类,待产品决策后立项。
|
||||
|
||||
---
|
||||
|
||||
## 五、建议修复顺序
|
||||
|
||||
1. **#8** 路由注册 `/tasks/:id`(1 行速赢)
|
||||
2. **#6** updateTask store 加 try/catch
|
||||
3. **#4** priority 值域校验(0..=3)
|
||||
4. **#5** 不可变字段保护(id/created_at 移出白名单)
|
||||
5. **#1** 状态枚举对齐(**需人定决策**)
|
||||
6. **#3** 软删除支持(**需人定决策**)
|
||||
7. **#2** DDL 默认值修正
|
||||
8. **#7** TaskDetail 接入 store
|
||||
9. 其余 P2/P3 按需排期
|
||||
|
||||
---
|
||||
|
||||
## 六、人定决策点(需用户拍板,非大模型推断)
|
||||
|
||||
1. **状态枚举方向**(#1):前端对齐到后端 7 种纯状态机,还是保留 Git 工作流 5 种语义(review_ready/merged/abandoned)做映射?影响筛选器/i18n/统计全链。
|
||||
2. **任务软删除**(#3):任务是否需要软删除 + 恢复(对标 projects),还是物理删除即可(任务粒度小、误删可重建)?
|
||||
|
||||
这两项是产品/架构取舍,与模型能力无关,决策后记入功能决策记录。
|
||||
Reference in New Issue
Block a user