Skip to content

fix(console): a create form states identifier errors in the reader's language, and its banner wraps them - #28395

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-58im2g
Oct 31, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-58im2g

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Fixes #28369

Clause-②: yes (widening)
Metadata-protocol: none

维护者速读

  • 改了什么:中文界面新建权限集(以及其他名称是 snake_case 标识符的元数据)时,表单上方错误横幅里关于「名称」的两条校验错误改为中文显示(「至少需要 2 个字符」「须为小写 snake_case:以字母开头……」);英文界面仍显示 spec 原句;横幅里的每条错误改为自动换行,不再被省略号截断。
  • 为什么改:中文管理员填了全中文的显示名称后,横幅却用英文说明错在哪,第二条还被截断(Studio create form: the summary banner states Name's identifier errors in English in zh-CN and cuts the second one #28369)。按 triage 路线,按 Zod issue 的 code 和 pattern 选译文,不匹配英文原句;spec 的消息文字不动。
  • 风险与回滚:只影响错误文字的显示语言和横幅换行,校验结果(能不能保存)不变;没有对应译文的错误照旧显示原文。回滚即 revert 本 PR。
  • 先看:ui/packages/app-shell/src/views/metadata-admin/i18n.ts(translateSchemaIssue 与 pattern 表);ui/packages/app-shell/src/views/metadata-admin/clientValidation.ts(issueDetail,只给 too_small / invalid_format 带 detail);ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx(横幅 li 的换行)。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/ResourceEditPage.identifierIssueI18n-28369.test.tsx,预期 8 个用例全绿;或在中文界面新建权限集,显示名称填「销售运营」,横幅两条都是中文、完整换行显示。
  • 需要你做的:无,席位落地。

What changes

The door carries what an issue is, not only what it says. validateMetadataDraft (clientValidation.ts) still returns each issue's spec message unchanged, and now adds an optional detail (Zod code plus origin / minimum / inclusive / format / pattern) on the two codes a rendering reads: too_small and invalid_format. Every other issue keeps exactly the { path, message } it had, so the existing exact-shape pins (clientValidation.viewDiagnostics.test.ts, clientValidation.metricMeasureArity-8894.test.ts) are untouched. Presentation only, after the verdict, like the two passes already there. SchemaFormIssue gains the optional detail.

The text is picked by code and pattern. New translateSchemaIssue (i18n.ts):

  • too_small on a string, inclusive bound → engine.validation.spec.stringTooShort ("至少需要 {minimum} 个字符").
  • invalid_format with format: 'regex' → a row chosen by the regex source, from a table of the spec's two identifier grammars in shared/identifiers.zod.ts: SnakeCaseIdentifierSchema → engine.validation.spec.snakeCaseIdentifier, SystemIdentifierSchema → engine.validation.spec.systemIdentifier.
  • Anything else, or no detail (server diagnostics, CEL lint findings) → the existing translateValidationMessage, unchanged.

English stays the spec's. The engine.validation.spec.* rows are zh-only in the studio namespace and read through tOptional, so an en console finds no row and shows the message @objectstack/spec wrote, never a copy kept in this repo (the same shape as engine.packages.form.help.*). The family is registered in STUDIO_ZH_ONLY_FAMILIES and, with its reason and anchor, in ZH_ONLY_REASONS / ZH_ONLY_FLOOR of inspectorStrings.studioNamespace-25922.test.ts. The other eight locales fall back to the English as for every Studio string. ⛔ No packages/spec/** change.

Callers. The summary banner and the canvas preview diagnostics in ResourceEditPage.tsx, and the inline field errors in SchemaForm.tsx, now call translateSchemaIssue. The banner's item is whitespace-normal break-words instead of truncate, with a metadata-diagnostics-item test id.

Tests

New ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.identifierIssueI18n-28369.test.tsx (8), the real page with the live registrations and the real served permission form, mocked client, copied from the #28232 rig:

  • fixtures: the installed SnakeCaseIdentifierSchema refuses an empty name with too_small then invalid_format; the zh rows exist.
  • (a) zh-CN, label 销售运营: both banner lines are the zh rows, and none carries the spec's English (read from the installed schema).
  • (b) CONTROL en-US: the banner shows the spec's own sentences.
  • (c) every banner line wraps (no truncate).
  • (d) the client door carries the detail and renders zh in zh, the spec message in en; both identifier schemas parsed live map to their zh rows; an issue without a code keeps the existing path.
Red on main, ablations, local runs (head c5e54f7)

Red through the real form on main: the three page files restored to the merge base a878ff6c (helper kept so the file imports) → Tests 4 failed | 4 passed (8): (a), (b), (c) and (d)-door red; (b) is red there only because main's banner item has no test id.

Ablations, each through scripts/ablation-replace.mjs (anchor 1 → 0, restored blob == HEAD, git diff HEAD empty):

  • A1 banner back to translateValidationMessage(i.message) → (a) red, 1 failed | 7 passed.
  • A2 banner item back to truncate → (c) red, 1 failed | 7 passed.
  • A3 door drops detail → (a) + (d)-door red, 2 failed | 6 passed (re-run on the final head c5e54f7, same result).
  • A4 snake_case pattern row deleted → (a), (d)-door, (d)-snake red, 3 failed | 5 passed; (d)-system stays green.
  • A5 stringTooShort lookup removed → 4 red, 4 failed | 4 passed.

Local, under the shared verify lock:

Acceptance notes

  • Only the two identifier grammars in shared/identifiers.zod.ts and the string minimum are translated. A schema with another regex (for example the dotted metadata item-name grammar) keeps its spec message in zh, as before.
  • The banner's warning block is server-sourced and still unrouted through this mapping; other translateValidationMessage call sites (EmbeddedItemEditor, PermissionMatrixEditor, studio-design) render server diagnostics, which carry no issue code, and are unchanged.
  • The ui/AGENTS.md ✨ Set up Copilot instructions #2 docs rule: no README or content/docs/frontend/ page describes the banner's text or SchemaFormIssue; nothing to update.

Verification

Live, Chromium at 820 px, own backend (objectstack dev --seed-admin, examples/app-showcase) and the Console dev server from this branch, Setup → Permission Sets → New, label 销售运营 (screenshots in the project folder issue-28369/):

  • before (page files at the merge base), zh-CN: 名称: Identifier must be at least 2 characters and the snake_case sentence, both text-overflow: ellipsis, the second cut (scrollWidth > clientWidth).
  • after, zh-CN: 名称: 至少需要 2 个字符 and 名称: 须为小写 snake_case:以字母开头,只能包含字母、数字和下划线(例如 “user_profile”), white-space: normal, nothing cut.
  • after, en-US: the spec's two sentences, the second wrapping onto two lines, nothing cut.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (not touched)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_01L6bhgUDuwt5hhPwSTHYJ4h

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 31, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv

维护者速读

  • 改了什么:中文界面新建权限集等元数据时,表单上方错误横幅和行内错误里关于「名称」格式的两条校验(长度不足、不是小写 snake_case)改为中文显示。英文界面仍显示 spec 原句。横幅里的每条错误改为换行,不再被省略号截断。
  • 为什么改:中文管理员填了中文显示名称后,横幅用英文说明错在哪,第二条还被截掉(Studio create form: the summary banner states Name's identifier errors in English in zh-CN and cuts the second one #28369)。
  • 风险与回滚:只改错误文字的语言和换行,能否保存不变。没有译文的错误照旧显示原文。回滚就是 revert。
  • 先看:metadata-admin/i18n.ts 里的 translateSchemaIssue 与 pattern 表,clientValidation.ts 里的 issueDetail。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/ResourceEditPage.identifierIssueI18n-28369.test.tsx,8 个用例应全绿。前后截图在项目文件 issue-28369/。
  • 需要你做的:无。非受管面、Tier S,席位在 CI 全绿后落地。

席位意见:ACCEPT。按 issue 的 code 与 pattern 选译文,不匹配英文,spec 文字未动,符合分诊路线。

席位核对 — ACCEPT · domain:ui#4 · Head-sha c5e54f7861e28d57784641ef0f8e95446b7fc7d9 · 2026-10-31T10:21Z

  1. Shape: 9 files, +340 / −10, all inside the claim's surface (6541160671): metadata-admin (i18n.ts, clientValidation.ts, ResourceEditPage.tsx, SchemaForm.tsx, the new test, and one floor row in the 25922 studio-namespace test), the i18n studio zh.ts plus its zh-only family list, and a root changeset (app-shell patch, i18n patch). packages/spec/** is untouched.
  2. Premise measured (seat's own read):
    • The route matches triage 6540860850. issueDetail attaches code plus params only to too_small and invalid_format, so other issues keep their exact { path, message } shape.
    • translateSchemaIssue picks the row by code. For a regex it picks by the pattern source, from a table of the two spec grammars, and never by the English. I read the table against packages/spec/src/shared/identifiers.zod.ts: L133 is ^[a-z][a-z0-9_]*$ (snake_case) and L105 is ^[a-z][a-z0-9_.]*$ (system identifier). The new test parses the live schemas and goes red on drift.
    • The banner li changed from truncate to whitespace-normal break-words.
    • The fix-zh-820.png screenshot shows both banner lines in Chinese and unclipped at 820 px. before-zh-820.png and fix-en-820.png are beside it in the project's files.
  3. Gates and check-runs:
    • On this head at this reading: 8 success, 11 skipped, 33 in progress, 0 failed. Landing waits for every check to be green or an expected skip.
    • The thread reported: new test 8/8 (4 red on main), 5 ablations red then restored, 684 metadata-admin files green, dispatch-gates 34 commands exit 0.
    • check-governed-merges --pr 28395: NOT governed, 350 changed lines.
  4. Accepted deviations: none. The changeset text is plain and names both packages.
  5. Out of scope, with destinations: none reported or found. Skills-docs: n/a (Metadata-protocol: none).
  6. Landing clause: Tier S. On all-green, the seat lands it by relay pr_ready plus automerge_enable.

Clause-② review of record (TIER_DEFAULT, in-seat)

  • Declared: Clause-②: yes (widening), on the claim and the PR.
  • What widens:
    • @object-ui/i18n (published) gains three zh-only rows: engine.validation.spec.stringTooShort, snakeCaseIdentifier and systemIdentifier. The en pack is unchanged, so TranslationKeys (typeof en) is unchanged. The family is registered in STUDIO_ZH_ONLY_FAMILIES and floored in the 25922 test, with a stated reason: an en row would be a second producer of the spec's English.
    • SchemaFormIssue gains an optional detail, and SchemaIssueDetail is new. Both live in @object-ui/app-shell, which is private: true (its package.json). No published entry exports either type.
  • Does any accept set widen? No. validateMetadataDraft's verdict is unchanged: detail is attached after the parse, for presentation only. No schema, key or route accepts anything new.
  • Verdict: PASS. It is an additive translation surface on a published locale pack, with no change to the contract's accept sets.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio create form: the summary banner states Name's identifier errors in English in zh-CN and cuts the second one

1 participant