9.8 KiB
9.8 KiB
[recycle] 发布前源代码审计
更新时间:2026-04-16
审计范围:
/mnt/Data1T/mnote
1. Bridge 入口与日志回查
1.1 最小查询与写入入口
当前已确认的 bridge 主线入口:
- 查询:
src/app/api/documents/content/route.tssrc/app/api/documents/meta/route.tssrc/app/api/sidebar/route.ts
- 写入:
src/app/api/documents/title/route.tssrc/app/api/documents/stats/route.tssrc/app/api/documents/options/route.tssrc/app/api/documents/save/route.tssrc/app/api/blocks/patch/route.tssrc/app/api/onlyoffice/callback/route.ts
1.2 日志与事件落账
当前已确认:
src/lib/documents/metadata-command-adapter.ts成功路径会调用recordBridgeCommandArtifactssrc/lib/documents/save-command-adapter.ts成功路径会调用recordBridgeCommandArtifactssrc/app/api/blocks/patch/route.ts成功路径会调用recordBridgeCommandArtifactssrc/lib/documents/media-asset-command-adapter.ts会在 ONLYOFFICE callback 成功写回后尝试复用同一 bridge log 落账src/lib/documents/bridge-log.ts会同时写入:bridgeLogs.recordCommandLogbridgeLogs.recordDomainEvent
- 回查入口:
src/app/api/bridge/request/route.ts -> bridgeLogs.listByRequestsrc/app/api/bridge/trace/route.ts -> bridgeLogs.listByTrace
结论:
- bridge 的最小查询、最小写入、日志生成、事件生成和错误返回已经形成源码闭环。
2. 保存口径审计
当前正文与页面元信息主写链如下:
documents.save -> api.documents.updateContentdocuments.title.update -> api.documents.updateTitledocuments.stats.update -> api.documents.updateStatsdocuments.options.update -> api.documents.updateOptionsblocks.patch -> 读取文档内容后回写 api.documents.updateContent
OnlyOffice 写回:
src/app/api/onlyoffice/callback/route.ts -> media.assets.replace_storage -> api.mediaAssets.replaceStorageFromUpload
结论:
- 页面正文、页面元信息、块补丁与 OnlyOffice 附件写回最终都以 Convex mutation 为主事实写入点。
- 当前未发现把页面/块主真相改写到
mnote-rust、本地缓存目录或其他派生目录的主写链。
3. trace_id / request_id / workspace_id / page_id 一致性
3.1 前端与 route
buildDocumentBridgeContext()统一生成requestId、traceId、workspaceIdbuildDocumentBridgeContextWithActor()可为 ONLYOFFICE callback 这类无用户 cookie 的服务端回调显式注入actor/sourcebuildDocumentCommandEnvelope()统一挂载commandId、target.pageIddocuments.title/stats/options/save均将normalizedDocumentId作为target.pageIdonlyoffice/callback会把asset.document_id作为target.pageId,并透传workspaceId
3.2 日志落账
recordBridgeCommandArtifacts()使用同一context.requestId、context.traceIdworkspaceId统一取target.workspaceId或context.workspaceIdtargetPageId统一落到 command log- domain event payload 同时记录
request_id、trace_id、command_id、command_name
3.3 当前辅助验证
src/lib/documents/bridge.test.ts已覆盖:target.pageId = doc_1executeSaveBridgeCommand成功路径会调用recordBridgeCommandArtifacts- 返回结果保留
req_1、trace_1
src/app/api/onlyoffice/callback/route.test.ts已覆盖:- callback 成功路径会调用
executeMediaAssetWritebackBridgeCommand storageId、assetId、documentId、workspaceId会进入media.assets.replace_storageenvelope
- callback 成功路径会调用
结论:
trace_id、request_id、workspace_id、page_id在 route、adapter、bridge log、回查入口之间已有统一口径。
4. 禁止事项复查
4.1 不双仓并行
- 主仓脚本与文档已统一指向
/mnt/Data1T/mnote wolai-frontend/src、wolai-frontend/convex、rust/下未发现直接依赖/mnt/Data1T/mnote-rust的运行时代码路径
4.2 不跨仓链接
- 排除
node_modules、.next、.venv、rust/target等构建产物后,主仓源码范围内未发现跨仓符号链接
4.3 不复制第二套产品前端壳
- 主仓保留的是既有
wolai-frontend主壳 - 历史仓对象页壳与第二套 sidebar 仅在文档中被标记为禁止误复制范围
4.4 不把对象页壳 / diagnostics / smoke 页带入主线
- 当前主仓
wolai-frontend/src/app下未发现新增的diagnostic/smoke页面目录 - 历史仓相关页面已在边界文档中明确列入禁止误复制清单
4.5 不散落多个 Rust 源码根
- 主仓顶层
Cargo.toml仅存在rust/Cargo.toml - 其余 crate
Cargo.toml均位于rust/crates/*
5. 运行态复核结果与最终结论
本审计只能关闭源码可验证项,但截至 2026-04-16,发布前运行态复核已经补齐五条直接证据:
- 已复跑
scripts/task019-document-ui-regression.js,文档页标题、正文、保存、刷新、回查链通过。 - 已复跑
scripts/task021-mindmap-ui-regression.js,Mindmap 全屏页的新增子节点、删除子节点、保存链、刷新回查与requestId/traceId元信息同步通过。 - 已复跑
scripts/task022-onlyoffice-ui-regression.js,ONLYOFFICE9.3.1基线下的打开、插件桥、callback 写回、forcesave 与storage_id变化通过。 - 已通过
pnpm exec vitest run src/lib/ai-agent/runtime/runAgent.test.ts,补齐docs_search -> docs_read的 AI runtime 调用证据。 - 已通过
bash /mnt/Data1T/mnote/rust/scripts/task049-cli-smoke.sh,补齐 CLI 主链的最小真实执行验收。
当前已不再存在阻塞发布的 CLI / AI 运行态尾项。
补充核验结果:
cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p mnote-cli -p bridge-runtime已通过。wolai-frontend相关定向eslint当前无 error,仅剩仓库既有 warnings,不构成本轮发布阻塞。
仍然要求环境满足的前置条件:
- 浏览器回归环境可访问
http://127.0.0.1:3000 MNOTE_ONLYOFFICE_PROBE_DOCX=/tmp/mnote-onlyoffice-probe/probe.docx可用- 已登录态可通过
/auth或测试账号快速登录建立
6. 旧 TS 执行面割接清单
当前源码审计之外,还需要看“哪些 TS route 还能留,哪些只是历史兼容”。
本轮已新增:
/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md
该文档已把主仓当前执行面明确分成四类:
RUST_OWNERTS_TRANSPORT_KEEPTS_COMPAT_PENDINGTS_LEGACY_DELETE
其中当前仍需要长期观察但不再构成主链阻塞的旧面主要包括:
src/app/api/documents/embed/route.tssrc/app/api/mindmap-ai/**
其中页面旧面在 2026-04-16 的最终口径如下:
src/app/api/documents/create-child/route.ts已改走documents.createsrc/app/api/documents/empty-trash/route.ts已改走documents.emptyTrashByWorkspacesrc/app/api/documents/purge/route.ts已改走documents.purgesrc/app/api/documents/template/route.ts已改走documents.templatesrc/app/api/documents/embed/route.ts已改走documents.save,但目标页面插入位与pageReferenceblock 组装仍在 TS,因此继续按TS_COMPAT_PENDING/ 产品编排壳维护src/app/api/mindmap/[docId]/route.ts与src/app/api/mindmap/[docId]/[mindmapId]/route.ts的DELETE/PATCH已改走mindmaps.delete/restore/purgesrc/app/api/mindmap-trash/empty/route.ts已改走mindmaps.emptyTrashByWorkspacesrc/app/api/blocks/*现网主链实际统一走src/lib/blocks/block-command-adapter.ts;src/lib/documents/block-command-adapter.ts应视为遗留兼容 helper,而非现网主执行面src/app/api/ai-agent/run/route.ts的核心工具主链现在已经统一走 Rust tool runtime:docs_search、docs_read、search_web、image_read、slash_run不再保留 TS 真执行兜底
结论:
- 当前可以说“Rust 已成为 mnote 的主业务执行平面”。
- 仍保留的 TS 路径只剩
TS_TRANSPORT_KEEP、少量TS_COMPAT_PENDING产品编排壳与冻结的TS_LEGACY_DELETE清单。 - 第一批
TS_LEGACY_DELETE已不再阻塞这轮 release readiness;它们现在的要求是“保持纯壳 / 冻结 helper,不允许反向长出新的业务规则”。
最终 release readiness 口径:
- 若按源码审计口径:可以说明“Rust 已成为 mnote 的唯一业务执行平面”,同时明确仍保留
TS_TRANSPORT_KEEP与少量产品编排壳。 - 若按完整发布口径:文档页、Mindmap、OnlyOffice、AI runtime、CLI smoke 的 Phase 8 scoped gate 已闭合,可以给出最终完成结论。
- 后续维护口径:剩余
TS_TRANSPORT_KEEP/TS_LEGACY_DELETE只属于长期清理与边界维护,不再构成第二套业务执行平面。
补记:
- 2026-04-15 已复跑
scripts/task019-document-ui-regression.js,确认文档页标题、正文、保存与刷新回查通过。 - 2026-04-15 已复跑
scripts/task021-mindmap-ui-regression.js,确认新增/删除节点、保存链、刷新回查与requestId/traceId元信息同步通过。 - 2026-04-15 已复跑
scripts/task022-onlyoffice-ui-regression.js,在升级后的 ONLYOFFICE9.3.1基线上确认oo_insert_text插件桥、同步保存、callback 写回与storage_id变化仍然通过;本次 callback 最终写回已不再由 route 直接调用api.mediaAssets.replaceStorageFromUpload,而是先经media.assets.replace_storagebridge 命令再落到 Convex。 - 2026-04-16 已通过
src/lib/ai-agent/runtime/runAgent.test.ts,确认docs_search -> docs_read的运行态工具链顺序、事件流与结果归一化闭合。 - 2026-04-16 已通过
rust/scripts/task049-cli-smoke.sh,确认sidebar/page/block/search/tool/mindmap主链 CLI 真实执行闭合。