60 lines
1.7 KiB
Markdown
60 lines
1.7 KiB
Markdown
# 5-23 [done][bug] editorDocument 缺少 blocks 或 root 引用损坏仍被当作合法真源 v1
|
||||
|
|
|
|||
|
|
> 发现时间:2026-05-18
|
|||
|
|
>
|
|||
|
|
> 状态:`[done]`
|
|||
|
|
>
|
|||
|
|
> 关联主线:`05-editor-mainline`
|
|||
|
|
|
|||
|
|
## 1. 问题定义
|
|||
|
|
|
|||
|
|
`EditorBlockDocument` 的 serde 结构对 `blocks/rootBlockIds` 使用默认值。旧实现只检查 JSON 是否能反序列化,导致这类输入被接受:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{"documentId":"doc_1"}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{"documentId":"doc_1","rootBlockIds":["missing"],"blocks":[]}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
它们会优先于 legacy content 被当作原生块文档真相,可能把页面保存为空,或让 `body.content` 与 `body.blockDocument` 分裂。
|
|||
|
|
|
|||
|
|
## 2. 根因
|
|||
|
|
|
|||
|
|
`normalize_save_editor_document` 与 `page_aggregate_block_document_projection` 只做 serde 形状解析,没有做原始字段存在性和 root 引用完整性校验。
|
|||
|
|
|
|||
|
|
## 3. 修复
|
|||
|
|
|
|||
|
|
- 新增 `validate_editor_document_structure`。
|
|||
|
|
- 显式 `editorDocument` 必须带 `blocks` 数组。
|
|||
|
|
- `rootBlockIds` 中的非空 id 必须能在 `blocks` 中找到。
|
|||
|
|
- 保存链和 Page Aggregate 读链共用同一校验。
|
|||
|
|
|
|||
|
|
## 4. 验证
|
|||
|
|
|
|||
|
|
RED:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime rejects_editor_document -- --nocapture
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
旧实现中以下两个新增测试失败:
|
|||
|
|
|
|||
|
|
- `documents_save_command_plan_rejects_editor_document_missing_blocks`
|
|||
|
|
- `page_aggregate_get_rejects_editor_document_root_ids_missing_blocks`
|
|||
|
|
|
|||
|
|
GREEN:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime rejects_editor_document -- --nocapture
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
结果:`2 passed`。
|
|||
|
|
|
|||
|
|
## 5. 剩余边界
|
|||
|
|
|
|||
|
|
当前校验保证 `editorDocument` 不会因 serde default 被误判为合法真源;更深的 schema 版本、块类型特定必填字段仍应在 EditorBlockDocument 原生落库迁移中继续收紧。
|