Files
mnote/design/03-rust-web/done/3-18-local-folder-tree-live-consumer-convergence-checklist-v1.md
T

116 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3-18 [done] Local Folder Tree Live Consumer 收敛 checklist v1
> 创建时间:2026-05-21
>
> 当前状态:`DONE`
>
> 上位入口:
> - `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`
> - `design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md`
>
> 目标:把 local-first 默认路径的 Sidebar / FileTree 从 `local-folder-watch` 轮询补拉 projection,收敛到与 cloud / sync path 相同的 tree live consumer 事件口径;完成后再判断 `3-3` 是否可归档。
## 1. 当前事实
- `3000` cloud / compat 工作区已通过 `TREE_LIVE_CONTROLLER_JS` 优先连接 `/api/realtime/ws`,失败后回退 `/api/tree/events`
- `sourceKind=local_folder` 时,`TREE_LIVE_CONTROLLER_JS` 当前直接标记 `data-mnote-tree-live-transport="local-folder-static"` 并返回,不进入 WS / SSE tree live consumer。
- local_folder Sidebar / FileTree 当前由 `startLocalFolderSidebarWatch()` 轮询 `/api/tree/local-folder-watch`,发现 revision 变化后再调用 `refreshLocalFolderSidebarSnapshot()` 分别拉 `/api/tree/projections/sidebar``/api/tree/projections/file`
- `web_shell.rs` 已有 `/api/local-folder/events` SSE,用于 tiptap 文档外部变更刷新,但它还没有统一到 Sidebar / FileTree 的 `tree:snapshot` / `tree:delta` / `tree:resync` consumer。
## 2. 不做事项
- 不恢复 Convex 正文主存储。
- 不把 local_folder 变化写回 Convex command log。
- 不重开旧 Next / BlockNote 默认路径。
- 不一次性重写所有 Sidebar/FileTree 逻辑;本轮只替换轮询补拉链路的 transport 和 consumer 入口。
## 3. Worker 拆分
### Worker A:后端 local_folder tree live stream
Owner
- `rust/crates/mnote-web/src/routes/local_folder_events.rs`
- `rust/crates/mnote-web/src/routes/stream_support.rs`
- `rust/crates/mnote-web/src/routes/mod.rs`
- 必要时只读 `rust/crates/mnote-web/src/local_folder_watcher_registry.rs`
目标:
- 给 local_folder 提供 tree live 事件形状:`tree:snapshot` / `tree:resync` 至少携带 `kernel_sidebar_projection``kernel_file_tree_projection`
- 复用现有 LocalFolderWatcherRegistry,不新增第二套 watcher。
- 事件 payload 必须保留 `sourceKind=local_folder``rootUri``workspaceId``revision`
- 若无法可靠生成细粒度 delta,允许先统一发 `resync`,但必须走同一个前端 `renderSidebarSnapshot()` consumer。
验收:
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_folder_events -- --test-threads=1`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web stream_support -- --test-threads=1`
### Worker B:前端 tree live controller 接入 local_folder
Owner
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
目标:
- 移除 `sourceKind=local_folder` 直接 `local-folder-static` 返回的长期阻塞。
- local_folder 进入 tree live controller 后,应使用新后端事件流,并把 snapshot/resync 统一 dispatch 到 `tree:snapshot` / `tree:resync`
- 保留 editor 文档外部变更的 `/api/local-folder/events` 用法,不破坏 tiptap conflict / external change 逻辑。
- 尽量让 `startLocalFolderSidebarWatch()` 退为 fallback,不再是默认主链。
验收:
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web sidebar_tree_runtime -- --test-threads=1`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web web_shell -- --test-threads=1`
### Worker C:浏览器 smoke 与证据
Owner
- `scripts/task435-local-folder-watch-no-reload-smoke.js`
- 可新增 `scripts/task487-local-folder-tree-live-consumer-smoke.js`
- `design/03-rust-web/process/3-18-local-folder-tree-live-consumer-convergence-checklist-v1.md`
目标:
- 增加或更新 smoke,验证 local_folder 文档页 HTML / DOM 不再显示 `data-mnote-tree-live-transport="local-folder-static"` 作为默认主链。
- 验证 local_folder Sidebar / FileTree 的外部文件变化最终通过 `data-mnote-tree-live-applied="snapshot|resync"` 或等价 tree live 标记刷新,而不是只依赖 `data-mnote-local-folder-watch-applied="projection"`
- smoke 必须可在 `http://127.0.0.1:3000` 环境运行,并输出 JSON 证据和截图路径。
验收:
- `node --check scripts/task435-local-folder-watch-no-reload-smoke.js`
- 若新增脚本:`node --check scripts/task487-local-folder-tree-live-consumer-smoke.js`
## 4. Codex 复核项
- [x] 复核 Worker A diff,确认没有新增第二套 watcher 或 Convex 写回。
- [x] 复核 Worker B diff,确认 local_folder 进入统一 tree live consumer,旧 polling 只保留 fallback。
- [x] 复核 Worker C smoke,确认断言覆盖真实 UI/DOM 状态。
- [x] 运行 targeted Rust tests。
- [x] 运行相关 smoke 或记录环境阻塞。
- [x] 更新 `3-3``1-8` 状态。
## 5. 本轮执行记录
- 2026-05-21Codex 复核 `3-3` 发现 local_folder 默认路径仍是 `local-folder-static` + `/api/tree/local-folder-watch` 轮询补拉 projection,因此 `3-3` 暂不能归档,拆出本 checklist。
- 2026-05-21**Worker C(本批次)**
- 新增 `scripts/task487-local-folder-tree-live-consumer-smoke.js`
- 未修改 `scripts/task435-local-folder-watch-no-reload-smoke.js`,该脚本保持 GREEN(覆盖 no-reload 语义,与 tree live consumer 正交)
- 先前使用旧进程和首页入口时 smoke 呈 RED;切换到新编译的 3000 进程并改为 `documents/local-md:README.md?sourceKind=local_folder...` 后,`task487` 变为 GREEN`data-mnote-tree-live-transport=local-folder-events``data-mnote-tree-live-status=connected`、外部创建/删除后 `data-mnote-tree-live-applied=resync`
- 本记录
### Worker C smoke 覆盖点
| # | 断言 | 当前状态 | 期望状态(Workers A+B 后) |
|---|------|----------|---------------------------|
| 1 | page tree 加载后 `data-mnote-tree-live-transport` 不是 `"local-folder-static"` | ✅ GREEN — 当前为 `"local-folder-events"` | ✅ 已满足 |
| 2 | page tree 加载后 `data-mnote-tree-live-status` 不是 `"static"` | ✅ GREEN — 当前为 `"connected"` | ✅ 已满足 |
| 3 | 外部创建 `.md``data-mnote-tree-live-applied``"snapshot"``"resync"` | ✅ GREEN — 当前为 `"resync"` | ✅ 已满足 |
| 4 | 外部删除 `.md``data-mnote-tree-live-applied``"snapshot"``"resync"` | ✅ GREEN — 当前为 `"resync"` | ✅ 已满足 |
| 5 | FileTree 视图加载后 transport/status 非 `"local-folder-static"` / `"static"` | ✅ GREEN — 当前为 `"local-folder-events"` / `"connected"` | ✅ 已满足 |
| 6 | FileTree 外部创建后 tree-live-applied 为 snapshot/resync | ✅ GREEN — 当前为 `"resync"` | ✅ 已满足 |
| 7 | `data-mnote-local-folder-watch-applied` 不再是唯一刷新证据 | ✅ GREEN — 当前同时存在 `data-mnote-tree-live-applied` | ✅ 已满足 |