Files
mnote/ARCHITECTURE.md
T
lix-2026 a2cb1338c8 chore: 保存当前架构收口与 bug 修复快照
归档本轮 P0/P1 bug 修复、设计审查迁移、AI selection scope 收口与 stream contract 调整,并保留当前 05 主线迁移起点。
2026-05-18 17:01:35 +08:00

19 KiB
Raw Blame History

MNOTE 当前架构梳理

更新时间:2026-05-16

当前阶段:初步 MVP 已达成。 3000 下文档页完整读写链路(标题、正文、页面设置、Page Aggregate)、Sidebar/File Tree/Page Tree 三层树模型、tree commandtree.* preferred)、tree realtime SSEsnapshot/delta/resync)、页面 AI 快速编辑(fast-path < 1s,当前 local_rule planner 为过渡实现,长期方向为 markdown 级编辑,见 7-14)均已通过真实浏览器 smoke 验证。剩余工作集中在单一真源收口、live cache 统一、AI 编辑路径从块级收敛到 markdown 文本层,而非继续证明架构可行性。

本文只描述当前仓库中真实成立的主线结构,以及当前最优先的架构收口点。

1. 当前主线结论

当前仓库的主线不是:

  • BlockNote-first
  • Mindmap-first
  • “先拆掉 Convex 再谈 Rust”

当前主线固定为:

  1. tree-first graph kernel 是长期对象真相层
  2. Convex 继续保留为当前自托管存储 / 实时 / 文件协作底座
  3. mnote-web 是当前 Rust Web 主执行面,负责 3000 gateway、server-first shell、query / command / projection / transport 与 realtime streamNext App Router 已降为 legacy compat / island bundle source,不再是当前主入口
  4. 文档页默认主编辑器已切到页面内 leptos-tiptap island
  5. BlockNote 已退出文档页默认主路径,仅作为历史参考实现 / 对照材料保留
  6. 页面 AI 工具链已建立最小闭环:POST /api/page-ai/block-edit-workflow 提供快速编辑 route(当前 local_rule planner 为过渡态,长期方向为 mnote.doc.markdown_edit 文本级搜索替换,见 7-14);Hermes toolsmnote.doc.* / mnote.block.*)承担复杂任务编排

一句话收口:

Rust 持有语义主导权,Convex 保留底座,前端逐步从重壳转向消费稳定 projection 与少量交互 island。

补充口径:

主 Web 执行面当前以 mnote-web 为 3000 ownerNext App Router 只保留为 legacy compat、交互 island bundle source 与显式 debug/迁移辅助边界。

页面 AI 块编辑当前以 fast-path local_rule planner/api/page-ai/block-edit-workflow)为简单操作首选;Hermes agentmnote.doc.* / mnote.block.* tools)保留为复杂任务编排器。

2. 当前主线目录

  • /mnt/Data1T/mnote/recycle/wolai-frontend/ 已退役移入 recycle。React island 与 legacy compat 代码的历史来源;Next.js App Router 已被 Rust mnote-web SSR 替代,不再作为 3000 主入口。
  • /mnt/Data1T/mnote/rust/crates/core-protocol/ Kernel 类型、projection 协议、编辑器协议、树 / 图核心术语。
  • /mnt/Data1T/mnote/rust/crates/bridge-runtime/ Kernel query / command、bridge transport、Tiptap <-> editor document 适配、命令解释层。
  • /mnt/Data1T/mnote/rust/crates/mnote-web/ Rust Web route、kernel projection、documents/search/mindmap shell、Hermes bridge、stream transport、compat,以及显式开启时的 debug shell;它是当前主 Web gateway / shell / transport owner。
  • /mnt/Data1T/mnote/recycle/wolai-frontend/convex/ 已随 wolai-frontend 移入 recycle。当前活跃 Convex functions 位于 infra/convex/ 与 Rust bridge 中。
  • /mnt/Data1T/mnote/infra/convex/ Convex 自托管部署与基础设施。
  • /mnt/Data1T/mnote/wolai-backend/ 辅助后端与异步处理,不是当前页面主链。

3. 当前页面运行结构

3.1 根布局与 legacy island source(已退役)

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/app/layout.tsx

该文件已随 wolai-frontend 移入 recycle/,不再作为当前实现依据。

注意:

3000 当前根入口与文档页 shell 由 mnote-web Rust SSR 持有;Next App Router 已完全退役。

3.2 工作区壳与 Sidebar(已迁移至 Rust SSR

以下文件已随 wolai-frontend 移入 recycle/,不再作为当前实现依据:

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/app-layout-shell.tsx
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/hooks/use-sidebar-data.ts
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/lib/tree-stream/use-sidebar-tree-stream.ts
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/sidebar/use-preferred-sidebar-snapshot.ts

当前 Sidebar/工作区壳的当前实现在 Rust mnote-web SSR

  • 工作区壳渲染入口:gateway.rsroot_entry
  • 文档页壳/文档面板:web_shell.rsdocument_page_shellbuild_document_panes_bootstrap_json
  • Sidebar tree stream 消费:layout.rs 嵌入 JSstartWithSse / startWithWebSocket
  • FileTree 渲染与交互:tree.rs 嵌入 JS

4. 文档页主链

4.1 入口

文档页入口的当前实现在 Rust mnote-web

  • 文档页壳 SSRweb_shell.rsdocument_page_shell),直接输出 HTML + bootstrap JSON
  • Page Aggregate 快照 APIweb_shell.rspage_aggregate)返回 /api/page-aggregate/:id
  • 前端桌面/窗口面板布局:web_shell.rsbuild_document_panes_bootstrap_json

历史 wolai-frontend Next 文档页入口(已移入 recycle/):

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/lib/documents/page-aggregate-loader.ts
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/app/(app)/documents/[id]/page.tsx
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/lib/documents/page-aggregate.ts

4.2 文档壳(已迁移至 Rust SSR)

历史 React 文档壳组件(已随 wolai-frontend 移入 recycle/,不再作为当前实现):

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/document-shell.tsx
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/document-content.tsx

当前文档壳由 Rust mnote-web SSR 输出:

  • web_shell.rsdocument_page_shell 直接渲染 HTML shell,不在前端保留 React 文档壳 runtime。

4.3 默认编辑器 host(已迁移至 WASM island

历史 React 编辑器 host(已移入 recycle/):

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/editor-host-config.ts
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/editor-host.tsx
  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/leptos-tiptap-island-editor-host.tsx

当前默认主编辑器是页面内 Leptos/WASM island,由 Rust mnote-web SSR 加载:

  • WASM 产物:rust/spikes/leptos-tiptap-spike/
  • 加载路由:web_shell.rsleptos_tiptap_manifest / leptos_tiptap_asset

4.5 BlockNote 的当前位置

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/blocknote-editor.tsx

BlockNote 已随 wolai-frontend 移入 recycle,仅作为历史对照材料,不参与当前实现。

而不是默认主编辑器方向。

5. 当前编辑器与页面聚合关系

当前文档页已经开始消费统一的前端侧 PageAggregateProjection,但仍不能说“页面域已完全统一成 Rust 单一真源”。

当前真实状态是:

  • 读取主链已优先消费 Rust mnote.page_aggregate.v1 snapshot
  • Page Aggregate 已输出 blockDocumentblockProjectionVersionprojectionSource
  • 标题链路已开始与工作区树 canonical snapshot 对齐
  • 正文默认由 leptos-tiptap island 编辑与保存
  • 页面设置已有一部分进入 island 运行时语义
  • page_tree / pageSubtree 已进入统一聚合入口
  • 页面/块 AI tools 已开始通过 Page Aggregate block projection 读取、定位、dry-run、替换、插入和受限移动块,并经 page.body.save -> documents:updateContent 持久化

2026-05-16 更新:以下四项已通过真实 3000 browser smoke 验证(证据见 tmp/page-aggregate-* 目录):

  • 标题写入后 Page Aggregate、页头、Breadcrumb、Sidebar、Page Tree、File Tree 一致性(task110
  • 正文保存后 body.revision / conflictDetectionKey / blockDocument 同步(task-page-aggregate-body-sync-smoke
  • 页面设置写入后 layout.pageOptions 与 island runtime DOM 同步,刷新后不退回(task-page-aggregate-options-sync-smoke / task-page-aggregate-refresh-persistence-smoke
  • Convex 不可用时返回 degraded error503 + x-error-code=convex_unavailable),不返回伪 fixture(route 级负向测试)

仍未完成的关键点是:

  1. Rust 侧已提供最小 Page Aggregate snapshot 和 block projection v1,但当前 block projection 仍主要从 documents.content / local markdown content 投影(projectionSource=documents.content),不是 EditorBlockDocument 原生落库完成态
  2. 标题 / 正文 / 页面设置虽已收口到 page.* family 并通过 smoke,但客户端仍保留 PageAggregateClientState reducer(混合 server snapshot / draft title / local content),页面域单一真源仍未完全闭环
  3. AI 块工具最小闭环已启动且 fast-path < 1s,但 scope=selectionformat=page_xml/text、多块插入、复杂块移动矩阵和持久审阅 UI 仍未完成
  4. Sidebar 仍通过 preferred snapshotinitial / query / tree_stream)做 freshness 选择,tree realtime live cache 未统一

因此当前正确表述应是:

文档页读取主链已进入 Rust-first page aggregate 过渡态,标题/正文/页面设置 smoke 已通过,但页面域单一真源(ClientState → Rust snapshot)与 tree realtime live cache 仍未闭环。

6. 当前树域结构

6.1 Kernel projection 与 route

  • /mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/kernel.rs

当前 Rust 已提供:

  • sidebar_tree
  • page_tree
  • file_tree
  • subtree
  • edges
  • graph

这些 route 说明树域 projection family 已经在 Rust 侧具备清晰边界。

6.2 树命令现状

  • /mnt/Data1T/mnote/recycle/wolai-frontend/src/lib/documents/tree-command-client.ts
  • /mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/tree.rs
  • /mnt/Data1T/mnote/rust/crates/storage-convex-bridge/src/mapping.rs

当前树命令已经开始以 tree.* 为 preferred command name,例如:

  • tree.node.create
  • tree.node.rename
  • tree.subtree.move

但兼容层仍广泛保留:

  • documents.create
  • documents.title.update
  • documents.move

这说明 tree command cutover 已开始,但还没有完成。

6.3 树 realtime 现状

当前 Sidebar 已有:

  • query snapshot
  • tree stream
  • preferred snapshot 选择

正式的 snapshot + delta 主链已经固定到 mnote-web/api/tree/eventsNext /api/mnote-web/stream 只保留 compat alias。

因此当前正确表述应是:

树域 realtime 主链由 Rust Web /api/tree/events 持有,前端只消费稳定 stream contract 与 projection。

补充:

3000 主壳当前已不再通过 /api/tree/projections/* 额外维护第二条 runtime live fallbacksnapshot / delta / resync 直接消费 /api/tree/events 载荷。

6.4 Resource Tree / File Tree / Page Tree 三层模型

当前树域已建立三层语义(合同见 design/04-tree-domain/done/4-24-*design/05-editor-mainline/done/5-12-*):

  • Resource Tree:长期 canonical 对象组织树,Rust kernel 持有语义。资源类型包括 page、mindmap、attachment、onlyoffice、code 等(KernelObjectIdentityKernelProjectionResourceKind 已在 core-protocol 落地)。
  • File TreeResource Tree 的主组织投影。展示页面文件夹、{title}.md(非 index.md)、mindmap、附件等资源。文件树行消费 Rust /api/tree/projections/file 或等价 projection,不在前端临时拼装第二真相。
  • Page Tree:面向阅读/导航的快捷投影。只显示页面关系和导航语义,不拥有排序、父子、附件归属的最终真相。

关键规则:

  • 文件树点击 mindmap 打开 mindmap object editor,不被 {title}.md 吞掉
  • {title}.md 只代表页面正文(Page Aggregate body),mindmap / OnlyOffice / 附件是不同 object model
  • 页面树不持有独立结构真相,只显示文档导航关系

7. Mindmap 与 OnlyOffice

7.1 Mindmap

当前 Mindmap 不再是系统中心,而是:

  • tree-first graph kernel 的一种视图 / 编辑挂件

它仍有:

  • 文档内嵌块形态
  • 独立页面形态

但不应再被理解为对象真相层。

7.2 OnlyOffice

OnlyOffice 仍然是:

  • 独立页面型编辑器

它不直接嵌入正文主编辑画布;正文中通常通过附件块跳转进入。

8. 当前最优先的架构收口

当前最优先的三条主线,不是继续大规模 UI 重写,而是:

8.1 Page Aggregate

目标:

  • 让标题 / 页面设置 / 正文 / page tree 统一成同一组 page aggregate projection 与 command family
  • 前端不在页面壳、island 外侧、Sidebar preferred snapshot 外再拼第二份页面真相

当前进度(2026-05-16):

  • 文档页读取主链已 Rust-firstTS builder 退出 runtimeNext compat 返回 410
  • 标题单一真源 smoke 通过(task110):页头/Breadcrumb/Sidebar/Page Tree/File Tree 一致
  • 正文写入后 body.revision / blockDocument 同步 smoke 通过
  • 页面设置写入后 pageOptions 同步与刷新持久化 smoke 通过
  • Convex 不可用时返回 degraded error,不返回伪 fixture
  • block projection 从 EditorBlockDocument 原生落库(当前仍从 documents.content 投影)
  • 客户端 PageAggregateClientState reducer 退役,页面域完全以 Rust snapshot 为单一运行时真相

对应设计稿:

  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-5-page-aggregate-single-truth-alignment-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/done/5-5-1-page-aggregate-contract-v1.md

8.2 Tree Command Cutover

目标:

  • tree.* 成为正式命令面
  • documents.* 降为兼容层

对应设计稿:

  • /mnt/Data1T/mnote/design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md

8.3 Tree Realtime Event Stream

目标:

  • 让 snapshot + delta 正式成为树域实时主链
  • 减少当前 query/refetch/freshness 补偿链的长期存在

对应设计稿:

  • /mnt/Data1T/mnote/design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md

8.4 Page / Block AI Tooling

目标:

  • 让 AI 读取、定位、dry-run 和精确块写入统一走 Rust Hermes tools、Page Aggregate block projection 与 EditorCommand
  • mnote.page.save 固定为页面级兜底写入工具,不再代表长期精确块编辑主入口
  • 补齐 scope=selectionformat=page_xml/text、多块插入、复杂块移动矩阵和持久审阅 UI

当前进度(2026-05-16,按 7-14 v2 更新):

  • 页面 AI 快速编辑 route 已上线:POST /api/page-ai/block-edit-workflow
  • 简单编辑本地 plannerlocal_rule)已验证:788ms(过渡实现,将被 markdown_edit 替代)
  • Hermes toolsmnote.doc.* / mnote.block.*)已可读取和写入块投影
  • 参考实现已确认两层模型可行性:CLI Main(Lark Docstr_replace 对应 markdown_editblock_* 对应 apply_block_ops
  • Phase A(当前唯一活跃实施)mnote.doc.markdown_edit + mnote.doc.fetch 增强(search/replace + format: "markdown" + local source + Hermes 注册)
  • Phase B(下一阶段):退役 direct_block_edit_operationspage_ai_workflow.rs 改走 markdown_editsystem prompt 产 search/replace 对
  • scope=selectionformat=page_xml/text 稳定输出
  • tool manifest annotationsreadonly / destructive / requiresApproval 等)
  • Phase C(设计冻结,不实施)StreamApplyController + ReviewSession + GhostTextOverlay(流式 apply + suggest/review
  • stale revision / idempotency 重放保护(已有 revision 乐观锁覆盖,补端到端 smoke)

关键原则(2026-05-16 补充,按 7-14 v2 更新):

  • 两层操作模型(参考 CLI Main Lark Doc):文本级 mnote.doc.markdown_editstr_replace)为主路径(覆盖 80%+ 场景),块级 mnote.doc.apply_block_ops 为结构性辅助(< 20%
  • AI 编辑主路径应从块级降维到 markdown 文本层:新增 mnote.doc.markdown_editsearch/replace 或 full_content)作为主要 AI 写入工具
  • mnote.block.* 降级为结构性辅助(拖拽排序、精确块删除等),不删除
  • 当前 local_rule plannerdirect_block_edit_operations)是过渡实现,应退役并替换为模型产出 search/replace 对
  • 在线 Convex 文档和本地 .md 文件共用同一条 markdown AI 写入路径(resolve_source → Convex | LocalFS
  • Markdown 既是 AI 编辑格式也是人类可读格式,不需要 XML 中间层
  • 流式 apply + suggest/review(参考 BlockNote AI 的 StreamToolExecutor + suggestChanges)仅作为 Phase C 设计冻结,当前不实施

对应设计稿:

  • /mnt/Data1T/mnote/design/07-ai/process/7-10-page-block-ai-tooling-execution-checklist-v1.md
  • /mnt/Data1T/mnote/design/10-review/process/09-page-ai-fast-block-edit-runtime-review.md
  • /mnt/Data1T/mnote/design/07-ai/process/7-14-online-local-ai-markdown-editing-convergence-v1.md

8.5 定向 Bug Hunt 与质量基线

目标:

  • 围绕已知架构风险做定向排查,而非泛泛"找 bug"

优先关注:

  • Page Aggregate 回流不一致
  • AI 块写入 conflict / stale revision
  • File Tree {title}.md 与 page title 同步
  • tree stream resync / 双浏览器一致性
  • debug / compat / fallback 是否混入首屏主链

已有 smoke 体系(scripts/ 目录):

  • task110-page-title-single-truth-smoke.js:标题全链路一致性
  • task-page-aggregate-body-sync-smoke.js:正文写入后 Page Aggregate 同步
  • task-page-aggregate-options-sync-smoke.js:页面设置写入后同步
  • task-page-aggregate-refresh-persistence-smoke.js:刷新持久化
  • task123-rust-web-tree-live-stream-consumer-smoke.jstree realtime 消费
  • task169-mindmap-realtime-smoke.jsmindmap 隔离与持久化
  • task179-tree-create-delete-no-reload-smoke.js:树操作无刷新

9. 当前不该再用的旧口径

下面这些说法现在都不准确:

  • “默认文档页仍然是 BlockNoteEditor
  • “主编辑器还没切到页面内 Leptos island”
  • “当前最优先是继续证明 leptos-tiptap 能不能跑”
  • “当前最优先是先做树域 UI 重构”
  • “Rust Web 还只是实验,没有接真实页面链路”
  • “页面 AI 编辑必须经过 Hermes agent,没有快路径”

当前真正的卡点已经从“能不能跑”变成:

单一真源如何收口(Page Aggregate ClientState → Rust snapshot),projection / command / realtime 三条链如何从兼容态进入正式主链,以及 AI 块编辑如何从“能写”变成产品级可靠(selection、review、conflict、idempotency)。