docs(design): 固化 3000 主文档壳刷新验收口径
明确 File Tree / Page Tree 的 no-refresh 验收必须在 3000 /documents/<id> 主文档壳执行,不能再用 3001/Next 或 /tree debug route 替代。 补充页面 tree.node.create、页面 delete/purge、页面内 mindmap create 三条链路的独立验收;mindmap create 按 /api/mindmap/<doc>/<mindmap> 资产写入链路单独验证。 记录 task426 主入口 smoke 作为后续回归入口。
This commit is contained in:
+2
-2
@@ -282,7 +282,7 @@
|
||||
### 本阶段完成后仍保留的问题
|
||||
|
||||
- 前端主 Sidebar 仍是超大客户端组件
|
||||
- 页面树 / 文件树 / picker 虽已统一协议,但 Rust Web tree shell 仍未开始
|
||||
- 页面树 / 文件树 / picker 虽已统一协议,Rust Web 3000 主文档壳也已补齐 create/delete 与页面内 mindmap create 的 no-refresh 回显;但这只代表主入口局部刷新链路已闭环,不等于 Sidebar 整体壳已完成 Rust 化瘦身
|
||||
- 文件树中的 `asset-folder` / `asset` / `index` 仍由前端 adapter 基于现有数据集补齐,不是 Rust 直接输出的 `file_tree projection`
|
||||
- `buildDocumentTree(...)` 仍保留在兼容 helper 与旧单测中,但已退出树域主路径
|
||||
- 现在可以进入树域 Rust Web 壳重写,但不能把这一步与本阶段混写成同一任务
|
||||
@@ -290,7 +290,7 @@
|
||||
### 下一阶段任务
|
||||
|
||||
- 独立推进 [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
|
||||
- 把当前 `page_tree` / `file_tree` protocol 下沉成 Rust Web 独立 route / shell
|
||||
- 继续把当前 `page_tree` / `file_tree` protocol 下沉成更稳定的 Rust Web route / shell;验收必须以 `3000 /documents/<id>` 主文档壳为准,`/tree` debug route 与 3001/Next 不能替代主链验收
|
||||
- 继续缩小 Sidebar 超大客户端壳,只保留局部交互岛
|
||||
- 让文件树中的更宽对象投影逐步由 Rust projection 直接输出
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
| Phase 0 | 边界冻结 | `DONE` | 文档、候选模块、边界口径已经成形,但性能基线更多还是文档定义,不是完整观测系统 |
|
||||
| Phase 1 | Rust Web 基础层 | `PARTIAL` 接近 `DONE` | `mnote-web` 已成为 `3000` 主 Web 入口 owner,根页 / 文档页 SSR 产品壳、tree stream 与关键 API 接缝已落地;主 API 全量迁移、compat 清理与 legacy island source 清理仍未完成 |
|
||||
| Phase 2 | 文档阅读页 server-first 化 | `PARTIAL` 接近 `DONE` | 阅读态/编辑态已明显分离,但仍有旧链回退和大量客户端状态集中在 `DocumentContent` |
|
||||
| Phase 3 | Sidebar / 树结构 Rust 化 | `PARTIAL` 偏早期 | 主 Sidebar 已以 `kernelSidebarTree` 作为主树来源,但整体仍是超大客户端组件 |
|
||||
| Phase 3 | Sidebar / 树结构 Rust 化 | `PARTIAL` | 主 Sidebar 已以 `kernelSidebarTree` 作为主树来源;Rust 3000 主文档壳已完成 Page Tree / File Tree create/delete 与页面内 mindmap asset create 的 no-refresh 验收,但整体仍是超大客户端组件 |
|
||||
| Phase 4 | 搜索 Rust 化与 island 化 | `PARTIAL` | host/runtime 懒加载拆分已做,结果形状也开始带 `nodeId` / `subtreeRootId` / `evidence`,但仍未完成 server-first 搜索页 |
|
||||
| Phase 5 | AI 面板 Hermes client island 化 | `PARTIAL` | host/runtime 拆分已做,且已开始把 `node` / `subtree` / `outline` / `evidence` 送入 AI bridge;后续应把 Web 面板退成 Hermes 页面内客户端,把 mnote 能力注册为 Hermes skill/plugin,但 runtime 仍重,协议也未统一到 Hermes session/run/tool contract |
|
||||
| Phase 6 | Mindmap 独立对象化 | `PARTIAL` | 独立页脱离 editor stub 主入口,并补出 `standalone` / `documentBridge` 边界,但仍是客户端重壳 |
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
## 8. Phase 3:Sidebar / 页面树 / 文件树 Rust 化与 island 化
|
||||
|
||||
**当前状态:`PARTIAL` 偏早期**
|
||||
**当前状态:`PARTIAL`;3000 主文档壳 no-refresh 主链已闭环,Sidebar 瘦身仍未完成**
|
||||
|
||||
### 8.1 已落地事实
|
||||
|
||||
@@ -236,12 +236,15 @@
|
||||
- [x] Rust Web 3000 workspace shell 已接入真实页面树 / 文件树 tab host、真实 row、UI 新建页面和 active page 链路
|
||||
- [workspace_shell.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/workspace_shell.rs)
|
||||
- [layout.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/ssr/pages/layout.rs)
|
||||
- [x] Rust Web 3000 主文档壳已监听 `tree:local-command` 与同页 mindmap asset 写入,页面 create/delete 与页面内 mindmap create 均可在 Page Tree / File Tree 无刷新回显
|
||||
- [layout.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/ssr/pages/layout.rs)
|
||||
- [task426-mnote-web-main-no-reload-smoke.js](/mnt/Data1T/mnote/scripts/task426-mnote-web-main-no-reload-smoke.js)
|
||||
|
||||
### 8.2 当前真实问题
|
||||
|
||||
- [ ] `Sidebar` 仍然是超大客户端组件
|
||||
- [sidebar.tsx](/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx)
|
||||
- [ ] 页面树 / 文件树虽然已统一协议,legacy Next 侧整体执行面仍主要在客户端;当前 Rust Web 3000 SSR 壳已接入 live EventSource,但 live cache、preferred snapshot 与补偿链还未完全统一
|
||||
- [x] 页面树 / 文件树在 3000 主文档壳下的 create/delete 与页面内 mindmap create 无刷新链路已验证;后续不能再用 3001/Next 或 `/tree` debug route 替代主链验收
|
||||
- [x] `buildDocumentTree(...)` 仅剩兼容 helper 与旧单测,不再位于树域主路径
|
||||
- [ ] 主布局仍然默认常驻挂载 Sidebar
|
||||
- [ ] 还不能叫“服务端输出 + 局部 island”,现在更像“服务端首包 + 超大客户端壳”
|
||||
@@ -251,7 +254,7 @@
|
||||
- [ ] 先拆 Sidebar 自身为 host / runtime 或分片 island
|
||||
- [ ] 把树结构首包与交互态严格分层
|
||||
- [x] 把主 Sidebar 之外的 page tree、file tree、embed/move picker 也统一切到 kernel projection
|
||||
- [ ] 把局部刷新协议显式化
|
||||
- [x] 把 3000 主文档壳内页面 create/delete 与页面内 mindmap create 的局部刷新协议显式化;后续新增资产类型时继续复用同一主入口验收口径
|
||||
- [ ] 给 Sidebar 建立真正的切页重渲染基线
|
||||
|
||||
---
|
||||
|
||||
@@ -210,6 +210,8 @@
|
||||
|
||||
补充:已新增 `PreferredSidebarSnapshotProvider`,并把文档页头标题的本地 draft / committed / persisted 语义直接并入 `page-aggregate-client-state`;`DocumentContent` 现在只从同一份 preferred sidebar snapshot 读取 live committed title,再与聚合 reducer 内的短暂 draft / persisted title 做合成,不再额外维护独立标题 hook。与此同时,`useSidebarData.refetch()` 在 Convex live 模式下收到 `documents-changed` 也会主动拉取一份新的 `/api/sidebar` snapshot,再与 tree stream 做 freshness 选择,避免“页头草稿是新的,但 breadcrumb / sidebar / page tree / file tree 还卡在旧快照”。对应单测为 `page-aggregate-client-state.test.ts`、`use-sidebar-data.test.tsx`。浏览器烟测 `scripts/task110-page-title-single-truth-smoke.js` 已验证:页头重命名后,breadcrumb、默认 sidebar、page tree、file tree、切页往返、刷新均保持一致,因此本阶段与“标题来自同一份更新后的 projection”相关的勾选正式保留。
|
||||
|
||||
补充:2026-05-14 已把“文件树 / 页面树无需刷新可见”的验收口径固定到 Rust 3000 主文档壳:`MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task426-mnote-web-main-no-reload-smoke.js` 覆盖 `/documents/<id>` 中页面 create、页面 delete,以及页面内新建 mindmap 后 File Tree asset row 即时出现。后续不能再用 3001/Next 路径或 `/tree` debug route 代表用户实际使用的 3000 主入口;页面内 mindmap create 是 `/api/mindmap/<doc>/<mindmap>` 资产写入链路,必须和页面 `tree.node.create/delete` 分开验收。
|
||||
|
||||
### 7.3 退出标准
|
||||
|
||||
- [x] 标题不同步问题不再以“前端本地状态漂移”的形式重复出现。
|
||||
|
||||
@@ -211,9 +211,9 @@
|
||||
- 未通过:`node scripts/task120-rust-web-tree-integration-smoke.js` 在等待 child sidebar row 可见时超时,完整浏览器 tree integration 继续归入第 6 项处理。
|
||||
- 受既有问题阻塞:`pnpm exec tsc --noEmit --pretty false` 仍被 `.next` 旧生成文件、Convex documents 类型和 mindmap/OnlyOffice 等无关类型错误阻塞;本轮新增 `bridgeLogs.ts` / `schema.ts` 未出现在错误列表中。
|
||||
|
||||
## 6. P1:统一 Sidebar live cache
|
||||
## 6. P1:统一 Sidebar / File Tree live cache 与主文档壳 no-refresh 验收
|
||||
|
||||
状态:代码侧完成,真实浏览器 create / rename / move / archive / purge 主链已通过。`usePreferredSidebarSnapshot` 已从“sync key 与 initial 对比”的特殊规则,改为基于 `getSidebarDataFreshness()` 的 version 仲裁,并保留 tree stream cursor 作为 live 元信息;`AppLayoutShell`、Sidebar、Breadcrumb、SearchPalette 继续消费同一份 preferred snapshot。Rust 3000 下已修复 `tree:delta` 的 title-only patch 被误当成空 projection 渲染的问题,`task110` 已通过页头、breadcrumb、sidebar、page tree、File Tree 标题一致性检查;`task120` 已通过 child sidebar row 可见性、rename live delta、reload 与 purge 后消失检查;`task177` 已覆盖 move / archive live DOM reducer,确认页面树与 File Tree 行局部更新后文档页头仍稳定。
|
||||
状态:代码侧完成,真实浏览器 create / rename / move / archive / purge 主链已通过。`usePreferredSidebarSnapshot` 已从“sync key 与 initial 对比”的特殊规则,改为基于 `getSidebarDataFreshness()` 的 version 仲裁,并保留 tree stream cursor 作为 live 元信息;`AppLayoutShell`、Sidebar、Breadcrumb、SearchPalette 继续消费同一份 preferred snapshot。Rust 3000 下已修复 `tree:delta` 的 title-only patch 被误当成空 projection 渲染的问题,`task110` 已通过页头、breadcrumb、sidebar、page tree、File Tree 标题一致性检查;`task120` 已通过 child sidebar row 可见性、rename live delta、reload 与 purge 后消失检查;`task177` 已覆盖 move / archive live DOM reducer,确认页面树与 File Tree 行局部更新后文档页头仍稳定。2026-05-14 追加验收口径:File Tree / Page Tree 的“无刷新可见”必须在 `http://127.0.0.1:3000/documents/<id>` 主文档壳验证,覆盖页面 `tree.node.create`、页面 delete/purge、页面内 mindmap create 三条链路;`/tree` debug route 与 3001/Next 路径只能作为补充排查,不能替代 3000 主入口验收。
|
||||
|
||||
目标:减少 `initial / query / tree_stream` 三源 freshness 选择,把 Sidebar、Breadcrumb、文档页头收口到统一 live cache / projection version 仲裁。
|
||||
|
||||
@@ -230,12 +230,17 @@
|
||||
- [x] `usePreferredSidebarSnapshot` 从 sync key 比较推进到 cursor/version 比较。
|
||||
- [x] Sidebar、Breadcrumb、文档页头统一消费同一 preferred/live snapshot。
|
||||
- [x] 保留 initial snapshot 只作为首屏启动输入,不能长期压过更新后的 stream/query。
|
||||
- [x] Rust 3000 主文档壳监听 `tree:local-command`,在 `tree.node.create` / delete 成功后即时更新 Page Tree 与 File Tree DOM。
|
||||
- [x] Rust 3000 主文档壳监听同页 mindmap 资产写入:slash 插入触发 `/api/mindmap/<doc>/<mindmap>` POST 成功后,File Tree 即时出现 `mindmap-<id>.json` asset row。
|
||||
|
||||
验收标准:
|
||||
|
||||
- [x] 新建、重命名、移动、归档页面后,Sidebar、Breadcrumb、文档页头无互相打架或回退闪烁。
|
||||
- [x] `usePreferredSidebarSnapshot` 有单测覆盖 query、initial、tree_stream 三者的新旧仲裁。
|
||||
- [x] 真实浏览器 smoke 覆盖至少一个 tree command 后 Sidebar 与文档页头一致。
|
||||
- [x] 真实浏览器 smoke 必须覆盖 `3000 /documents/<id>` 主文档壳中页面新建后 Page Tree / File Tree 立即出现,且 `navigationEvents.length=0`。
|
||||
- [x] 真实浏览器 smoke 必须覆盖同一主文档壳中页面删除或 purge 后 Page Tree / File Tree 立即移除,且不依赖浏览器刷新。
|
||||
- [x] 真实浏览器 smoke 必须覆盖同一主文档壳中页面内新建 mindmap 后 File Tree 立即出现对应 asset row;该链路是 `/api/mindmap/<doc>/<mindmap>` 资产写入,不等同于页面 `tree.node.create`。
|
||||
|
||||
证据:
|
||||
|
||||
@@ -255,7 +260,8 @@
|
||||
- 已通过:`node scripts/task120-rust-web-tree-integration-smoke.js` 在 Rust 3000 下通过 root/child row、active 切换、rename live delta、reload 与 purge 检查。
|
||||
- 已通过:`node scripts/task112-tree-rust-family-regression-smoke.js`,但当前页面选项壳缺少 move/embed 入口导致 picker 部分 skipped:`move_embed_entry_missing_in_current_page_options_shell`。
|
||||
- 已通过:`node scripts/task177-tree-move-archive-live-smoke.js`,覆盖 `move_document` live event 后页面树 / File Tree 行 `data-parent-id` 更新,以及 `remove_document` live event 后两棵树局部移除归档行;文档页头和标题输入保持根页面标题稳定。
|
||||
- 已通过:`node scripts/task179-tree-create-delete-no-reload-smoke.js`,覆盖 Rust `/tree` `convex_workspace` 下 File Tree create/delete 与 Page Tree create;最新结果 `ok=true`,`filetree.createMs=120`、`filetree.deleteMs=178`、`page.createMs=120`,对应 mode 内 `navigationEvents.length=0`,URL 前后一致。
|
||||
- 已通过:`node scripts/task179-tree-create-delete-no-reload-smoke.js`,覆盖 Rust `/tree` `convex_workspace` 下 File Tree create/delete 与 Page Tree create;该脚本只作为 debug route 补充证据,不再代表最终主链验收。
|
||||
- 已通过:`MNOTE_UI_BASE_URL=http://127.0.0.1:3000 node scripts/task426-mnote-web-main-no-reload-smoke.js`,覆盖 `3000 /documents/<id>` 主文档壳:页面 create/delete 无刷新即时更新 Page Tree / File Tree,页面内 mindmap create 经 `/api/mindmap/<doc>/<mindmap>` POST 后即时插入 `asset:<mindmapId>` File Tree row,`afterMindmapCreate.localApplied=true`。
|
||||
|
||||
## 7. P1:明确 `pageSubtree` 与本地正文编辑关系
|
||||
|
||||
|
||||
Reference in New Issue
Block a user