fix(showcase): showcase_contact 声明 fieldGroups,让视图注释承诺的自动分组成真 (#5443) - #5463
Merged
Conversation
…erivation promise is true (#5443) Nine `showcase_contact` fields carry `group: 'contact' | 'work' | 'status' | 'notes'` while the object declared no `fieldGroups`. Per ADR-0085 §5, `deriveFieldGroupLayout` buckets a field only when its `group` matches a declared `fieldGroups[].key` — with none declared it returns `null` outright, so those nine `group` values rendered exactly like no `group` at all. `os lint` said so, nine times, as `field-group-undeclared`. Meanwhile the header comment of `src/ui/views/contact.view.ts` — the reference implementation `content/docs/ui/create-vs-edit-form.mdx` cites — promised that the hand-written `form` "mirrors what the platform auto-derives from `field.group`" and that you may "OMIT it and get an equivalent grouped form for free". That grouped form did not exist: a reader copying the example and dropping `form` got a flat one. Prime Directive #10's corollary, with the example's own comment doing the advertising. - `contact.object.ts` declares the four groups (labels matching the view's four sections). - The view comment is calibrated rather than rewritten: it now names `fieldGroups` as the authority for the derivation, and states the two honest differences the derived form has — the platform-injected `owner_id` lands in a trailing untitled section (audit/system columns are excluded, ownership is not), and `columns: 2` is form-view presentation the group declaration does not carry. Both verified against `deriveFieldGroupLayout` over the object before and after `applySystemFields`. - `test/seed.test.ts` pins the promise itself: the derived sections must equal the authored `form.sections` in order and membership. Removing `fieldGroups` turns it red on `derived !== null` rather than passing vacuously. Three-state measurement, not presumption — before / `fieldGroups` only / full: `field-group-undeclared` 9 → 0 → 0 (total warnings 484 → 475 → 475, no new rule); the derived `_sections` key set is unchanged at 14 (`showcase_contact` stays contact/work/status/notes — the walker dedupes the declaration-derived keys against the view-authored ones #5438 already translated); repo-level `check:i18n-coverage` reports 660 baselined, "none new", in all three states. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016FNvXhtSdnEGEfLEsMmvxh
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
This was referenced Aug 5, 2026
baozhoutao
marked this pull request as ready for review
August 5, 2026 13:04
baozhoutao
enabled auto-merge
August 5, 2026 13:05
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.
Fixes #5443
问题
examples/app-showcase/src/data/objects/contact.object.ts的九个字段都写了group(contact/work/status/notes),对象却没有声明fieldGroups。按 ADR-0085 §5,deriveFieldGroupLayout(渲染器与 i18n walker 共用的唯一派生实现)只把group命中已声明fieldGroups[].key的字段归入分组;一个都没声明时它直接return null,分组根本不适用。所以这九个group与完全不写group渲染结果相同 ——os lint为此报了九条field-group-undeclared。而
src/ui/views/contact.view.ts的头注释(content/docs/ui/create-vs-edit-form.mdx引用的那份参考实现)写的恰恰相反:手写的form「镜像平台自动派生的结果」,「省掉它就能免费得到等价的分组表单」。那张分组表单当时并不存在:照抄示例、真把form省掉的读者拿到的是一张平铺表单。这是 Prime Directive #10 推论(不要宣传运行时并不提供的能力),只不过做广告的是示例自己的注释。#5420 落地后nav_contacts真的会渲染这一族视图,潜伏的谎言变成现役。改动
按 12:01Z 分诊裁定走方向 1 + 注释校准,三个文件:
contact.object.ts补四组fieldGroups声明,label 与视图四个段落一致;字段表头注释点明「group还必须在fieldGroups里声明,那份声明才是派生的授权来源」。contact.view.ts只改头注释:保留原有叙事,把错误的承诺改真 —— 派生以fieldGroups声明为授权来源,未声明的group等同于没写。并如实写出省掉form后与手写版的两处差异(实测所得,不是推定):owner_id(审计列与organization_id被FIELD_GROUP_SYSTEM_FIELDS/hidden排除,所有权列两者都不属于);columns: 2这类段落排版是表单视图的旋钮,分组声明不携带。test/seed.test.ts新增用例,钉住的是承诺本身而不是声明:派生段落必须与视图手写的form.sections在顺序与成员上相等。三态实测(实测不推定)
fieldGroupsfield-group-undeclaredos lint总计_sections键总数showcase_contact._sectionspnpm check:i18n-coverage_sections键集合不变的机制已核实:声明派生(walker 路径 a)与视图手写段落(路径 b)产出同名四键,addSection首次写入即去重 —— 与 #5438 已译的四键完全同名,所以既没有第 5 个新键,也没有计数变动。棘轮基线scripts/i18n-coverage-baseline.json与supportedLocales未动;packages/**未动。「省掉 form」这半句的实测依据
直接跑
deriveFieldGroupLayout(不起浏览器),对同一对象取两态:contact[name,email,phone]/work[company,title,account]/status[stage,lead_score]/notes[notes],与视图手写段落逐段同序同成员。applySystemFields(注册时形态)→ 同样四段,外加一个无 key 的末尾段[owner_id]。所以「省掉
form得到等价分组表单」现在成立,注释按上面这两处差异如实收口。反向验证(方向先判后跑)
预判:删掉
fieldGroups后deriveFieldGroupLayout返回null,新用例应在第一条断言就红,而不是因为「什么都没产出」而空跑变绿。实跑一致:恢复后 127/127 全绿。
测试
pnpm --filter @objectstack/example-showcase test→Test Files 12 passed (12)/Tests 127 passed (127)pnpm --filter @objectstack/example-showcase typecheck→tsc --noEmit无输出pnpm check:i18n-coverage(先turbo run build,72/72 successful)→OK (12 config(s), 660 baselined untranslated string(s), none new).os validate/os lint见上表pnpm --filter @objectstack/dogfood test→503 passed | 6 skipped,另有 1 个 suite 失败且与本改动无关 ——showcase-declarative-endpoints的/openapi.json返 503,原因是packages/spec/json-schema/(.gitignore第 61 行)在新工作树里没有openapi.json,而gen:openapi是 AGENTS.md 明确记载的两个无门禁生成器之一;共享检出里同样缺这个文件。跑一次pnpm --filter @objectstack/spec gen:openapi后该文件14 passed (14)全绿。顺带发现(未在本 PR 修)
已另立 #5458(未认领):
content/docs/ui/create-vs-edit-form.mdx§2 与content/docs/ui/field-grouping-and-order.mdx的语义分组小节及其代码样例,同样把「表单分组派生自field.group」讲成field.group自己就够,两篇全文均不出现fieldGroups—— 与本单同一个谎言的文档层,按分诊给定的文件面不在本 PR 范围内。🤖 Generated with Claude Code
https://claude.ai/code/session_016FNvXhtSdnEGEfLEsMmvxh
Generated by Claude Code