fix(plugin-audit): exclude computed fields from update diffs + treat undefined/null as equal#3293
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 4 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…undefined/null as equal
Two audit-writer diff bugs surfaced by the objectui record History tab
(gantt QA report showed "紧前依赖(渲染用): [id] → —" on every drag):
1. The beforeUpdate snapshot is read back through the query path, which
computes formula/summary/rollup/autonumber fields; ctx.result is the raw
write result, which does not. diff() therefore recorded a phantom
"value → null" change for every computed field on every update. Computed
fields are now excluded from the diff via the engine schema (their
changes are implied by their source fields); an update touching only
computed fields no longer writes an audit/activity row at all.
2. safeStringify(undefined) returns undefined (JSON.stringify contract),
not a string, so a key absent on one side compared unequal to an
explicit null on the other and wrote a noise row with old=new=null.
Values are normalized with `?? null` before comparison; a real
value → null transition is still recorded (covered by a guard test).
Verified against a live showcase stack: updating showcase_project.health
now writes old_value {"health":"green"} / new_value {"health":"yellow"}
with no task_count/total_estimate phantoms, and the three new regression
tests fail against the pre-fix writer.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
os-zhuang
added a commit
that referenced
this pull request
Jul 22, 2026
The v16 sweep (#3358 §4 "Record History tab") couldn't exercise the tab because no showcase object opted into it: the console gates the History tab on object-level `enable.trackHistory` (RecordDetailView) — audit *capture* is always on, but the *tab* is opt-in — and the showcase only set `trackHistory` at the FIELD level (industry/status), which just selects which diffs are summarized. So the tab never rendered anywhere and #2691/#3293 (display-value diffs, computed-field exclusion) were undemonstrated. Set `enable: { trackHistory: true }` on Account (which already declares field-level `trackHistory` on `industry`/`status` for clean diffs). Verified in the running app: the Account detail now shows a **历史 / History** tab; after editing `industry`, it renders "Dev Admin · UPDATE · 行业: Retail → Technology" — field label + select **display values** (not raw stored codes/ids), no phantom value→null rows. `os validate` + `tsc --noEmit` pass. Follow-up to #3364 / #3393, from the #3358 sweep §4. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
问题
objectui 记录历史 Tab 实测(甘特 QA 项目)暴露出审计写入器
diff()的两个数据层 bug:beforeUpdate快照经查询路径读回,带 formula/summary/rollup/autonumber 的计算值;ctx.result是裸写入结果,不带。于是每次更新都为每个计算字段写入一条值 → null的假变更(前端表现为紧前依赖(渲染用): [id] → —逢改必现)。safeStringify(undefined)按JSON.stringify契约返回 undefined(非字符串),与'null'比较必不等,导致"字段缺失"对"显式 null"被记成 old=new=null 的废行。修复
diff()接受字段定义,跳过formula/summary/rollup/autonumber类型(派生值的变化由源字段的 diff 隐含);仅计算字段变化时不再写审计/活动行?? null归一化;真实的"值 → null"清空仍正常记录(守护用例覆盖)测试
showcase_project.health(该记录task_count=5/total_estimate=100均在 before 快照内)→ 审计行为干净的{"health":"green"} → {"health":"yellow"},零幻影字段配套展示层修复:objectstack-ai/objectui#2691(老数据幻影行由前端过滤兜底)。
🤖 Generated with Claude Code