优化: 待审查 CR-260619-15 F-260619-01 任务关联灵感审查回填( PASS)

7 维度全过:V20 迁移幂等 + task_repo 3 处 SELECT 完整 + 6 处 TaskRecord 构造补 idea_id + 前端 router-link 展示。
2 WATCH:schema_version INSERT 非 IGNORE(同 v1-v19 统一模式)/ V20 测试 mock(同 V21 模式)。
清理审查 agent 遗留重复登记块。无 🔴/🟡 阻塞项。
This commit is contained in:
2026-06-19 21:09:25 +08:00
parent 4a87c552cc
commit ba47f44ab8

View File

@@ -1087,6 +1087,32 @@
--- ---
### CR-260619-15 F-260619-01 任务关联灵感(tasks.idea_id 1对1 单向·V20 迁移·commit 4a87c55) — ✅ 已审(PASS·⚪2)
- **结论(2026-06-19·独立 grep/read 核验 commit 4a87c55 + 复跑 cargo test df-storage 47 passed + vue-tsc EXIT 0)**: ✅ **PASS** — 🔴0 🟡0 ⚪2
- **7 维度逐项核验**(独立 grep 源码当前形态,不信 commit message):
| # | 维度 | file:line | 判定 |
|---|------|-----------|------|
| 1 | V20 迁移正确性 | `migrations.rs:361-369`(migrate_v20)+ `:575-580`(V9_SQL 列)+ `:47`(steps 含 (20,migrate_v20))+ `:26`(注释从"预留给 F-260619-01 跳过"更新为"V20 = F-260619-01") | ✅ column_exists 探测跳过 ALTER + ALTER 兜底老库 + V9_SQL 新库直接 `idea_id TEXT REFERENCES ideas(id)` + 写版本 20;steps 数组 20 项 + 注释同步更新。schema_version INSERT 普通(非 IGNORE)与 v1-v19 全一致模式(grep 20 处全 `INSERT INTO schema_version`),run() 正常流程 current_version<20 只调一次无 PK 冲突 |
| 2 | TaskRecord idea_id | `models.rs:78-82`(`pub idea_id: Option<String>` + `#[serde(default)]`) + `task_repo.rs:34`(task_from_row `idea_id: row.get("idea_id")?`) | ✅ Option + serde default 兼容老前端 JSON + from_row 读 |
| 3 | task_repo SQL 完整 | `task_repo.rs:52-58`(insert 加列+占位 ?13)+ `:62-65`(update 加 idea_id=?12)+ 3 处显式 SELECT: `:83`(list_active)/`:184`(advance_status_atomic)/`:205`(list_deleted)全加 idea_id;`impl_repo!` 宏(mod.rs:81/98/119)用 `SELECT *` 自动带列 | ✅ grep `SELECT.*FROM tasks` 仅 3 处全含 idea_id 无遗漏 |
| 4 | 白名单 | `crud/settings.rs:145-147`(`"idea_id"` 加入 tasks allowed_columns + 注释"非状态机收口字段,合法可写") | ✅ update_task 工具经白名单自动支持改 idea_id |
| 5 | AI 工具 + IPC | `tool_registry.rs:633-634`(create_task schema 加 `("idea_id","string",false)`)+ `:650-651`(handler `args.get("idea_id").and_then(as_str).filter(!is_empty).map(String)` 空串/null 视为不关联);`commands/task.rs:24-27`(CreateTaskInput `pub idea_id: Option<String>`)+ `:85`(handler `input.idea_id.filter(!is_empty)`) | ✅ AI 工具 + IPC 双层一致空串语义 |
| 6 | 前端展示 | `types.ts:120-121`(TaskRecord `idea_id?:string`)+ `:133-135`(CreateTaskInput 同)+ `TaskDetail.vue:107-115`(router-link `:to="/ideas/${task.idea_id}"` 显 ideaTitle 非 id)+ `:222-227`(ideaTitle computed find idea by id 回退 id)+ `:402-409`(load Promise.all 加 ideaApi.list)+ `:443`(df-data-changed 监听 entity==='idea') | ✅ router-link 友好 + 回退 id + 数据变更联动 |
| 7 | 向后兼容 | `models.rs:80-81`(#[serde(default)] 老任务 None)+ 单向 1对1(grep 全 crates 无 `list_tasks_by_idea` 反向查询)+ 6 处 TaskRecord 构造点全补 idea_id(project_soft_delete.rs/ai_node.rs/task_advance_node.rs/df-mcp tools.rs create+update×2) | ✅ 无反向查询符合 1对1 起步约束 + 编译无遗漏 |
- **复跑验证**(防 check 假绿):
- `cargo test -p df-storage --lib`: **47 passed 0 failed**(含 `migrations::tests::v20_legacy_db_adds_idea_id_column` + `v20_column_exists_skips_alter` 两测)✅
- `vue-tsc --noEmit`: **EXIT 0**
- **复用印证**:tasks.idea_id (`migrations.rs:579`) 与 projects.idea_id (`:562`) 同 `TEXT REFERENCES ideas(id)` 模式,FK 引用语义一致。
- **⚪ WATCH-1**: `migrate_v20` schema_version 用普通 `INSERT`(非 `INSERT OR IGNORE`),重跑同版本会 PK 冲突报错——这是 v1-v19 全部迁移的统一模式(run() 流程 current_version<20 才调,正常无重跑),非本次引入。测试注释 `migrations.rs:1072-1074` 已诚实标注此语义。
- **⚪ WATCH-2**: V20 测试用 mock legacy schema 直接调 migrate_v20(非完整 run() 链),新库真路径依赖 V9_SQL 列存在性(已 grep 核验 :579)。同 V21 测试模式(:844-862),非本次短板。
- **待修项回流 todo**: **无** 🔴/🟡 项
---
## 已审归档 ## 已审归档
> 已审 CR 段迁独立文件: [待审查归档/2026-06.md](./07-项目管理/待审查归档/2026-06.md) > 已审 CR 段迁独立文件: [待审查归档/2026-06.md](./07-项目管理/待审查归档/2026-06.md)