fix(objectql): 运行时注册的汇总字段不该等重启才会算 - #4427
Merged
Merged
Conversation
…t to compute The engine's roll-up summary index had exactly one invalidation site — `engine.registerApp` — and the runtime publish path does not go through it: it registers straight into the registry (`protocol.saveMetaItem` → `registry.registerObject`). So a kernel that had already performed a single write — publishing itself writes `sys_metadata` rows — held a summary index built before the new object existed. Every child write of a freshly published roll-up then found no descriptor and silently skipped the recompute, and the parent field read null until the process restarted. That is how an AI-built app's "已完成任务数" shipped permanently empty over completely correct metadata: the roll-up was configured, the child rows were seeded with resolved foreign keys, and nothing recomputed (cloud#970). `SchemaRegistry` now carries a monotonic `objectRevision`, bumped on every change to the registered object set (register, invalidate, unregister, reset), and the engine rebuilds its index whenever that number has moved — so a registry-derived cache can no longer go stale through a path that forgot to call the invalidator. `invalidateSummaryIndex` stays as a belt-and-braces hook. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
xuyushun441-sys
pushed a commit
that referenced
this pull request
Aug 1, 2026
…ll-up fix #4427 made the summary index follow `registry.objectRevision` and pinned the headline path: an object registered after the index was already built. The same counter is responsible for three neighbouring behaviours it does not exercise, and each was independently broken before that fix: - re-registering an EXISTING object with a new summary field (the `update_metadata` incremental-authoring path — the object is already live, so this replaces a contributor rather than adding an object) - unregistering the parent, after which its roll-up must STOP being recomputed (the mirror of the bug: a stale index keeps writing to a parent that is gone) - the child's own insert already being correct, rather than a later write quietly repairing it — the property that made the original defect so slippery, since the no-op PATCH workaround always produced right answers Verified they earn their place: reverting #4427's `getSummaryDescriptors` change fails all three (roll-up `undefined`), alongside its own case. objectql 1504 tests pass; tsc clean. Test-only change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
引擎的 roll-up summary 索引只有一个失效点 ——
engine.registerApp。而运行时发布路径根本不走它:它直接往 registry 里注册(protocol.saveMetaItem→registry.registerObject)。于是:任何已经写过一次数据的 kernel(发布动作自己就会往
sys_metadata写行)都握着一份在新对象出现之前构建的索引。此后每一次子记录写入都查不到 descriptor,静默跳过重算,父记录上的汇总字段一直是 null,直到进程重启。这正是 AI 搭出来的应用里「已完成任务数」在元数据完全正确的情况下依然永远为空的原因:汇总配置对、子行的外键也解析好了,就是没有任何东西去算它(objectstack-ai/cloud#970 的收尾环节)。
改动
SchemaRegistry增加单调递增的objectRevision,在对象集合发生变化时自增(registerObject/invalidate/invalidateAll/unregisterObjectsByPackage/reset)。getSummaryDescriptors记住索引构建时的 revision,一旦对方前进就重建。这样「从 registry 派生的缓存」不会再因为某条路径忘了调用失效函数而变陈旧。
invalidateSummaryIndex()保留,作为兜底。测试
新增回归用例
summary-rollup.test.ts > a roll-up registered at RUNTIME still computes:先写一行把索引焐热,再按运行时发布的方式注册 parent + child,插入子行后断言父行的task_count/completed_task_count(带 filter)算对。去掉本 PR 的引擎改动后该用例会失败(已验证)。packages/objectql全量 91 files / 1501 tests 通过。🤖 Generated with Claude Code