Skip to content

fix(showcase): translate the task detail review banner under zh-CN - #29104

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-28982-showcase-review-alert-zh
Nov 2, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-28982-showcase-review-alert-zh

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by 田騏 · project thread

Fixes #28982
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:showcase 任务详情页顶部的「待评审」黄色提示条在中文会话下改为中文——标题走翻译包,正文用页面上的内联多语言文本。
  • 为什么改:中文用户打开评审中的任务,整页都是中文,唯独这条提示是英文,像没翻完;发版清单 i18n.notification-localized-and-clears 的 A1(不得中英混排)因此一直红。
  • 风险与回滚:只动示例应用,不发布任何包;提示条的「关闭记忆」改用固定键,之前关掉过它的人会再看到一次;回滚即还原本 PR。
  • 先看:examples/app-showcase/src/ui/pages/task-detail.page.ts(record:alert 节点的 id、body、dismissKey)→ examples/app-showcase/src/system/translations/index.ts(zh-CN 的 pages.showcase_task_detail)→ 新测试文件。
  • 两分钟验证:pnpm --filter @objectstack/example-showcase exec vitest run test/task-detail-review-alert-zh-cn.test.ts,预期 3 passed;或中文会话打开种子任务「Design system」,提示条显示「待评审」和中文正文。
  • 需要你做的:无,席位落地。

What changes

The Task Detail page (showcase_task_detail) shows a record:alert banner while a task is in review. On a zh-CN session it rendered in English because the node had no component id, and page component copy is translated through pages.NAME.components.COMPONENT_ID.KEY.

  • task-detail.page.ts: the banner gets id: 'review_alert' (snake_case, like the page ids elsewhere in the showcase: new_project_form, project_picker).
  • translations/index.ts: the zh-CN bundle gains pages.showcase_task_detail.components.review_alert.title = 待评审. The en block carries no pages entries, and the authored English stays the default text. The showcase ships en and zh-CN only (objectstack.config.ts supportedLocales), so no other locale needs the key.
  • body does not go through the bundle, because the bundle has no key for it. The page-component copy face is title / description / label / placeholder / emptyText (PAGE_COMPONENT_COPY_KEYS, packages/spec/src/system/i18n-resolver.ts), and the bundle schema is strict there. Measured on the built spec: an entry with only title parses, and one with title plus body is refused with unrecognized_keys ("Unrecognized key(s) on this page component translation: body"). RecordAlertProps.body is declared I18nLabelSchema, and the renderer reads it through pickLocalized, so the body is now an inline locale map holding both en and zh-CN. This follows the recorded precedent for element:text content in translation.zod.ts: the inline locale map is the ruled route for page prose, and that shape was not added to the bundle.
  • dismissKey: 'showcase_task_review': the dismissal key defaults to the English resolution of title. Once the bundle translates the title, a zh-CN session would resolve that key to the translation, so a banner dismissed in one locale would come back in the other. The key is now fixed.

Tests

  • New pin: examples/app-showcase/test/task-detail-review-alert-zh-cn.test.ts. It applies translateMetadataDocument('page', …) to the page with the app's own bundle, which is the same thing the REST boundary does for each request locale. It asserts the zh-CN title, that the body's locale map comes back intact, the fixed dismissKey, the English title under en, and that the zh-CN bundle still parses under TranslationBundleSchema. Its model is zh-cn-report-blocks-inline-titles.test.ts.
  • Reverse check, run once: with the two source files restored to base ab085a0482 and the test kept, the pin goes red (expected undefined to be 'review_alert', 1 failed and 2 passed). Restored from HEAD, git diff HEAD is empty.

Acceptance notes

  • The card listed title/body under the bundle key. Only title can go there (see above). Adding body to the page-component face would widen the spec (Metadata-protocol: added), and the content precedent declined that for prose of the same shape. This PR stays inside the current contract.
  • The inline locale map on body cannot be seen by os i18n extract or check:i18n-coverage. That extractor question is a known one and is out of scope here.
  • Read-only survey of the showcase pages, not fixed here and not measured in a browser: these id-less components carry copy on the bundle face, so they have no zh-CN key. showcase_my_work: the object-metric label and description ("Open Tasks", "In Review", "At-Risk Projects") and the page:card titles "Shortcuts" and "Leadership View". showcase_component_gallery: four object-metric blocks and an element:button "Create Task". showcase_project_detail: the record:line_items and record:related_list titles "Tasks". Several element:text content strings on those pages are plain English. Their route is the inline map, not the bundle.

Verification

Head 6c6289c0c9 (origin/main merged once, at c708de67b2). The dependency closure was rebuilt after the merge.

Showcase package: typecheck, tests, validate
  • pnpm --filter @objectstack/example-showcase typecheck && … exec vitest run --maxWorkers=2 (run under the verify lock): VERDICT command-exit 0, Test Files 43 passed (43), Tests 514 passed (514)
  • pnpm --filter @objectstack/example-showcase validate: exit 0. No finding names showcase_task_detail or the banner.
Derived gates (dispatch-gates --commands, 40)
  • 39 gates exited 0, including check:i18n-coverage ("OK (14 config(s), 426 baselined untranslated string(s), none new)"), check:page-declaration-shape, check:nul-bytes and check:examples-live-imports.
  • check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET). It needs dist output from packages outside this diff's closure, so it is NOT MEASURED here and is left to CI.
  • --ran reconciliation: "40 derived famil(ies) accounted for — 39 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)".

Changeset: none. @objectstack/example-showcase is private: true and publishes nothing, so the PR carries skip-changeset.

🤖 Generated with Claude Code

The record:alert on showcase_task_detail had no component id, so the
page-component translation route could not address it and its title and
body stayed English on a zh-CN session. Give it the id review_alert,
translate its title in the zh-CN bundle, carry the body as an inline
locale map (body has no key on the page-component copy face), and pin a
dismissKey so a translated title does not move the dismissal key.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2gLghEqeDKTbDTC7Zd
…owcase-review-alert-zh

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2gLghEqeDKTbDTC7Zd
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 2, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd

席位核对 — ACCEPT · domain:devx#2 · head 6c6289c0c9513379ef90083a08e91db3a74b944e · 2026-11-02T07:43Z

Checked against GitHub and the PR head, not against the report (os-dev-report 6571575900 on #28982).

  • Shape: a draft to main with Fixes #28982 once, Clause-②: no and Metadata-protocol: none. It has no assignees and no reviewers. skip-changeset is correct, because only examples/app-showcase changes and that package is private.
  • Path surface: three files in the showcase example (+88/−1): the page, its zh-CN bundle, and one new test. It touches no contract face and no skill text, so the seat reads it with CI and no second agent.
  • Card rules, read in the diff: the card expects the callout to render in Chinese like the rest of the page. Both strings now reach a zh-CN reader:
    • title goes through the bundle at pages.showcase_task_detail.components.review_alert.title. That works because the node now has id: 'review_alert', which was the gap the card's Mechanism names.
    • body carries an inline { en, 'zh-CN' } map. The seat read why it cannot use the bundle: PAGE_COMPONENT_COPY_KEYS (packages/spec/src/system/i18n-resolver.ts L2803) is title, description, label, placeholder and emptyText, with no body. RecordAlertProps.body is I18nLabelSchema, and the renderer resolves it through pickLocalized (packages/spec/src/ui/component.zod.ts, the RecordAlertProps docblock). The English text is unchanged.
    • dismissKey: 'showcase_task_review' keeps one dismissal key in every locale. By the schema's own description, the default key is the resolved title, and a bundle-translated title would otherwise move it.
  • Gates: the new pin passes 3/3 and fails against the base sources (1 failed, 2 passed), so it catches the defect. The showcase package typechecks and passes 43 files / 514 tests, and objectstack validate exits 0. dispatch-gates --ran accounts for 40 commands: 39 exit 0 (including check:i18n-coverage), and check:dual-build-cjs-loads exited 3 locally because unrelated packages were unbuilt, so CI's run of it stands. The seat lands once every check on this head is green.
  • Accepted deviations: the card names a bundle key for both title and body. Only title has one on this face. Widening the page-component face for body would be a spec change (Metadata-protocol: added) beyond a showcase card, and the inline map is a delivered route on this component. Also, a reader who already dismissed the English banner sees it once more, because the dismissal key changes.
  • Out of scope: the dev read, from source only, more showcase copy that has no component id or is plain English: the KPI labels and card titles on showcase_my_work, four KPI blocks and a "Create Task" button on showcase_component_gallery, and the "Tasks" titles on showcase_project_detail. These are not verified in a browser and not filed. The seat files a card once a zh-CN run confirms them. Skills-docs: none — example copy only.
  • Landing: non-governed. Once every check on this head is green, the seat marks the PR ready and enables auto-merge.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 2, 2026 07:44
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 2, 2026 07:44
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 692e0dc Nov 2, 2026
48 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-28982-showcase-review-alert-zh branch November 2, 2026 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

1 participant