产品设计

Notion:改错文档之后,怎样找回真正需要的内容

Notion 把文档、任务和资料放在同一个工作空间。它的版本历史帮助协作者查看旧内容、辨认修改,并取回需要的部分。

先尝试拆解问题、设计和实现,再展开思路,检查状态、边界与取舍,并设计验证用例。思路提供分析路径,不给出完整实现。

01
代码思考进阶

预览之后有人编辑了,怎样避免恢复覆盖新内容

场景:为自己的文档服务设计恢复接口。每份文档有递增版本号。一次恢复必须作为一个完整操作完成,不能只改一半。

  1. 输入与约定:客户端提交文档 ID、目标历史版本、预览时的当前版本号和操作 ID。操作 ID 用于识别同一次提交的重试。所有请求都需校验当前权限。
  2. 推演例子:用户在版本 12 上预览恢复到版本 8;提交前,同事写入了版本 13。请说明此时的响应,以及界面下一步应做什么。
  3. 异常情况:服务端已完成恢复,但响应在网络中丢失;客户端用相同操作 ID 重试。另一个请求错误地复用该 ID,却携带不同目标版本。
  4. 请交付:状态变化图、原子提交的边界、操作 ID 的保存策略,以及成功、冲突、重复请求和权限变化的测试表。只写思路,不写完整实现;JS 或 Rust 均可用于讨论数据结构。
查看思路
  1. 先检查当前权限,再辨认是否已经执行过。 已完成的同一操作,核对请求关键字段后返回原记录结果;相同 ID 却携带不同目标版本应拒绝。只有新操作才进入当前版本检查,不能让成功重试因为版本已变化而误报冲突。
  2. 把版本检查、写入和操作记录一起提交。 新操作发现当前版本从预览时的 12 变成 13,就保留现状并返回冲突。客户端重新取得差异,不得默默覆盖。操作 ID、请求摘要和结果需与写入处于同一次原子操作中。
  3. 恢复生成新的版本。 历史版本 8 提供内容,版本号继续递增。如果恢复把 12 变成 13,同事随后又写入 14,原操作的重试只返回当时的恢复结果,不再写入,也不能说 13 仍是当前版本。
  4. 区分明确失败与结果未知。 超时后先按操作 ID 查询或重试,不能直接认定服务端未执行。约定操作记录保存多久;过期后无法保证无限期去重。
  5. 用交错时序验证。 覆盖预览后他人修改、写入后断网、两次并发重试、相同 ID 不同请求和权限撤销。逐步列出当前版本和操作记录,确认每一步没有重复写入、泄漏内容或覆盖新编辑。