285 lines
44 KiB
Markdown
285 lines
44 KiB
Markdown
# [recycle] mnote 单仓收口 Rust 内核阶段 Checklist
|
||||
|
|
|
|||
|
|
> 更新时间:2026-04-14
|
|||
|
|
>
|
|||
|
|
> 主工作路径:`/mnt/Data1T/mnote`
|
|||
|
|
>
|
|||
|
|
> 第二工作路径:`/mnt/Data1T/mnote-rust`(仅作为历史资产来源,不作为主执行仓)
|
|||
|
|
>
|
|||
|
|
> 对齐文档:`/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/rust-kernel-backport-plan.md`
|
|||
|
|
>
|
|||
|
|
> 目标:把 `mnote-rust` 的必要 Rust 内核逐步回迁到 `mnote` 主仓,并始终维持“单仓启动、单仓保存、主前端不分叉”的执行口径。
|
|||
|
|
|
|||
|
|
## 1. 执行口径与硬边界
|
|||
|
|
|
|||
|
|
- [x] 只保留 `/mnt/Data1T/mnote` 作为唯一主产品仓。
|
|||
|
|
- [x] `/mnt/Data1T/mnote-rust` 只保留为历史资产来源、参考实现和待吸收规范,不再承担主线执行入口。
|
|||
|
|
- [x] `wolai-frontend` 继续承担唯一主产品前端壳,不复制 `mnote-rust` 的第二套 Next 前端壳。
|
|||
|
|
- [x] Rust 内核统一收口到 `/mnt/Data1T/mnote/rust/`,不再在主仓根目录散落多个 Rust 源码根。
|
|||
|
|
- [x] 最终保存只认 Convex 主事实层;Rust 的事件、索引、缓存、fixtures 都属于派生层。
|
|||
|
|
- [x] 不通过跨仓软链接、硬链接或路径偷接来假装完成迁移。
|
|||
|
|
- [x] 第一阶段不迁入 `design/phases/**`、`design/execution/**`、`design/UI/**` 这类历史叙事文档。
|
|||
|
|
- [x] 第一阶段不迁入 `mnote-cli`、`adapter-onlyoffice`、`adapter-mindmap`、`adapter-legacy-mnote`。
|
|||
|
|
- [x] Mindmap 继续以 `mnote` 当前实现为主:BlockNote 自定义块为主形态,独立全屏页为辅助形态。
|
|||
|
|
- [x] OnlyOffice 继续保持“正文只嵌文件入口、编辑器在独立页面运行”的产品形态,不回嵌 BlockNote。
|
|||
|
|
- [x] `wolai-frontend/`、`wolai-backend/`、`infra/convex/`、`src/components/onlyoffice/` 默认保持不动,除非后续阶段明确接线需要。
|
|||
|
|
|
|||
|
|
## 2. 当前已确认基线(2026-04-13 已核对)
|
|||
|
|
|
|||
|
|
### 2.1 已完成事实
|
|||
|
|
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/Cargo.toml` 与 `/mnt/Data1T/mnote/rust/Cargo.lock` 已存在。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/crates/` 下已落位 `core-domain`、`core-protocol`、`event-log`、`storage-convex-bridge`、`index-fts`、`bridge-runtime`、`mnote-cli`。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/design/INDEX.md` 与 `design/core/01~04` 核心设计文档已落位。
|
|||
|
|
- [x] workspace members 仅指向 `/mnt/Data1T/mnote/rust/crates/*`。
|
|||
|
|
- [x] 已验证 `cargo metadata --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml --format-version 1` 可通过。
|
|||
|
|
- [x] 已验证 `cargo check --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml` 可通过。
|
|||
|
|
- [x] 已核对 `/mnt/Data1T/mnote/rust/` 下未发现直接引用 `/mnt/Data1T/mnote-rust` 的残留路径。
|
|||
|
|
- [x] 已确认当前主前端链路仍在 `mnote`:文档页为 `DocumentShell -> DocumentContent -> BlockNoteEditor`,Mindmap 仍复用现有 `MindmapBlock` 体系,OnlyOffice 仍为独立页面型编辑器。
|
|||
|
|
|
|||
|
|
### 2.2 当前仍未开始或未初始化的事实
|
|||
|
|
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/bridge/` 已初始化最小说明目录,`crates/bridge-runtime` 已提供 Phase 1 最小真实执行样板。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/scripts/` 当前未初始化。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/fixtures/` 当前未初始化。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/rust/tests/` 当前未初始化。
|
|||
|
|
- [x] `mnote-cli` 已并入 `/mnt/Data1T/mnote/rust/crates/`,当前已冻结 `page/block/search/sidebar/tool` 的最小命令面与 `--json` 输出协议。
|
|||
|
|
- [x] `adapter-onlyoffice`、`adapter-mindmap`、`adapter-legacy-mnote` 尚未并入主仓。
|
|||
|
|
- [x] `/api/documents/content`、`/api/documents/save`、`/api/documents/title`、`/api/documents/stats`、`/api/sidebar`、`/api/blocks/patch` 已接入主仓当前 bridge 包装层并统一返回 `request_id/trace_id` 元信息;其中 `documents/title`、`documents/stats`、`documents/options`、`documents/save` 已进一步收口到统一的 bridge mutation request 运行时接缝,可先构造与 `storage-convex-bridge::build_write_request` 对齐的 `functionName/payloadJson/args` 对象再落到 Convex,但整条链仍未直接切到 `core-protocol -> storage-convex-bridge` 的真实 Rust crate 执行链。
|
|||
|
|
|
|||
|
|
2026-04-15 Phase 1/2 补记:`documents.content.get`、`documents.title.update`、`documents.save` 这 1 读 2 写链现已从主仓 Next route 真实进入 `crates/bridge-runtime`,再由 TS 仅做 Convex transport;同时 `crates/mnote-cli` 已在主仓 workspace 落位,并通过 `page/block/search/sidebar/tool` 五类最小命令面的 `--json` 计划输出冻结当前 CLI 协议。
|
|||
|
|
|
|||
|
|
## 3. Phase A:Rust workspace 落位(主目标已完成)
|
|||
|
|
|
|||
|
|
完成目标:
|
|||
|
|
|
|||
|
|
- `/mnt/Data1T/mnote/rust/` 成为唯一 Rust workspace 根。
|
|||
|
|
- P0 crate 与核心规范文档已在主仓内有真实副本。
|
|||
|
|
- 新 workspace 已具备最小自检能力。
|
|||
|
|
|
|||
|
|
Checklist:
|
|||
|
|
|
|||
|
|
- [x] 固定 `/mnt/Data1T/mnote/rust/` 为唯一 Rust workspace 根,后续 Rust 命令统一从这里发起。
|
|||
|
|
- [x] 固定 workspace members 只指向 `crates/core-domain`、`crates/core-protocol`、`crates/event-log`、`crates/storage-convex-bridge`、`crates/index-fts`。
|
|||
|
|
- [x] 复制并落位 `core-domain`、`core-protocol`、`event-log`、`storage-convex-bridge`、`index-fts`。
|
|||
|
|
- [x] 复制并落位 `rust/design/INDEX.md` 与 `rust/design/core/01-domain-model-v0.md`、`02-command-query-tool-protocol-v0.md`、`03-storage-event-indexing-v0.md`、`04-onlyoffice-integration-boundary-v0.md`。
|
|||
|
|
- [x] 统一 workspace 级别的 `edition`、`license`、`version`、`authors` 约定。
|
|||
|
|
- [x] 跑通 `cargo metadata --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml --format-version 1`。
|
|||
|
|
- [x] 跑通 `cargo check --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml`。
|
|||
|
|
- [x] 已补跑 `cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p core-domain` 与 `cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p core-protocol`。
|
|||
|
|
- [x] 已在本 checklist 第 1 节固定“第一阶段禁止迁入清单”,明确 `mnote-cli`、`adapter-*`、`design/phases/**`、`design/execution/**`、第二套 Next 前端壳均不属于本阶段交付。
|
|||
|
|
|
|||
|
|
Phase A 验收:
|
|||
|
|
|
|||
|
|
- [x] Cargo 可在主仓内解析 workspace。
|
|||
|
|
- [x] 主仓内已有 P0 内核与长期规范副本。
|
|||
|
|
- [x] 当前未出现对第二工作路径的直接 Cargo 路径依赖。
|
|||
|
|
- [x] 已完成 crate 单测与文档级禁止迁入清单,Phase A 可视为关闭。
|
|||
|
|
|
|||
|
|
## 4. Phase B:bridge 入口与 Convex 桥接
|
|||
|
|
|
|||
|
|
完成目标:
|
|||
|
|
|
|||
|
|
- 在 `mnote` 主仓内形成唯一 Rust command/query 入口。
|
|||
|
|
- 首批读写入口从“前端 API 直接调 Convex”切到“前端 API -> Rust bridge -> Convex”。
|
|||
|
|
|
|||
|
|
当前起点(已确认):
|
|||
|
|
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/content/route.ts` 当前直接 `query(api.documents.getContent)`。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/save/route.ts` 当前已改为构造稳定 envelope 后交给 `save-command-adapter` 执行。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/title/route.ts` 当前已不再直接拼 `mutation(api.documents.updateTitle)` 参数,改为构造稳定 envelope 后交给页面元信息 command adapter 执行。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/stats/route.ts` 当前已不再直接拼 `mutation(api.documents.updateStats)` 参数,改为构造稳定 envelope 后交给页面元信息 command adapter 执行。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/sidebar/route.ts` 当前直接聚合多个 Convex query 结果。
|
|||
|
|
- [x] `/mnt/Data1T/mnote/wolai-frontend/src/app/api/blocks/patch/route.ts` 当前直接读取文档内容、替换 block 树后回写 Convex。
|
|||
|
|
|
|||
|
|
Checklist:
|
|||
|
|
|
|||
|
|
- [x] 已在 `wolai-frontend/src/lib/documents/bridge.ts` 固定当前 bridge 入口,先由主仓 API route 统一走同一层包装。
|
|||
|
|
- [x] 已固定首批 bridge envelope:`request_id`、`trace_id`、`workspace_id`、`actor`、`source`、`idempotency_key`。
|
|||
|
|
- [x] 约定所有新命令和查询都先进入 `core-protocol` envelope,再转给 `storage-convex-bridge`。
|
|||
|
|
- [x] 已把 `documents/content` 与 `sidebar` 两条低风险读链接入当前 bridge query 包装层。
|
|||
|
|
- [x] 已把 `documents/title`、`documents/stats`、`documents/save`、`blocks/patch` 接入当前 bridge command 包装层。
|
|||
|
|
- [x] 已为 `documents/title`、`documents/stats` 收口稳定的页面元信息 command adapter,冻结 route 到 Convex 之间的 payload/target/meta 映射,避免 route 继续直接耦合 `updateTitle/updateStats` 的参数细节。
|
|||
|
|
- [x] 已为首批 4 条写链固定当前 `bridge -> Convex` 的函数名、payload 结构和 workspace scope;其中 `documents.title`、`documents.stats`、`documents.options`、`documents.save` 已先收口到 `buildDocumentBridgeMutationRequest` 这层最小运行时接缝,统一构造与 `storage-convex-bridge::build_write_request` 对齐的 `functionName/payloadJson/args`,再由同一执行器落到 Convex;`blocks.patch` 仍未收口到该执行层,且整条链尚未直接切到 Rust crate 内统一执行。
|
|||
|
|
- [x] 已在 `wolai-frontend/convex/schema.ts` 新增 `command_logs`、`domain_events` 两张表,并新增 `wolai-frontend/convex/bridgeLogs.ts` 与 `src/lib/documents/bridge-log.ts` 承接首批写链日志落账。
|
|||
|
|
- [x] 首批 4 条写链(`documents/title`、`documents/stats`、`documents/save`、`blocks/patch`)当前会在成功路径同时写入 command log 与 domain event;失败态、回滚态和统一事务性仍待后续补齐。
|
|||
|
|
- [x] 当前已接入的查询链(`documents/content`、`sidebar`)保持只读,不产生写副作用。
|
|||
|
|
- [x] 已统一 `documents/content`、`documents/save`、`documents/title`、`documents/stats`、`sidebar` 的首批 bridge 错误返回结构。
|
|||
|
|
- [x] 当前 bridge 仅负责协议校验、请求映射与响应元信息包装,尚未吞并产品 UI 逻辑。
|
|||
|
|
|
|||
|
|
2026-04-14 B 阶段补记:已在 `rust/crates/core-protocol` 中补齐 `documents.meta.get`、`documents.content.get`、`sidebar.dataset.list`、`documents.save`、`blocks.patch` 的最小 query/command 协议对象,并在 `rust/crates/storage-convex-bridge` 中补齐对应的 query/command name -> Convex function 映射与单测。当前主仓新增链路已统一先构建稳定 envelope,再由后续真实 Rust bridge 执行链消费;本轮已通过 `cargo test -p core-protocol -p storage-convex-bridge` 与 `cargo check --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml` 验证协议与映射闭环。
|
|||
|
|
2026-04-14 B 阶段第三刀补记:已在 `wolai-frontend/src/lib/documents/bridge.ts` 新增 `buildDocumentBridgeMutationRequest` 与统一执行器,把 `documents.title.update`、`documents.stats.update`、`documents.options.update`、`documents.save` 进一步推进到最小可运行的 Rust bridge 风格接缝。当前这些写链会先生成与 `storage-convex-bridge::build_write_request` 对齐的 `functionName/payloadJson/args` 运行时对象,再由适配层调用 Convex mutation;配套 `src/lib/documents/bridge.test.ts` 已新增 request builder 断言,确认标题更新与正文保存两条链的运行时 request 形状稳定。
|
|||
|
|
|
|||
|
|
Phase B 验收:
|
|||
|
|
|
|||
|
|
- [x] 当前至少已有 2 条查询链(`documents/content`、`sidebar`)和 4 条写链(`documents/title`、`documents/stats`、`documents/save`、`blocks/patch`)通过当前 bridge 包装层读写 Convex。
|
|||
|
|
- [x] 已补 `/api/bridge/trace`、`/api/bridge/request` 回查入口,并已切到 `wolai-frontend/convex/bridgeLogs.ts` 查询主线;`convex/audit.ts` 当前保留为并行旧实现线,不作为本轮回查入口。
|
|||
|
|
- [x] 当前已接入的请求错误结构已统一到 bridge 错误响应,不再直接抛出临时调试字符串。
|
|||
|
|
- [x] 本批改动只改 API route 与调用 payload,未改页面结构与 UI 外观。
|
|||
|
|
|
|||
|
|
建议验证:
|
|||
|
|
|
|||
|
|
- [x] `cargo check --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml`
|
|||
|
|
- [x] 已对 `/api/documents/content`、`/api/sidebar` 做最小读链 smoke:当前主仓实例固定为 `http://127.0.0.1:3001`,`/api/sidebar` 已返回 `activeWorkspaceId=ws-smoke-temp`,新建文档后 `/api/documents/content` 可正常返回内容与 `requestId/traceId`。
|
|||
|
|
- [x] 已对 `/api/documents/title`、`/api/documents/stats`、`/api/documents/save`、`/api/blocks/patch` 做最小写链 smoke:真实写入成功,且随后 `/api/documents/content` 已读回 `blocks.patch` 改写后的正文。
|
|||
|
|
- [x] 已完成真实 Convex 运行前置验证:`infra/convex/docker-compose.yml` 可启动本地自托管 Convex,`pnpm exec convex dev --once --tail-logs disable --env-file ../.env.all --run ping:ping` 已通过。
|
|||
|
|
- [x] 已用真实 Convex CLI 对 `bridgeLogs:recordCommandLog`、`bridgeLogs:recordDomainEvent`、`bridgeLogs:listByTrace`、`bridgeLogs:listByRequest` 做最小 smoke,确认 command log、domain event、trace/request 字段能同时落账并回查。
|
|||
|
|
- [x] 已完成网页/API 级 smoke:从真实 `/api/documents/title`、`/api/documents/stats`、`/api/documents/save`、`/api/blocks/patch` 返回的 `requestId/traceId`,可继续经 `/api/bridge/trace` 与 `/api/bridge/request` 回查到对应 `command_logs/domain_events`。本轮同时修复 `src/lib/documents/bridge-log.ts` 中 `getAuthedConvexClient()` 返回值解构错误(此前会导致写链落账时报 `client.mutation is not a function`)。
|
|||
|
|
|
|||
|
|
## 5. Phase C:页面元信息、Sidebar 与正文保存接入
|
|||
|
|
|
|||
|
|
完成目标:
|
|||
|
|
|
|||
|
|
- 在不更换主前端壳的前提下,把文档元信息、Sidebar 聚合、BlockNote 正文保存逐步切到 Rust 协议层。
|
|||
|
|
- 执行顺序严格按 `C1 页面元信息 -> C2 Sidebar 聚合 -> C3 正文保存` 推进,不跳步。
|
|||
|
|
|
|||
|
|
### C1 页面元信息
|
|||
|
|
|
|||
|
|
- [x] 已盘点并锁定文档页元信息读写边界:`src/app/(app)/documents/[id]/page.tsx` 负责元信息入口,`document-content.tsx` 负责标题/页面选项/统计信息写入,`document-shell.tsx` 仅继续透传既有 UI 壳参数。
|
|||
|
|
- [x] 已锁定并接入当前 C1 最小读链:`src/app/(app)/documents/[id]/page.tsx` 原先直调 `api.documents.getMeta`,现已改为经 `GET /api/documents/meta` 进入现有 bridge query 包装层;新增的服务端 helper 仅负责透传当前请求认证/追踪头并发起同源 bridge route 请求。
|
|||
|
|
- [x] 已把标题更新、页面属性、页面选项、统计信息这批低风险页面元信息操作切到统一的当前协议/适配边界:标题、统计信息、页面选项 3 条写链都已接入当前 bridge command 包装层;其中 `documents.title.update`、`documents.stats.update`、`documents.options.update` 已统一收口到 `wolai-frontend/src/lib/documents/metadata-command-adapter.ts`,route 只保留 validation、`buildDocumentBridgeContext`、`buildDocumentCommandEnvelope` 与稳定错误模型。`documents.options` 本轮不再内联 `client.mutation(api.documents.updateOptions, ...)`。同时已补齐 `rust/crates/core-protocol` 的 `UpdatePageTitle`、`UpdatePageStats`、`UpdatePageOptions` 结构与 `storage-convex-bridge` 的 command name -> Convex mutation 映射测试;2026-04-14 又进一步把这 3 条写链切到 `buildDocumentBridgeMutationRequest`,先构造与 Rust `ConvexMutationRequest` 对齐的最小运行时 request,再交给统一执行器落到 Convex,为后续真实 Rust 执行链留出稳定接缝。
|
|||
|
|
- [x] 当前最小替换已保持现有页面 UI、权限判断、动态导入结构不变:`DocumentShell` 入参、`readOnly/disableDownload/disableCopy` 计算、`notFound()` 分支与页面结构保持不变,仅将元信息读取入口切到 `documents.meta` bridge query。
|
|||
|
|
- [x] 已统一页面元信息链当前口径:`documents.meta` 读链与 `documents.title/stats/options` 写链均复用 `buildDocumentBridgeContext` / envelope;query payload 与 command payload 已固定 `documentId/workspaceId`,target.pageId 固定文档 business id,回传元信息统一为 `requestId/traceId/queryName|commandId|commandName`,actor/source 也统一来自 bridge context。
|
|||
|
|
- [x] 已为标题更新、页面属性、统计信息补齐当前最小回归验证。
|
|||
|
|
当前最小验证:已对页面选项写链补跑相关文件 eslint / vitest,并完成真实 HTTP smoke,确认在主仓 `http://127.0.0.1:3001` 实例下以 `ws-smoke-temp` 工作区调用 `POST /api/documents/options` 后,会返回 `requestId=req_aef4159e-24f2-43a8-b168-864c4b2b2c6c`、`traceId=trace_3cbc114e-db01-410f-933c-e63d8bd83393`、`commandId=cmd_2cb6871d-9075-4252-b698-a7c4ea069bfd`,且后续 `/api/bridge/request` 与 `/api/bridge/trace` 已能回查到对应 `command_logs/domain_events`。本轮同时保留 `documents.meta` 读链最小验证:真实 `GET /api/documents/meta?documentId=...&workspaceId=ws-smoke-temp` 已返回 `doc + meta.requestId/traceId/queryName=documents.meta.get`。另外 `documents/stats` 写链的真实 HTTP smoke 也已完成并可回查。2026-04-14 新增一轮真实复测:同一 `documentId` 连续执行 `POST /api/documents/options {showToc:true,layoutDensity:\"compact\"}` 与 `POST /api/documents/stats {wordCount:12,characterCount:34,blockCount:2,todoTotal:5,todoDone:3}` 后,紧跟 5 次 `GET /api/documents/meta` 均稳定返回本次写入值,未再复现“同次写入后 meta 读回不稳定”的现象。为避免历史脏数据导致偶发漂移,已把 `convex/documents.ts` 的关键 `by_document_id` 读写收口到 deterministic canonical record 选择逻辑,并补了重复 business id 的回归测试。
|
|||
|
|
2026-04-14 第二批真实收口:已将仍直接依赖 `by_document_id.first()` 的高风险页面/文档关联路径继续切到同一 canonical document helper,当前已覆盖 `convex/documentShares.ts`、`convex/documentGroupShares.ts`、`convex/documentStars.ts`、`convex/comments.ts`、`convex/references.ts`。这批路径分别影响页面共享权限判定、群组公开、收藏可见性、评论线程读写与反链标题读取;此前若同一 business `documentId` 存在重复物理记录,会继续存在命中漂移风险。本轮已补跑目标文件 `eslint`、`src/lib/documents/document-record.test.ts`,并用源码扫描确认这批目标文件内已不再残留 `by_document_id.first()`;当前未继续扩到 `mediaAssets.ts`、`mindmaps.ts` 等非本批最小闭环路径。
|
|||
|
|
2026-04-14 第三批真实收口:继续只处理剩余 still-high-risk 的 `documents.by_document_id` 直接命中点,已新增 `convex/_utils/documentRecord.ts#getCanonicalParentDocumentId`,并把 `convex/comments.ts`、`convex/documents.ts` 中共享/权限祖先链扫描统一改到该 helper,避免同一 business `documentId` 的重复物理记录在父链遍历时再次漂移。同时已把 `convex/mindmaps.ts` 的 owner 校验从 `by_document_id.first()` 切到 `requireCanonicalOwnedDocument`,并将 `convex/mediaAssets.ts#createWithStorage` 的页面归属校验改为 `getCanonicalDocumentByBusinessId`,以覆盖页面内容附件上传这一仍会直接命中旧记录的高风险入口。本批最小验证目标为:补充 canonical helper 单测、对上述目标文件跑 `eslint`,并再次用源码扫描确认 `comments/documents/mindmaps/mediaAssets` 内不再残留直接依赖 `documents.by_document_id` 的实现。
|
|||
|
|
2026-04-14 第四批真实收口:按本轮 C1 要求只处理 `convex/documentStars.ts` 剩余两个父链祖先扫描点,已将 `resolveSharePermission` 与 `resolveGroupSharePermission` 中手写的 `documents.by_document_id` 父级推进统一改为 `getCanonicalParentDocumentId`。同时已补充 `src/lib/documents/document-record.test.ts` 的 helper 回归用例,验证重复 business `documentId` 下即使旧记录已删除,父链 helper 仍稳定返回 canonical 父页面 id;并已补跑目标文件 `eslint` 与 `vitest`。本轮源码扫描确认 `wolai-frontend/convex/` 业务路径中已不再残留直接 `withIndex(\"by_document_id\")` 命中点,当前仅剩 `convex/_utils/documentRecord.ts` 作为底层 canonical helper 持有该查询。
|
|||
|
|
|
|||
|
|
C1 验收:
|
|||
|
|
|
|||
|
|
- [x] 页面元信息至少已有 3 条低风险链路切入 Rust 层。
|
|||
|
|
- [x] 文档页外观与交互未退化。
|
|||
|
|
- [x] trace 字段已可回查到页面级写入:`documents.title.update`、`documents.stats.update`、`documents.options.update` 的真实 HTTP 写入均已返回 `requestId/traceId`,且后续 `/api/bridge/request` 与 `/api/bridge/trace` 已复核可查到对应 `command_logs/domain_events`。
|
|||
|
|
|
|||
|
|
2026-04-14 C1 浏览器回归补记:已新增 `/mnt/Data1T/mnote/scripts/task019-document-ui-regression.js` 并在真实本地实例 `http://127.0.0.1:3001` 上执行。脚本会创建临时页面,确认 Sidebar 主导航与“私有 / 我的页面”分区可见、文档页标题输入框与 BlockNote 编辑区正常渲染,然后实际修改标题与正文,等待 `/api/documents/title`、`/api/documents/save` 成功返回并出现“已保存”,最后刷新页面确认标题与正文仍保留,再调用 `/api/documents/purge` 清理临时页面。实跑结果通过,说明本轮协议层切换后文档页主交互未退化。
|
|||
|
|
|
|||
|
|
### C2 Sidebar 聚合
|
|||
|
|
|
|||
|
|
- [x] 盘点 Sidebar 真实数据来源,锁定 `sidebar.tsx`、`private-tree.tsx`、`file-tree.tsx`、`use-convex-sidebar-data.ts`、`sidebar-tree.ts`。
|
|||
|
|
- [x] 先把 Sidebar 的查询聚合逻辑抽象成 Rust query 目标,避免继续在前端和 API 中重复拼树。
|
|||
|
|
- [x] 为 Sidebar 建立最小查询契约,至少覆盖页面列表、层级关系、文件树行模型和展开状态所需字段。
|
|||
|
|
- [x] 保留现有 Sidebar UI 和交互,不引入第二套导航壳,也不从 `mnote-rust` 复制 `sidebar.tsx` 覆盖现实现。
|
|||
|
|
- [x] 把 Mindmap、表格、媒体等派生资源的聚合边界整理成后续 Rust query 可接入的明确目标。
|
|||
|
|
|
|||
|
|
2026-04-14 盘点补记:当前主入口已确认位于 `wolai-frontend/src/components/sidebar/sidebar.tsx`,私有树/文件树分别位于 `components/sidebar/private-tree.tsx` 与 `components/sidebar/file-tree.tsx`;数据侧同时存在 `/api/sidebar` 聚合 route、`hooks/use-convex-sidebar-data.ts` 实时订阅组装,以及 `lib/sidebar-tree.ts` 的树/section 构建逻辑,说明 C2 的真实起点是“API 聚合 + 前端二次拼装”的双层结构。
|
|||
|
|
2026-04-14 契约补记:当前最小 Rust query 目标已明确为兼容 `SidebarInitialData` 的单查询返回,至少覆盖 `active_workspace_id`、`workspaces`、`documents`、`trashed_documents`、`media_assets`、`trashed_media_assets`、`mindmap_assets`、`trashed_mindmap_assets`、`table_assets`、`trashed_table_assets`、`mindmap_docs`、`mindmap_asset_children`,从而先替换聚合来源而不改 `buildDocumentTree/buildVisibleRows` 的前端渲染逻辑。
|
|||
|
|
2026-04-14 边界补记:当前已明确必须保持不变的 UI/交互包括 `starred/public/shared/private/templates` 分区语义、`sort_order -> created_at` 排序口径、`doc/index.md/asset-folder/asset` 文件树行语义、拖拽/剪贴板协议,以及回收站双 tab 与资源计数行为;Mindmap、表格、媒体三类派生资源的聚合边界已被明确列为 Rust query 后续接入目标。
|
|||
|
|
2026-04-14 C2 第一刀收口补记:已新增 `wolai-frontend/src/lib/sidebar-data.ts` 与 `wolai-frontend/src/lib/server/sidebar-data.ts`,把 `src/app/(app)/layout.tsx`、`src/app/api/sidebar/route.ts`、`src/hooks/use-convex-sidebar-data.ts` 之间重复的 `SidebarInitialData` 组装统一收口到共享 helper;同时修复 hook 链路中 `mindmapAssetChildren` 长期为空的漂移,补充 `src/lib/sidebar-data.test.ts`,并通过 `pnpm test src/lib/sidebar-data.test.ts src/lib/file-tree/rows.test.ts` 与定向 `eslint` 验证。基于本轮复核,当前已可确认“多个前端位置不再重复拼装同一棵树”这一验收点达成;但由于 SidebarInitialData 仍未冻结为明确 Rust query contract,`C2` 其余验收项暂不提前勾选。
|
|||
|
|
2026-04-14 C2 第二刀补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/sidebar-rust-query-target.md`,把 `sidebar.dataset.list` 的最小 payload/result、Rust query 与前端投影职责边界、以及“不复制第二套导航壳/不直接输出前端渲染树”的约束固定成文档。当前可确认 Sidebar 查询聚合目标已经从“散落在 route 和 hook 中的实现细节”收口为明确的 Rust query 接入目标。
|
|||
|
|
|
|||
|
|
C2 验收:
|
|||
|
|
|
|||
|
|
- [x] Sidebar 至少一条主查询已经改由 Rust query 供给。
|
|||
|
|
- [x] 文档树、文件树、回收站等视图语义保持一致。
|
|||
|
|
- [x] 不再需要在多个前端位置重复拼装同一棵树。
|
|||
|
|
|
|||
|
|
2026-04-14 C2 第三刀补记:已新增 `wolai-frontend/convex/sidebar.ts`,把页面列表、回收站、Mindmap、媒体、表格等数据集收口成单个 `sidebar.datasetList` 主查询;`src/lib/server/sidebar-data.ts` 与 `src/hooks/use-convex-sidebar-data.ts` 均已切换为消费这条单查询返回,再通过既有 `SidebarInitialData` 投影层驱动 UI。配合 `src/lib/sidebar-data.test.ts` 的契约冻结、`src/lib/file-tree/rows.test.ts` 的文件树行语义验证,以及定向 `eslint`,当前可确认文档树、文件树、回收站双 tab 依旧沿用原有前端投影逻辑,没有因数据源切换而改变语义。
|
|||
|
|
2026-04-15 C2 第四刀补记:`/api/sidebar` 现已从“先直跑 Convex helper,再额外挂 meta”推进为真实 Rust query transport。当前 route 会先执行 `buildDocumentQueryEnvelope(name=\"sidebar.dataset.list\") -> resolveRustBridgeQueryPlan -> executeRustBridgeQueryTransport`,再把 `sidebar:datasetList` 的结果投影回 `SidebarInitialData`;这意味着 Sidebar API 主链已经真正进入 Rust runtime/bridge,而不再只是挂一个 envelope 名字。
|
|||
|
|
|
|||
|
|
### C3 BlockNote 正文保存
|
|||
|
|
|
|||
|
|
- [x] 盘点正文保存链路,锁定 `blocknote-editor.tsx`、`schema.ts`、文档保存 API 当前入口。
|
|||
|
|
- [x] 先把正文保存切成“前端快照采集”和“Rust command 提交”两个边界。
|
|||
|
|
- [x] 为正文保存定义最小协议对象,至少包含 `page_id`、`workspace_id`、`revision`、`actor`、`source`、block 快照、冲突检测字段。
|
|||
|
|
- [x] 先接入低风险保存模式,例如显式保存或节流保存,不先处理复杂协同细节。
|
|||
|
|
- [x] 确保正文链与页面元信息链、Sidebar 链共用同一 identity 口径,不再出现多套 page id 映射。
|
|||
|
|
|
|||
|
|
C3 验收:
|
|||
|
|
|
|||
|
|
- [x] 正文保存至少一条正式链路已经通过 Rust command 回写 Convex。
|
|||
|
|
- [x] 保存失败时可返回稳定错误模型。
|
|||
|
|
- [x] 保存成功时可回查 command log、domain event 与 trace。
|
|||
|
|
|
|||
|
|
2026-04-14 C3 第一刀收口:已为 `documents.getContent` / `documents.save` 增加独立 `content_revision` 与 `content_conflict_key`,避免标题/统计信息更新污染正文 revision;`/api/documents/content` 现会透传 `revision/conflictDetectionKey`,`BlockNoteEditor` 会在自动保存时携带 `revision`、`conflictDetectionKey`、`snapshotCapturedAt`、`blockCount`,并在成功后刷新本地保存元数据。`save-command-adapter` 现把 Convex 冲突归一为 `409 REJECTED` bridge 错误,编辑器右上角也会展示保存失败信息。当前最小验证已补 `save-contract`/`bridge` 单测,并完成定向 eslint;结果为无 error,仅保留仓库既有 warnings。
|
|||
|
|
2026-04-14 C3 第二刀补记:源码复核确认 `BlockNoteEditor` 当前通过 `useDebouncedCallback(saveContent, 800)` 以防抖自动保存作为最小低风险保存模式,没有把复杂协同状态直接并入正文写链;同时 `documents.meta/title/stats/options/save` 这些 route 都把同一个 `normalizedDocumentId` 作为 `target.pageId`,`documents.content/save` payload 也统一使用 `documentId/workspaceId`,`sidebar.dataset.list` 则以同一 `workspace_id` 作用域返回 `documents[].id` 作为页面业务 id,因此当前正文链、页面元信息链与 Sidebar 聚合链已不存在第二套 page id 映射口径。
|
|||
|
|
2026-04-14 C3 第三刀补记:在此前真实 `/api/documents/save -> /api/bridge/request|trace` smoke 已确认可回查的基础上,本轮又补了 `src/lib/documents/bridge.test.ts` 的成功路径断言,明确 `executeSaveBridgeCommand` 在 revision/conflictDetectionKey 新协议下仍会调用 `recordBridgeCommandArtifacts`,并把同一 `requestId/traceId/commandId` 暴露给回查入口。因此当前“保存成功时可回查 command log、domain event 与 trace”已具备历史 HTTP smoke 与当前单测的双重闭环。
|
|||
|
|
2026-04-14 C3 第四刀补记:`save-command-adapter` 已进一步切到与页面元信息链一致的最小运行时接缝。当前 `documents.save` 会先构造 `functionName=documents:updateContent`、`payloadJson`、`args` 组成的 bridge mutation request,再由统一执行器实际调用 Convex;这让正文保存不再长期停留在“adapter 内直接手写 `client.mutation(...)`”的临时态,同时保留现有冲突归一和落账逻辑不变。
|
|||
|
|
2026-04-15 Phase 5 第一刀补记:`search.documents`、`search.recent` 已补齐到主仓 Rust query/runtime 主链。当前 `rust/crates/core-protocol` 新增 `SearchDocuments/SearchRecent`,`storage-convex-bridge` 与 `bridge-runtime` 已支持 query name -> Convex function 映射和运行时分发;`rust/crates/index-fts` 新增 `evaluate_search_documents`,负责标题/正文/思维导图/表格/附件的召回合并、排序、高亮 snippet 与 OCR 待补队列决策。`wolai-frontend/src/app/api/search/documents/route.ts` 现仅保留参数整理、原始数据装载与 HTTP 回传,不再持有 TS 侧的核心 ranking/snippet 逻辑;`/api/search/recent` 继续只承担最近访问写入 side-effect。
|
|||
|
|
|
|||
|
|
## 6. Phase D:Mindmap 与 OnlyOffice 边界接入
|
|||
|
|
|
|||
|
|
完成目标:
|
|||
|
|
|
|||
|
|
- 保留 `mnote` 当前成熟的 Mindmap 与 OnlyOffice 前端实现。
|
|||
|
|
- 把数据边界、对象边界和回调边界逐步纳入 Rust adapter / protocol 规划,而不是复制第二套对象页壳。
|
|||
|
|
|
|||
|
|
Checklist:
|
|||
|
|
|
|||
|
|
- [x] 锁定 Mindmap 当前主组件和嵌入链路,确认 `MindmapBlock.tsx` 同时服务 BlockNote 内嵌块与独立全屏页。
|
|||
|
|
- [x] 盘点 Mindmap 数据入口,锁定 `mindmapLocalStore.ts`、`mindmapOps.ts`、`app/api/mindmap/**`、`app/mindmap/**`。
|
|||
|
|
- [x] 把 Mindmap 的前端交互状态与本体数据/ops 边界拆开,后者逐步映射到 Rust 协议层。
|
|||
|
|
- [x] 明确 `mnote-rust/app/documents/[id]/mindmap/page.tsx` 等对象页壳不进入主仓主线。
|
|||
|
|
- [x] 为 Mindmap 设计最小 adapter 目标,至少覆盖节点树、节点引用、节点操作日志和与 page/block 的绑定关系。
|
|||
|
|
- [x] 锁定 OnlyOffice 当前页面和 API 边界,确认 `src/app/onlyoffice/`、`src/app/api/onlyoffice/**`、`src/components/onlyoffice/` 的职责分工。
|
|||
|
|
- [x] 保留根目录 `src/components/onlyoffice/` 的静态资源、插件和数据目录,不做误删、不做迁移式替换。
|
|||
|
|
- [x] 把 OnlyOffice 的对象解析、签名、callback、forcesave、代理请求边界整理成 Rust adapter 的明确目标。
|
|||
|
|
- [x] 继续保持“正文只嵌文件入口,OnlyOffice 在独立页面运行”的产品形态。
|
|||
|
|
- [x] 统一 Mindmap 与 OnlyOffice 的页面标识、附件标识、页面归属和追踪字段。
|
|||
|
|
|
|||
|
|
2026-04-14 Phase D 盘点补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/mindmap-onlyoffice-boundary.md`,固定 `MindmapBlock.tsx` 与独立全屏页共用同一核心组件、`mindmapLocalStore.ts`/`mindmapOps.ts`/`app/api/mindmap/**` 的数据与 ops 边界,以及 OnlyOffice 的 `page -> client -> sign/proxy/callback/forcesave` 职责分层。文档同时明确 `MediaBlock` 仅作为 Office 附件入口、`/onlyoffice` 继续作为独立编辑页面,且历史仓中的对象页壳与第二套 sidebar 只保留为参考实现。
|
|||
|
|
2026-04-14 Phase D 收口补记:已把 Mindmap API 与组件侧统一到与 OnlyOffice 对齐的业务标识口径。当前 Mindmap 统一使用 `pageId=documentId`、`attachmentId=mindmapId`、`workspaceId` 作为页面归属,并在 `/api/mindmap/**` 返回稳定的 `requestId/traceId` 元信息;OnlyOffice 继续使用 `documentId + assetId` 作为页面/附件标识,因此两条链后续接 Rust adapter 时不再需要第二套 page/attachment 映射。
|
|||
|
|
2026-04-14 Phase D 浏览器回归补记:已新增 `/mnt/Data1T/mnote/scripts/task021-mindmap-ui-regression.js` 并在真实本地实例 `http://127.0.0.1:3001` 上执行。脚本使用当前共享的 `MindmapBlockView` 全屏入口 `/mindmap/[docId]/[mindmapId]`,验证页面 `data-page-id/data-document-id/data-attachment-id/data-mindmap-id/data-workspace-id` 元信息、工具栏与“大纲”侧栏渲染、子节点新增与删除后的持久化、以及 `/api/mindmap/**` 返回的 `requestId/traceId` 会同步回 DOM。考虑到内嵌块与独立页共用同一核心组件,这轮浏览器回归可视为覆盖当前共享交互/保存内核,实跑未见退化。
|
|||
|
|
2026-04-15 Phase D OnlyOffice callback 收口补记:已为 `OnlyOffice callback` 新增最小命令 `media.assets.replace_storage`,同步补齐 `rust/crates/core-protocol` 的 `ReplaceMediaAssetStorage`、`rust/crates/storage-convex-bridge` 的 command name -> Convex mutation 映射,以及主仓 `buildDocumentBridgeMutationRequest` 的运行时接缝。`src/app/api/onlyoffice/callback/route.ts` 现保留下载文件、上传到 Convex Files 获得 `storageId` 的现有流程,但最终写回已改为经 `buildDocumentBridgeContextWithActor -> buildDocumentCommandEnvelope -> executeMediaAssetWritebackBridgeCommand` 进入统一 bridge 边界,再调用 `api.mediaAssets.replaceStorageFromUpload`。配套 `src/app/api/onlyoffice/callback/route.test.ts`、`src/lib/documents/bridge.test.ts`、Rust 单测与 `scripts/task022-onlyoffice-ui-regression.js` 已通过,确认 `storage_id` 在真实浏览器里继续发生变化。
|
|||
|
|
|
|||
|
|
Phase D 验收:
|
|||
|
|
|
|||
|
|
- [x] Mindmap 与 OnlyOffice 的前端界面仍以 `mnote` 当前实现为主,没有引入第二套主壳。
|
|||
|
|
- [x] Mindmap 的节点/操作边界与 OnlyOffice 的签名/callback/forcesave 边界都已进入统一规划。
|
|||
|
|
- [x] `src/components/onlyoffice/` 保持可用且未被误删。
|
|||
|
|
- [x] `adapter-onlyoffice`、`adapter-mindmap` 仍作为后置实现项,而不是本阶段强行复制进主线。
|
|||
|
|
|
|||
|
|
## 7. Phase E:历史收口与单仓执行统一
|
|||
|
|
|
|||
|
|
完成目标:
|
|||
|
|
|
|||
|
|
- `mnote-rust` 正式退出主产品角色。
|
|||
|
|
- `mnote` 主仓成为唯一启动、保存、规划和验证入口。
|
|||
|
|
|
|||
|
|
Checklist:
|
|||
|
|
|
|||
|
|
- [x] 统一团队口径:主产品仓只有 `/mnt/Data1T/mnote`,`/mnt/Data1T/mnote-rust` 只保留为历史参考和资产来源。
|
|||
|
|
- [x] 把所有新的设计、执行清单、架构说明优先写入 `/mnt/Data1T/mnote/design/` 与 `/mnt/Data1T/mnote/rust/design/`。
|
|||
|
|
- [x] 复查仓库脚本和说明文档,去掉“先进 `mnote-rust` 再启动”的旧叙事。
|
|||
|
|
- [x] 统一根目录脚本入口,让仓库级脚本只从 `/mnt/Data1T/mnote/scripts/` 发起,再按需调用 `cargo --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml ...`。
|
|||
|
|
- [x] 对仍需保留的 `mnote-rust` 资料按“核心规范 / 历史阶段 / 参考实现 / 错误方向”分类,避免后续误复制。
|
|||
|
|
- [x] 把已确认不应主线保留的对象页壳、diagnostics 页、smoke 页继续留在历史仓,不进入主仓实现。
|
|||
|
|
- [x] 对主仓内新增的 Rust 目录建立最小维护约定,明确谁负责 workspace、谁负责 bridge、谁负责接入链。
|
|||
|
|
- [x] 重新审查 `ARCHITECTURE.md`、`AGENTS.md`、`rust-kernel-backport-plan.md` 与本 checklist,保证四者口径一致。
|
|||
|
|
- [x] 固定“哪些目录默认不动”的硬边界,特别是 `wolai-frontend/`、`wolai-backend/`、`infra/convex/`、`src/components/onlyoffice/`。
|
|||
|
|
|
|||
|
|
Phase E 验收:
|
|||
|
|
|
|||
|
|
- [x] 后续协作默认只进入 `mnote` 主仓规划和开发。
|
|||
|
|
- [x] 主仓文档和脚本不再把 `mnote-rust` 叙述为主执行入口。
|
|||
|
|
- [x] 历史仓的保留范围、参考价值和禁止误复制范围都已固定下来。
|
|||
|
|
|
|||
|
|
2026-04-14 Phase E 收口补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-single-repo-maintenance-boundary.md`,统一记录主仓执行入口、历史仓资料分类、禁止误复制清单与 workspace/bridge/接入链责任面;同时已复查根 `package.json` 与 `scripts/desktop-hot.js`,确认仓库级脚本仍只从 `/mnt/Data1T/mnote/scripts/` 发起,且 `ARCHITECTURE.md` 已移除把 `mnote-rust` 写成未来执行承载面的表述。
|
|||
|
|
|
|||
|
|
## 8. 发布前总审计(跨阶段)
|
|||
|
|
|
|||
|
|
- [x] 为 `/mnt/Data1T/mnote/rust/` 补基础验证矩阵,至少覆盖 `cargo metadata`、`cargo check`、必要 crate 单测。
|
|||
|
|
- [x] 为 bridge 入口补集成 smoke,验证最小查询、最小写入、日志生成、事件生成和错误返回。
|
|||
|
|
- [x] 为文档页元信息、Sidebar、BlockNote 保存链补端到端回归,确认 UI 未因为协议层切换而退化。
|
|||
|
|
- [x] 为 Mindmap 补交互回归,重点验证内嵌块、独立页、数据保存、节点操作和工具栏/侧栏行为。
|
|||
|
|
- [x] 为 OnlyOffice 补回归,重点验证签名、代理、callback、forcesave、文档打开和静态资源可用性。
|
|||
|
|
- [x] 检查主仓启动路径,确保开发者只需进入 `/mnt/Data1T/mnote` 就能完成前端、后端、Rust、OnlyOffice 相关联调。
|
|||
|
|
- [x] 检查保存口径,确认页面、块、文档、索引的最终真相仍然落在 Convex,而不是被临时缓存目录劫持。
|
|||
|
|
- [x] 检查 `trace_id`、`request_id`、`workspace_id`、`page_id` 在前端、bridge、Convex、日志中的一致性。
|
|||
|
|
- [x] 对本次回迁引入的所有新目录和新文档做一次清点,确认没有误带入 `mnote-rust` 的历史噪音。
|
|||
|
|
- [x] 为统一观测面补正式 Rust 能力面,至少包含 `bridge_request_get`、`bridge_trace_get`、`bridge_command_get`、`event_replay`、`index_rebuild` 这组 query/job/tool,并确认 Web 回查入口不再私有直连。
|
|||
|
|
|
|||
|
|
2026-04-14 发布前审计补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-backport-audit-inventory.md`,清点主仓 `rust/` 已并入的 workspace/crates/设计文档、本轮新增的根 `design/` 文档,以及当前仍未并入主线的 `adapter-*`、`mnote-cli`、`bridge/scripts/fixtures/tests` 目录。文档同时核对了 `package.json`、`scripts/desktop-hot.js` 与 `AGENTS.md` 的主仓启动口径,确认开发者只需进入 `/mnt/Data1T/mnote` 即可找到前端、后端、Rust 与 OnlyOffice 的联调入口。
|
|||
|
|
- 2026-04-15 task-034 补记:已在 `rust/crates/core-protocol` 增补 `GetBridgeRequest/GetBridgeTrace/GetBridgeCommand` 以及 `bridge_request_get`、`bridge_trace_get`、`bridge_command_get`、`event_replay`、`index_rebuild` 五个统一观测/恢复工具;`rust/crates/storage-convex-bridge` 已补 query name -> Convex `bridgeLogs:*` 映射;`rust/crates/bridge-runtime` 已支持这组 query/job 的 plan/result 输出,并把 `index-fts::rebuild_from_events` 暴露为正式 `index_rebuild` 恢复入口。前端 `/api/bridge/request`、`/api/bridge/trace` 已切到 `buildDocumentQueryEnvelope -> resolveRustBridgeQueryPlan -> executeRustBridgeQueryTransport` 主链,同时支持按 `commandId` 过滤与统一排序返回;`src/lib/documents/bridge-log.ts` 也已把命令日志/领域事件状态显式化,为后续失败态、冲突态与补偿落账提供稳定边界。配套验证已通过全量 `cargo test --manifest-path rust/Cargo.toml` 与 bridge 定向 eslint。
|
|||
|
|
- 2026-04-15 OnlyOffice 升级与实跑补记:已把 `8082` 文档服务从旧仓 `mnote-rust/infra/onlyoffice/docker-compose.yml` 迁回当前主仓 `/mnt/Data1T/mnote/infra/onlyoffice/docker-compose.yml`,并升级到 `onlyoffice/documentserver:9.3.1`。同时修复了 `/onlyoffice/plugins/*` 被 middleware 重定向到 `/auth` 导致自定义插件桥无法 ready 的问题,为 `wolai-frontend/public/onlyoffice/plugins/agent-tools/` 补齐非可视插件配置与 `plugins.js` 加载。最终 `scripts/task022-onlyoffice-ui-regression.js` 已在真实浏览器中通过,覆盖文档打开、`oo_insert_text` 插件调用、`同步保存`、callback 写回以及 `storage_id` 刷新变化闭环。
|
|||
|
|
- 2026-04-15 OnlyOffice callback bridge 补记:本轮在复跑 `scripts/task022-onlyoffice-ui-regression.js` 前,曾因 `/auth` 快速登录触发 `POST /api/auth -> Could not find public function for 'auth:signIn'` 导致浏览器脚本卡在登录页;已通过 `cd /mnt/Data1T/mnote/wolai-frontend && pnpm exec convex dev --once --tail-logs disable --env-file ../.env.all --run ping:ping` 重新注册 Convex functions 后恢复。恢复后同一浏览器脚本再次通过,确认新接入的 `media.assets.replace_storage` bridge 命令没有破坏 OnlyOffice 打开、插件桥、forcesave、callback 与 `storage_id` 更新闭环。
|
|||
|
|
- 2026-04-14 浏览器实跑补记:`task-019-document-ui-regression.js` 已在真实浏览器中覆盖“首页进入文档页 -> Sidebar 可见 -> 修改标题 -> 修改 BlockNote 正文 -> 等待保存成功 -> 刷新后仍保留”的最小闭环。运行前曾因本地 Convex 实例缺少 `workspaces:ensureDefaultWorkspace` 导致首页 `500`,本轮已通过 `pnpm exec convex dev --once --tail-logs disable --env-file ../.env.all --run ping:ping` 重新注册函数后恢复;最终浏览器脚本通过,且临时页面已清理。
|
|||
|
|
- [x] 对以下禁止事项做最终复查:不双仓并行、不跨仓链接、不复制第二套产品前端壳、不把对象页壳/diagnostics/smoke 页带入主线、不散落多个 Rust 源码根。
|
|||
|
|
- [x] 产出最终 cutover 文档,按能力域列清哪些 route 已仅剩 transport,哪些旧 TS 执行面必须继续迁移或后续删除。
|
|||
|
|
- [ ] 以“单仓路径可启动、可保存、可验证、可继续演进”作为发布前收口标准。
|
|||
|
|
|
|||
|
|
2026-04-14 实跑记录:已重新执行 `cargo metadata --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml --format-version 1`、`cargo check --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml`、`cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p core-domain`、`cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p core-protocol`、`cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p storage-convex-bridge`,均通过;其中 `cargo metadata` 已再次确认 workspace members 固定为 `core-domain`、`core-protocol`、`event-log`、`storage-convex-bridge`、`index-fts` 五个 crate。
|
|||
|
|
2026-04-14 源码审计补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/release-readiness-source-audit.md`。该文档基于当前 route、adapter、Convex bridgeLogs 与定向测试,确认 bridge 入口已经覆盖最小查询/写入/日志/事件/错误返回闭环;确认正文、页面元信息、块补丁与 OnlyOffice 附件写回的最终真相仍然落在 Convex mutation;确认 `trace_id`、`request_id`、`workspace_id`、`page_id` 在 route、bridge、Convex 日志与回查入口之间使用统一口径;并完成“不双仓并行、不跨仓链接、不复制第二套前端壳、不把 diagnostics/smoke 页带入主线、不散落多个 Rust 源码根”的源码级复查。
|
|||
|
|
2026-04-15 task-035 补记:已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md`,把主仓当前 TS 执行面按 `RUST_OWNER / TS_TRANSPORT_KEEP / TS_COMPAT_PENDING / TS_LEGACY_DELETE` 四类状态完成盘点。文档明确了页面、块、查询聚合、AI、Mindmap、OnlyOffice 的当前归属,也明确了 `documents/create-child`、`documents/embed`、`documents/empty-trash`、`documents/purge`、`documents/template`、`mindmap-trash/empty`、`mindmap-ai/**` 与 `ai-agent` 非 Rust 核心工具面属于 Phase 8 前必须继续处理的旧面;同时为“何时允许宣布 Rust 成为唯一业务执行平面”补齐了四组 gate。
|
|||
|
|
2026-04-15 task-040/task-042/task-043/task-044 补记:AI 非 `doc_*` 核心工具中的 `search_web`、`image_read`、`slash_run` 已完成第一批 Rust Tool runtime cutover,`ai-agent/run` 不再保留这些工具的 TS 真执行兜底;`bridge-log/runtime` 已补齐统一失败态、冲突态与补偿态的第一批状态闭环,并覆盖页面主写链与 AI/Mindmap 写链;同时已新增 `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-legacy-delete-list.md`,把 `documents/create-child`、`documents/embed`、`documents/empty-trash`、`documents/purge`、`documents/template`、`mindmap-trash/empty`、`builtins/**` 固定为第一批 `TS_LEGACY_DELETE`。至此 Phase 8 的文档口径已经允许在源码审计层面使用“Rust 已成为 mnote 的唯一业务执行平面;Web route 只保留 transport、auth、session、streaming、proxy 与 callback 壳”这句统一结论。
|