Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell): SchemaForm 读取归一化后的 visibleWhen,让 metadata-form 谓词首次真正生效 - #3923
Conversation
…g every metadata-form predicate (objectstack#6331) ADR-0089 renamed the FormView visibility predicate `visibleOn` -> `visibleWhen`, and the spec normaliser REWRITES the alias instead of keeping both: a parsed FormView carries `visibleWhen` and no `visibleOn` at all. All five predicate read sites in the metadata-admin SchemaForm looked at `visibleOn` only, so every spec-served predicate read as absent and each guard short-circuited to "visible" - conditional fields, sections and tabs rendered unconditionally in every metadata form. Measured over the bundled @objectstack/spec@17: objectForm carries 16 sub-field predicates, viewForm 7, actionForm 6, pageForm 4 - all spelled `visibleWhen`, none spelled `visibleOn`. Every one was inert. Read sites fixed (all via one `readVisibility()` reader, canonical first): flat per-property, section-level, section field-level, the tabbed path's field probe, and `type: 'record'` row sub-fields. Spelling and precedence mirror the existing adapters - plugin-form `sectionFields.ts` and react `form-view.ts` both already read `visibleWhen ?? visibleOn` - so the repo keeps one dialect. `FormSectionSpec` / `FormFieldSpec` now declare both keys, alias `@deprecated`. The alias stays honoured because it has live producers that never pass through the spec normaliser: this app's own create schemas set `visibleOn` directly on raw JSONSchema properties (`view-create-body.ts`, `anchors.ts`). Tests: SchemaForm.visibleWhen.test.tsx pins each of the five sites in both directions, the alias limb, canonical-over-alias precedence, and the real bundled `pageForm` (so a regression cannot hide behind a hand-transcribed fixture). `SchemaForm.pageVisibility.test.tsx`'s doc comment is corrected: its `visibleOn` fixtures pin the deprecated limb, not the shape a backend serves - which is why they stayed green while every real predicate was dead.
The latest updates on your projects. Learn more about Vercel for GitHub. |
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 9, 2026
正文里提到的求值器 finding 已立单:objectstack-ai/objectstack#6936(未认领、未进队列,交 PM 分诊)。 要点: Generated by Claude Code |
yinlianghui
commented
Aug 9, 2026
✅ 验收通过(objectui 分片 PM,session 实物核验:base 验收要点:
范围外发现 objectstack#6936(求值器对解析失败静默判假,与 fail-open 自述相反;前后端版本错配时 16 个配置项静默消失)已按规程立单未认领,归后续分诊 —— v17 冻结期不派。 GraphQL 配额未恢复则 undraft+auto-merge 由 PM 随后补发。 Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixesobjectstack-ai/objectstack#6331
问题
ADR-0089 把 FormView 的可见性谓词从
visibleOn改名为visibleWhen,spec 的归一化是改写而非双写:parse 之后的 FormView 只带visibleWhen,visibleOn完全不存在。而 metadata-admin 的SchemaForm.tsx五个谓词读取站点只读visibleOn,于是每一条 spec 下发的谓词都读到undefined,guard 短路成「可见」—— 所有 metadata 表单的条件字段、条件分区、条件页签一律恒显。一次性探针跑在本仓实际安装的
@objectstack/spec@17.0.0-rc.5上(读数入 issue 报告):33 条谓词,一条都没生效过。
修法
五个站点统一走一个
readVisibility()(canonical 在前):扁平逐属性、分区级、分区内字段级、tabbed 路径的字段探测、type: 'record'行内子字段。拼法与优先级镜像仓内既有适配,不新造方言 ——@object-ui/plugin-form的sectionFields.ts与@object-ui/react的form-view.ts早就是visibleWhen ?? visibleOn。FormSectionSpec/FormFieldSpec两处类型同时声明两个键,别名标@deprecated。别名这条腿保留不是「容错」,而是它有活的生产者:本 app 自己的 create schema 直接把
visibleOn写在原始 JSONSchema 属性上(view-create-body.ts、anchors.ts),这条路径根本不经过 spec 归一化。行为变更面(这些谓词从未在发布版里生效过,本 PR 是第一次打开)
currency字段只出 Min / Max / Precision / Scale,text字段只出 Max Length / Min Length,不再一次性全出。list页隐藏 Data Context / Layout / Template 并显示 Interface 分区,record 页反之。View / Action / Report 表单同样拿回各自的类型条件分区与字段。浏览器实证
临时探针页(未提交)把真实 bundled spec 表单喂进真实
SchemaForm,Playwright 驱动 Chromium 读数:pageForm,type: home→ 分区 Basics / Data Context / Advanced,字段含 Template;切到type: list→ Data Context 与 Template 消失,Interface (list pages)整棵子树出现。objectForm的fieldsrecord 节点(#6254 后的data.拼法),行type: currency→Min, Max, Precision, Scale;切到text→Max Length, Min Length。两向都对。反向验证(方向先判后跑,逐站点点名)
五个站点各自还原成只读
visibleOn,红点与预判完全一致:站点1 → 扁平 2 红;站点2 → 分区 2 红 + bundled pageForm 渲染 1 红;站点3 → 字段级 3 红;站点4 → tabbed 2 红;站点5 → record 行 2 红。一处预判需要更正:我原本写「别名 describe 在任何还原下都保持绿」,但站点2 还原时多出第 4 个红点 —— 那条「canonical wins」测试虽然写在别名 describe 里,实际钉的是 canonical 优先级(删掉 canonical 腿后由过期别名定胜负,必然红)。已按它真正守的东西把它移进独立 describe 并注明。别名测试本身在每次还原下确实全绿 —— 这正是这个 bug 能长期潜伏的原因:别名拼法的 fixture 永远看不见它。
rollout 注意
谓词必须是
data.作用域才能对着草稿求值(objectstack#6254 修正了object.form.ts里 16 处裸拼法)。仍在下发 #6254 之前裸拼法的后端,配上本 PR 会得到相反症状 —— 这些子字段变成恒隐而非恒显,因为本引擎的求值器把未作用域标识符解析成undefined、谓词判假。浏览器探针里两种拼法并排验证过。求值器这个「未解析标识符静默判假、与自身文档承诺的 fail-open 相反」的行为已另立 finding 单,不在本 PR 范围。验证
pnpm --filter '@object-ui/app-shell^...' build✅SchemaForm.visibleWhen.test.tsx+ 既有三个 SchemaForm 测试文件 + repeaterUnion:Test Files 5 passed (5) / Tests 26 passed (26)packages/app-shell/src/views/metadata-admin→Test Files 131 passed (131) / Tests 1272 passed | 1 skippedpackages/core的 column-identity ratchet(按文件计数的闸门,确认新增??不撞它):7 passedpnpm exec turbo run type-check --concurrency=2:78 successful, 78 totalnode scripts/check-control-bytes.mjs:OK(3799 tracked text files)Generated by Claude Code