205 lines
10 KiB
Markdown
205 lines
10 KiB
Markdown
# 3-10 [done] Rust Web 3000 Tree / Editor Runtime Integration Checklist v1
|
||
|
||
> 更新时间:2026-04-29
|
||
>
|
||
> 纠偏补充(2026-04-29):用户复核发现此前“完成”口径只覆盖 API / 直达文档页 smoke,没有覆盖默认根页真实 UI 工作流。默认 `3000 /` 重新接入既有 Rust page tree / file tree renderer 与 UI 新建到 `leptos-tiptap` 的闭环,详见 `/mnt/Data1T/mnote/design/03-rust-web/done/3-11-rust-web-3000-existing-tree-editor-runtime-relink-checklist-v1.md`。
|
||
>
|
||
> 对应计划:
|
||
> - `/mnt/Data1T/mnote/design/03-rust-web/done/3-9-rust-web-3000-tree-editor-runtime-integration-plan-v1.md`
|
||
>
|
||
> 参考输入:
|
||
> - 当前 3000 截图:`/mnt/Data1T/mnote/tmp/image copy 32.png`
|
||
> - 当前 shell parity checklist:`/mnt/Data1T/mnote/design/03-rust-web/done/3-8-rust-web-3000-wolai-ui-parity-checklist-v1.md`
|
||
> - Page Aggregate 对齐主线:`/mnt/Data1T/mnote/design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md`
|
||
|
||
## 1. 当前结论
|
||
|
||
当前已经完成的是:
|
||
|
||
- [x] `3000` 默认由 `mnote-web` 监听。
|
||
- [x] `3000` 根页已经有 Wolai 风格 workspace shell。
|
||
- [x] 根页包含左栏、顶栏、右下浮动按钮和 `data-mnote-shell="workspace"`。
|
||
- [x] `/documents/:id` 已有 Rust Web document shell、Page Aggregate marker 和 `data-editor-host="leptos_tiptap_island"` marker。
|
||
|
||
当前没有完成的是:
|
||
|
||
- [x] 左栏 `我的页面` 显示真实 file/page tree rows,而不是空 section。
|
||
- [x] 根页正文不再使用设计稿静态链接列表作为伪主内容。
|
||
- [x] active page selection 能从 projection / recent / URL 一致落到 sidebar 和 document shell。
|
||
- [x] `/documents/:id` 浏览器运行态能挂载 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
|
||
- [x] `.ProseMirror[contenteditable="true"]` 可见、可输入、可保存、reload 后可读回。
|
||
- [x] smoke 能区分“只有外壳 UI”与“真实树和编辑器已接入”。
|
||
|
||
一句话判断:
|
||
|
||
> **本轮已完成 tree/editor runtime parity 收口;3-8 作为 shell/UI parity 基线已迁入 done。**
|
||
|
||
## 2. 不可误判为完成的情况
|
||
|
||
- [x] 只看到 `data-testid="wolai-sidebar"`,不算页面树接入。
|
||
- [x] 只看到 `我的页面` 文案,不算真实树接入。
|
||
- [x] 只看到正文静态链接列表,不算 Page Aggregate 主内容接入。
|
||
- [x] 只看到 `data-editor-host="leptos_tiptap_island"`,不算 editor island 已 hydrate。
|
||
- [x] 只看到 `#mnote-editor-island` 空占位,不算主编辑区完成。
|
||
- [x] 只在 fixture gateway 下通过,不算当前真实 `3000` 主链完成。
|
||
|
||
## 3. Phase E-0:冻结真实树和编辑器失败用例
|
||
|
||
目标:让当前截图暴露的问题可以自动失败。
|
||
|
||
- [x] 新增 `scripts/task120-rust-web-tree-integration-smoke.js`。
|
||
- [x] `task120` 通过 `POST /api/tree/commands action=create` 创建临时根页面。
|
||
- [x] `task120` 创建临时子页面并记录 `workspaceId` / `documentId`。
|
||
- [x] `task120` 断言 `GET /` 或 `/documents/:id` 的左栏包含 `data-testid="wolai-sidebar-row"`。
|
||
- [x] `task120` 断言临时页面 row 的 `data-node-id` 等于真实 document id。
|
||
- [x] `task120` 断言 active row 有 `data-active="true"` 或等价稳定标记。
|
||
- [x] `task120` 点击 row 后能打开 Rust Web `/documents/:id`。
|
||
- [x] `task120` 用 `purge` 清理临时页面。
|
||
- [x] 新增 `scripts/task121-rust-web-editor-island-hydration-smoke.js`。
|
||
- [x] `task121` 断言 `data-testid="mnote-leptos-tiptap-island-editor-root"` 可见。
|
||
- [x] `task121` 断言 `.editor-surface .ProseMirror[contenteditable="true"]` 可见。
|
||
- [x] `task121` 输入唯一文本并触发保存。
|
||
- [x] `task121` reload 后仍能读回唯一文本。
|
||
- [x] `task121` 拉取 `/api/page-aggregate/:id` 后能读回保存内容或版本变化。
|
||
- [x] `task119` 增加负向断言,不能只靠 `.mnote-home-links` 静态列表通过。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task120-rust-web-tree-integration-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-island-hydration-smoke.js
|
||
```
|
||
|
||
## 4. Phase E-1:workspace sidebar 接入真实 projection rows
|
||
|
||
目标:左栏 `我的页面` 不再是空 section,而是 projection 驱动的真实页面树。
|
||
|
||
- [x] `WorkspaceShellProjection.myPageItems` 来源于 `sidebar_tree` / `sidebar.dataset.list` / kernel projection。
|
||
- [x] `WorkspaceShellProjection.starredItems` 来源于真实 projection,不硬编码。
|
||
- [x] `render_workspace_shell_sidebar_html` 输出 `data-testid="wolai-sidebar-row"`。
|
||
- [x] 每个 row 输出 `data-node-id`。
|
||
- [x] 子页面 row 输出 `data-parent-id` 或等价层级标记。
|
||
- [x] active row 输出 `data-active="true"`。
|
||
- [x] 空 workspace 输出明确 empty state,不回到设计稿静态链接列表。
|
||
- [x] Cargo 测试覆盖 root/child/active/empty 四类输入。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/rust
|
||
cargo test -p mnote-web workspace_shell
|
||
```
|
||
|
||
## 5. Phase E-2:根路径接入 active page / empty workspace
|
||
|
||
目标:`GET /` 选择真实 active page 或显示真实空 workspace,不再把设计稿静态首页当主编辑区。
|
||
|
||
- [x] `gateway.rs::root_entry` 选择顺序固定为 `pageId` > recent cookie > projection active > first page > empty workspace。
|
||
- [x] 有 active page 时,根路径渲染或跳转到真实 document shell。
|
||
- [x] 无 active page 时,根路径显示空 workspace state。
|
||
- [x] 根页不再输出 `.mnote-home-links` 静态设计稿列表作为主内容。
|
||
- [x] recent page cookie 与 document shell 打开行为一致。
|
||
- [x] Rust 测试覆盖 root selection 顺序。
|
||
- [x] `task118` / `task119` 仍通过。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/rust
|
||
cargo test -p mnote-web root_entry
|
||
cd /mnt/Data1T/mnote
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task118-rust-web-wolai-ui-parity-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task119-rust-web-wolai-visual-regression-smoke.js
|
||
```
|
||
|
||
## 6. Phase E-3:document shell 接上真实 Page Aggregate 与 page tree
|
||
|
||
目标:文档页标题、页面树、正文 bootstrap 来自同一份 Page Aggregate / projection。
|
||
|
||
- [x] `/documents/:id` 标题来自 Page Aggregate `head.title`。
|
||
- [x] breadcrumb / topbar active title 与 Page Aggregate 标题一致。
|
||
- [x] 左栏 active row 与当前 document id 一致。
|
||
- [x] 页面内 page tree / subtree 使用 Page Aggregate `tree.pageSubtree` 或 kernel `page_tree` projection。
|
||
- [x] HTML 内嵌 `__MNOTE_PAGE_AGGREGATE__`。
|
||
- [x] HTML 内嵌 `__MNOTE_EDITOR_BOOTSTRAP__`。
|
||
- [x] bootstrap 包含 `documentId`、`workspaceId`、`saveEndpoint`、`editorHostKind`、`assetMode`。
|
||
- [x] 不从 URL 或静态 fallback 重新推导第二份页面真相。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/rust
|
||
cargo test -p mnote-web document_shell page_aggregate
|
||
cd /mnt/Data1T/mnote
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task115-rust-web-document-shell-smoke.js
|
||
```
|
||
|
||
## 7. Phase E-4:挂载 `leptos-tiptap` island 并证明可编辑
|
||
|
||
目标:主编辑区不是 marker,而是浏览器内真实可编辑 runtime。
|
||
|
||
- [x] Rust document shell 输出稳定 mount root。
|
||
- [x] 前端 island adapter 能读取 `__MNOTE_PAGE_AGGREGATE__`。
|
||
- [x] 前端 island adapter 能读取 `__MNOTE_EDITOR_BOOTSTRAP__`。
|
||
- [x] `leptos_tiptap_island` 成为 active host。
|
||
- [x] 页面出现 `data-testid="mnote-leptos-tiptap-island-editor-root"`。
|
||
- [x] 页面出现 `.editor-surface .ProseMirror[contenteditable="true"]`。
|
||
- [x] `data-editor-host-active="leptos_tiptap_island"` 或等价 observability 可见。
|
||
- [x] BlockNote 没有成为默认主编辑器。
|
||
- [x] 输入文本能保存。
|
||
- [x] reload 后文本仍在。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-island-hydration-smoke.js
|
||
```
|
||
|
||
## 8. Phase E-5:树事件与编辑保存联动回归
|
||
|
||
目标:树和编辑器不是一次性 SSR,而是接入当前 Rust Web transport / realtime 主链。
|
||
|
||
- [x] 新建页面后 `/api/tree/events` 或 projection reload 可看到新增节点。
|
||
- [x] 重命名页面后 sidebar row title 更新。
|
||
- [x] 删除 / purge 页面后 sidebar row 消失。
|
||
- [x] 编辑保存走 `/api/documents/save` 或约定 Rust Web save endpoint。
|
||
- [x] 保存后 `/api/page-aggregate/:id` 能看到正文变化或 revision 变化。
|
||
- [x] `task114`、`task115`、`task118`、`task119`、`task120`、`task121` 在当前 3000 全部通过。
|
||
|
||
验证命令:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task114-rust-web-gateway-entry-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task115-rust-web-document-shell-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task118-rust-web-wolai-ui-parity-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task119-rust-web-wolai-visual-regression-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task120-rust-web-tree-integration-smoke.js
|
||
MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task121-rust-web-editor-island-hydration-smoke.js
|
||
```
|
||
|
||
## 9. Harness 映射建议
|
||
|
||
本 checklist 建立阶段不直接修改 `harness-tasks.json`。若进入执行,建议追加:
|
||
|
||
| 新任务 | Phase | 标题 | 优先级 |
|
||
| --- | --- | --- | --- |
|
||
| `task-034` | E-0 | 冻结真实树和编辑器 hydration 失败用例 | P0 |
|
||
| `task-035` | E-1 | workspace sidebar 接入真实 projection rows | P0 |
|
||
| `task-036` | E-2 | 根路径接入 active page / empty workspace | P0 |
|
||
| `task-037` | E-3 | document shell 接上真实 Page Aggregate 与 page tree | P0 |
|
||
| `task-038` | E-4 | 挂载 leptos-tiptap island 并证明可编辑 | P0 |
|
||
| `task-039` | E-5 | 树事件与编辑保存联动回归 | P1 |
|
||
|
||
## 10. 完成判定
|
||
|
||
- [x] `task120` 在当前 `3000` 通过。
|
||
- [x] `task121` 在当前 `3000` 通过。
|
||
- [x] 左栏页面树来自真实 projection。
|
||
- [x] 根页不再用设计稿静态列表伪装主内容。
|
||
- [x] 文档页有真实 `leptos-tiptap` 可编辑 surface。
|
||
- [x] 保存后 Page Aggregate / reload 可读回。
|
||
- [x] `3-8` 可移动到 `done` 后,本 checklist 才能进入完成评估。
|