docs: 巡检简报+todo 回写(2026-06-15 第2轮)

巡检发现:
- 2196c77 workflow 整文件替换回退破坏(AiChat+Ideas 12项功能)
- B-260615-03 truncated 标志已落地
- AR-8-scroll scrollToBottom smooth 已补
- CR-260615-09 .ai-md 残余:4详情页各21处 scoped .ai-md
  (全局 ai-md.css 75行已建,旧副本待清理但非阻塞)
This commit is contained in:
2026-06-15 17:23:57 +08:00
parent 672d677046
commit f30df333b3
17 changed files with 2184 additions and 15 deletions

View File

@@ -0,0 +1,73 @@
# 定时代码走查 — 第 6 轮2026-06-15
> 触发:定时走查 cron每 30 分钟)。范围 = **列表页 + Dashboard + AI 面板/窗口垂直切片**此前从未深查。1 新提交CR-22 修复)。
> 方法2 路代理A 列表页 / B Dashboard+AI窗口+ 主代理地面核 stopListener。
> 性质:核对记录,不改产品代码(本会话 session-role-diagnose-only。todo 见 `docs/todo.md`。
> 关联:[第1-5轮](./)。
---
## CR-22 ✅ + CR-23 撤销(价值第 5 次闭环)
- `16aeacc` CR-22 ✅types.ts 3 枚举注释对齐后端Task/Idea/Project status+ 删 AiConversationSummary.models 冗余
- CR-23 撤销(不适用):接收方核对 B-34「Tauri 不转」注释在 ARC-05 拆分时已简化workflow.ts:81/project.ts:58 仅风格对齐无错误说明)
---
## 🔴 分离窗口生命周期新功能首次深查P1 核心)
**代理 B R1-R5**。地面核 `stopListener`(useAiEvents.ts:258) **全仓零调用**grep App/AiChat/AiDetached onUnmounted/onBeforeUnmount 都不调)确认 R2。
### CR-260615-24 [P1] listener 双注册 + 永不清理R1+R2
- **R1 双窗口重复消费 ai-chat-event**:后端 `app.emit`stream_recv/agentic/commands/audit 多处)是**全局广播**发给所有 webview。主窗口AiChat.vue:790+ 分离窗口AiDetached 渲染 AiChat各注册 `listen('ai-chat-event')`,两窗口 handleEvent 都触发 → delta 各 `+=` 一次 / AiAgentRound 各 push 空气泡。当前靠 App.vue:94 `v-if="panelOpen && !detached"` detach 时卸载主窗口 AiChat 间接停,但 state 是模块级单例handleEvent 仍写主窗口 state**脆弱隐式契约**。
- **R2 stopListener 零调用**useAiEvents.ts:258 定义但全仓无调用点 → listener + watchdog 永久泄漏startListener 幂等防重复注册,但卸载不释放)。
- **边界影响**reattach 重叠窗口期多一条空 assistant 消息(非崩溃/非数据损坏)。
- **修**AiChat.vue onBeforeUnmount 补 `store.stopListener()` + detach 时主窗口显式 stopListener / reattach startListener或后端 `emit_to(label)` 定向。
### CR-260615-25 [P2] 分离窗口状态机缺口R3/R4/R5
- **R3**`win.once('tauri://destroyed')` 置 detached=false 但**不恢复 panelOpen=true**(只 reattachPanel 显式设)→ 用户直接 X 关分离窗口后面板消失,需手动 Ctrl+I
- **R4**`resumeInDetached`(useAiWindow.ts:79-95) 强行重建生成态(读 df-ai-gen 置 streaming=true + push 空气泡),与后端 `ai_is_generating` 真值可能失配 → 假气泡 / 130s 后 watchdog 假超时
- **R5**:分离窗口 onMounted `switchConversation`(useAiWindow.ts:81) + loadConversations 内自动 switch后端 **AiSession 单例** activeConversationId 被分离窗口覆盖 → 主窗口期间发消息可能落错会话B-22 同类延伸)
---
## 🟡 列表页(代理 A
### CR-260615-26 [P2] AR-11 + B-29 契约交互 + Tasks 空态R-1/Y-2
- **R-1**AR-11 监听器project.ts:38对 task 调 `loadTasks()` **无参 → 全量加载**,破坏 B-260615-29 建立的「store.tasks 反映当前筛选」契约。filteredGroups 二次过滤**兜住结果正确**,但 store.tasks 变全量createTask push 到全量数组)+ 性能
- **Y-2**Tasks.vue:39-71 **无 loading/error/empty 兜底**加载失败或无结果时空白页store.error/loading 零引用)。对比 Projects.vue:107 至少有空态
### ✅ 列表页亮点
- **Projects/Tasks i18n 100%**grep 确认中文仅注释/console— CR-08 范围内这两页**无硬编码遗漏**
- Projects.vue useConfirm composable 抽离DRY消除 4 视图重复)
- B-260615-29 筛选重载注释保留(可追溯)
---
## 🟡 Dashboard代理 B
### CR-260615-27 [P2] refresh 兜底 + stage 颜色 + 死代码M1/M3/L4
- **M1**refreshDashboard.vue:202-204Promise.all **无 try/catch**,任一接口失败 unhandledrejection + 用户无反馈onMounted 有 try/catch 但 refresh 无)
- **M3**getProjectStage(:150) status→stage 映射 **planning 归 coding stage颜色紫但 label planning**颜色语义撒谎cancelled 归 testing 同)
- **L4**:决策/批注两 panel(:103-120) 永远空态CSS(.decision-row/.anno-row :504-572) 完整但模板未用 = **死代码**
### ✅ Dashboard 亮点
- **无图表库**,纯 CSS 进度条 + 数字 statGPU 友好动画,**无性能问题**
- aiShared 破环正确ARC-06nextMsgId 两窗口各自独立不冲突
---
## 📊 本轮摘要
| 类别 | 数 | 代表 |
|---|---|---|
| 价值闭环 | 1 | CR-22 ✅ + CR-23 撤销 |
| P1 新发现 | 1 | 分离窗口 R1+R2 listener 双注册+泄漏CR-24|
| P2 新发现 | 3 | 分离窗口状态机CR-25/ 列表页契约+空态CR-26/ DashboardCR-27|
| 亮点 | 4 | 列表页 i18n 100% / Dashboard 纯 CSS 无性能问题 / aiShared 破环 / useConfirm DRY |
**本轮价值****分离窗口是新功能,前几轮横切(按提交/改动)完全没覆盖**垂直切片Dashboard+AI窗口维度首次深查即暴露 P1listener 泄漏)+ 状态机缺口。**再次印证 task2/3 垂直走查价值** — 横切收敛后垂直切片是新发现来源i18n/api/列表页/AI窗口 4 个垂直切片均挖出真问题)。
**方法论**:分离窗口 P1R1+R2经地面核 stopListener 零调用坐实避免第5轮代理 A 假阳性教训),走查发现须地面验证。
todo 映射CR-260615-24P1 分离窗口 listener/ CR-25P2 状态机)/ CR-26P2 列表页)/ CR-27P2 Dashboard