Files
mnote/bugs/05-editor-mainline/done/5-24-page-body-save-preserves-uploaded-image-and-attachment-v1.md
T
lix-2026 cdff672aa5 feat: align local-first workspace direction
Document the VSCode-like local-first product shape, demote Convex to a control-plane role, and retire stale architecture drafts.

Add local workspace migration/export references plus smoke coverage for no-Convex managed workspace startup, local markdown title/body/options persistence, asset upload behavior, and Convex fixture export.

Verification: git diff --cached --check; node scripts/check-local-first-convex-guard.js --staged; node scripts/task444-convex-workspace-export-local-fixture-smoke.js; node scripts/task166-local-first-managed-workspace-no-convex-smoke.js; node scripts/task167-local-markdown-title-body-options-no-convex-smoke.js
2026-05-19 08:11:58 +08:00

61 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 5-24 [done][bug] page.body.save 上传图片与附件持久化字段丢失 v1
> 发现时间:2026-05-18
>
> 状态:`[done]`
>
> 关联主线:`05-editor-mainline`
## 1. 问题定义
主编辑区文本保存修复后,继续验证上传图片与附件发现两个持久化缺陷:
- 附件能插入到编辑器,并且 `/api/documents/save` 返回 200,但 `/api/documents/content` 回读时链接 mark 被降级成纯文本。
- 图片能上传并触发保存,但 `/api/documents/content` 回读时图片块只剩 `type: "image"``props.src / alt / title / tiptapImage` 为空。
这会导致刷新或跨浏览器打开后,附件不能作为 OnlyOffice 附件链接恢复,图片也缺少可渲染的资源地址。
## 2. 根因
保存链优先使用 `editorDocument` 生成 canonical legacy content 后再写入当前 Convex legacy substrate。
两个字段在这一步丢失:
- `legacy_content_from_editor_document` 只用 `legacy_text_from_editor_block()` 生成纯文本,未保留 `ContentNode.attrs.styles.link`
- `EditorBlockDocument` 反序列化时 `BlockProps.extra` 不是 flatten 字段,前端传来的 image `props.src / alt / title / tiptapImage` 会被 serde 忽略;`hydrate_editor_document_props_from_raw` 旧实现只回填 mindmap props,没有回填 image props。
## 3. 修复
- `legacy_content_from_editor_document` 对带结构化样式的 inline 节点输出 legacy inline content 数组,保留 `styles.link` 等样式;普通纯文本段落仍保持旧的字符串 content。
- `hydrate_editor_document_props_from_raw` 增加 image 分支,从原始 `editorDocument.blocks[].props` 回填 `src / alt / title / tiptapImage`
- `legacy_props_from_editor_block` 对 image 块输出回填后的直接 props 与 `tiptapImage`
## 4. 验证
单测:
```bash
cargo fmt --manifest-path rust/Cargo.toml --all --check
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime legacy_content_from_editor_document_preserves_inline_link_styles -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime documents_save_hydrates_image_props_from_raw_editor_document -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime documents_save_command_plan_prefers_valid_editor_document_over_other_sources -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web documents_save_route_executes_page_body_save_command -- --nocapture
```
浏览器验证:
- 以测试账号登录 `http://127.0.0.1:13000`
- 新建临时页面。
- 通过 slash 上传 `.docx` 附件和 `.png` 图片。
- 断言两次 `/api/documents/save` 均返回 200。
- 断言 `/api/documents/content` 回读包含:
- image `props.src`
- 附件 inline `styles.link`
- 刷新页面后,编辑器 DOM 中仍能找到附件链接与图片节点。
结果:通过;临时测试页面已 purge。
## 5. 剩余边界
当前仍是 legacy content substrate 下的过渡修复。完整 EditorBlockDocument 原生落库完成后,图片/附件 props 应由原生 schema 和迁移校验继续收紧。