Files
mnote/design/04-tree-domain/done/4-4-tree-projection-protocol-contract-v1.md
T
lix-2026 5f97800489 chore: align local-first control plane and editor fixes
- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
2026-05-23 23:38:42 +08:00

5.4 KiB
Raw Blame History

4-4 [done] Tree Projection Protocol Contract v1

更新时间:2026-04-18

关联:

  • /mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md
  • /mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md

1. 目的

这份文档用于冻结树域 projection contract,避免 sidebar_treepage_treefile_tree 在后续 Rust route、Leptos tree shell、Next 挂载切流阶段继续各自长字段。

这里固定三条原则:

  • 树域只消费 projection,不消费前端自己拼出来的结构真相
  • Rust 与前端共享同一组 projection 字段语义
  • sidebar_treepage_treefile_tree 是同一协议家族,不是三套无关返回值

2. 协议分层

2.1 Rust canonical contract

Rust 侧的 canonical contract 统一表达为:

  • projection_id
  • projection
  • root_node_id
  • items
  • edges

items 里的字段语义冻结如下。

2.2 TypeScript transport contract

前端 TypeScript 侧继续使用 camelCase 字段,但语义必须与 Rust 一致:

  • projectionId
  • projectionKind
  • rootNodeId
  • parentNodeId
  • resourceMeta
  • iconHint
  • expandedByDefault

也就是说:

  • Rust 是 canonical truth
  • TypeScript 只是命名风格映射,不允许再引入第二套语义

3. 共享字段

下面这些字段属于 sidebar_treepage_treefile_tree 的共享基线。

canonical TS 说明
node_id nodeId 当前 projection item 对应的 kernel node
parent_node_id parentNodeId 上级 node,根节点为 null
node_type nodeType workspace/folder/page/section/asset/book/pdf/mindmap/table/index 等语义类型
projection_kind projectionKind 当前 item 属于哪种 projectionsidebar_tree/page_tree/file_tree
title title 展示标题,允许兜底为“无标题”
depth depth 当前树深度
position position 同级排序位置
child_count childCount 子项数量
expandable expandable 当前 item 是否理论上可展开
expanded_by_default expandedByDefault 默认展开建议
capabilities capabilities 当前行允许的交互能力
resource_meta resourceMeta 绑定到业务资源的元信息
icon_hint iconHint 给 shell / renderer 的图标提示

4. capabilities 冻结口径

当前允许的共享 capabilities 为:

  • expand
  • open
  • drag
  • drop
  • select
  • create-child
  • rename
  • archive
  • restore
  • context-menu
  • reorder
  • open-asset
  • pick

约束:

  • capabilities 只表达“允许做什么”
  • 它不表达局部 UI 状态
  • 它不表达 hover、selected、dragging、drop target 这类临时态

5. resource_meta 冻结口径

resource_meta 统一用于表达 projection item 背后的真实资源。

共享字段:

  • resource_kind
  • document_id
  • asset_id
  • workspace_id
  • asset_kind
  • icon_hint
  • extra

5.1 resource_kind

当前冻结为:

  • workspace
  • document
  • index
  • asset
  • asset_folder
  • mindmap
  • table
  • book
  • pdf

5.2 asset_kind

当前冻结为:

  • file
  • mindmap
  • table
  • book
  • pdf
  • image
  • video
  • audio
  • unknown

6. 三类 projection 的差异字段

6.1 sidebar_tree

sidebar_tree 是最轻的导航 projection。

要求:

  • 保留共享字段
  • 不引入 row_id
  • 资源主语义通常落在 resource_kind=document
  • 允许后续继续作为 workspace 首屏 / stream snapshot 主链

6.2 page_tree

page_tree 是页面树 projection。

它在共享字段基础上新增:

  • row_id

当前 row_id 命名约束:

  • page:<nodeId>

要求:

  • page_tree 必须可直接生成 picker 轻量列表
  • page_tree 必须可直接生成可见 rows
  • page_tree 不允许重新回退成前端自行 flatten 嵌套树

6.3 file_tree

file_tree 是页面树骨架上的更宽对象投影。

它在共享字段基础上强调这些字段必须稳定存在:

  • resource_kind
  • asset_kind
  • icon_hint
  • expandable
  • expanded_by_default

要求:

  • file_tree 不能继续由前端用 asset-folder / asset / index 临时猜语义作为长期真相
  • file_tree 必须由 Rust 直接输出 document/index/asset/asset_folder/mindmap/table/book/pdf 等对象投影

7. 当前稳定项与过渡项

7.1 已稳定

  • sidebar_tree 基础 contract
  • page_treerow_id/node_id/parent_node_id/depth/position/capabilities/resource_meta
  • expanded_by_default
  • child_count

7.2 仍处于过渡

  • file_tree 里的 asset_folder/asset/index 仍有前端 adapter 残留
  • icon_hint 还没有完全由 Rust 主导
  • asset_kind 仍需要从更宽对象类型扩展到 book/pdf

8. Fixture 与 Contract Test 要求

后续所有树域 fixture / contract tests 至少覆盖:

  • sidebar_tree 基础 fixture
  • page_tree fixture
  • file_tree fixture
  • resource_meta 差异字段
  • capabilities
  • icon_hint
  • expanded_by_default

9. 完成判定

当以下条件同时成立时,视为本 contract 冻结完成:

  • sidebar_treepage_treefile_tree 的共享字段与差异字段都已写成文档与共享类型
  • Rust 与前端共享同一组字段语义
  • file_tree 不再依赖前端“补字段猜语义”
  • 后续 shell / renderer / route 改造不再新增破坏性字段