← [ BACK_TO_NOTES ]

MemoFlow · Goal 数据同步开发笔记

按版本记录 Goal Store 初始化、聚合刷新、同步通知和 Mutation Receipt。

#blog #growing #dev

Goal 数据同步目标

Goal 页面需要快速展示已有目标,也要在新增 KR、Record 或修改目标后立即显示正确数据。我希望尽量复用已加载的 Store,不必每次切换页面都重新请求全部数据。

但 Store 本身不能取代业务数据真值,需要明确谁负责持久化,谁负责让页面更新。

V1.0.0

现在使用 Store Persistence 插件保存一部分客户端状态,但初始化时发现持久化后的数据不完整。

第一步先检查:哪些字段确实经过序列化、初始化先后顺序是否正确、服务端返回数据与 Store 缓存有没有被混用。不能只因为启用了 Persistence 插件,就认为嵌套实体和全部引用关系都一定能正确恢复。

页面希望优先使用已经载入的数据,同时在初始化时补齐缺失部分。缓存只是为了提升体验,不能成为权威业务状态。

v1.1.0

另一个问题是子实体变化:修改了 KeyResult 或 GoalRecord,父级 Goal 聚合和其他页面不一定马上显示新进度。

当前可以先在成功保存后重新获取整个 Goal,再更新 Store,保证页面能看到服务端返回的最新值。这个办法简单,但每次改动都要重新加载较大的聚合,多个组件也可能反复刷新。

因此想继续把“哪次业务操作成功”与“哪几个视图应该刷新”分开。

V2.0.0

这版考虑用领域事件或应用层通知协调刷新:KR、Record 修改成功后,发出含 Goal ID 的变更消息,由 Sync Service 或 Store 订阅者更新相关视图。

优点是不会让每个组件各自猜测需要刷新哪里;但不能只靠一个内存事件就认为数据一定一致。事件丢失、重复消费、页面迟到订阅或请求乱序,都可能让客户端留下旧值。

事件负责“某个对象发生变化”的信号,持久化结果仍需要由真正拥有 Goal 数据的应用服务返回。

V3.0.0

现在把 Goal 的写入统一交给拥有 Goal/KR/Record/Review 的聚合边界。修改已有对象时携带 expectedVersion,服务端发现冲突就返回明确结果,不能静默覆盖。

成功变更返回权威的 GoalMutationReceipt,包含可以用于合并或失效缓存的信息。客户端按 Goal/KR/Record 的身份更新,而不是依赖旧对象引用碰巧触发 Vue 响应。

跨模块的 Task→Goal 贡献也一样:Task 只提交带来源和幂等身份的贡献意图,由 Goal 结算并生成 Record。这样刷新页面之前,首先能够确认真正成功提交的是哪一次业务变更。

这一版的重点从“强制刷新 Store”转到了用有版本的写入结果维护缓存与业务真值的一致性。

创建于 2026/3/5 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本