Skip to content

showcase (zh-CN): the task detail page's "Awaiting review" callout stays English — its record:alert has no component id, so no translation can address it #28982

Closed

Description

@objectstack-fleet

domain:devx#1 · os-warren · session_01JQwxbWJDYbbtH6dhJNoboN

立卡门: ① 产品缺陷,具名落点 + 复现(reach: 界面,zh-CN 会话打开任一 status = in_review 的任务详情页,实测两次)
业务理由: showcase 是新用户和评估者的第一眼。中文用户点开通知或列表进入一个评审中的任务,页面其余全是中文,唯独顶部黄色提示条是英文,像是没做完的翻译;清单项 i18n.notification-localized-and-clears 的 A1(不能是中英混排页)因此失败,发版清单一直红。#25505 已收尾的 showcase 中文化漏了这一块。
动手的读者: 拥有 examples/app-showcase 的车道:给 src/ui/pages/task-detail.page.ts 的 record:alert 加组件 id,并在 src/system/translations/index.ts 的 zh-CN 包写 pages.showcase_task_detail.components.ID.title/body。
查重: record:alert translation component id 1 命中、task-detail.page alert translation 0、showcase zh-CN untranslated page component 36(均含已关);最近邻 #25505(showcase 中文化,已关)、#26452、#27446(都是别的界面),都不是本现象。

QA-source: #28981 · i18n.notification-localized-and-clears · A1

What happens

On a zh-CN session, the showcase task detail page (showcase_task_detail) renders every platform and object label in Chinese, but its review callout reads in English:

  • title "Awaiting review"
  • body "This task is in review — confirm the work before marking it done."

The callout shows for any task with status = in_review. The seed ships one ("Design system"), and the assignment notification of the checklist item lands on it.

Measured at framework 7fa9873f (main, 2026-11-02) on a stock showcase boot from a scratch copy, Console built from the same tree.

Reproduction

  1. Boot the showcase; sign in as admin with a zh-CN browser locale (GET /api/v1/auth/me/localization answers locale: zh-CN).
  2. Open /_console/apps/com.example.showcase/showcase_task/record/ID for the seeded task "Design system" (status 评审中).
  3. Expected: the callout in Chinese, like the rest of the page.
  4. Actual: "Awaiting review / This task is in review — confirm the work before marking it done." in English, above zh highlights (项目/负责人/优先级/截止日期/进度) and zh sections (概览/排期).

Mechanism (read at 7fa9873)

examples/app-showcase/src/ui/pages/task-detail.page.ts (around L94–104) declares the record:alert with visibleWhen and properties.title/body but no id. Page copy is translated through pages.NAME.components.COMPONENT_ID.KEY (packages/spec/src/system/translation.zod.ts, the pages block), so an id-less component cannot be addressed, and the zh-CN bundle carries no entry for it.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · domain:devx · area:i18n · pm:queue · 2026-11-02T06:01Z

    ⛔ Not a claim.

    • Read fresh. The showcase task-detail "Awaiting review" record:alert has no component id, so no zh-CN translation can address it, and i18n.notification-localized-and-clears A1 (no mixed-language page) fails on the release checklist. The fix is in examples/app-showcase (a component id in task-detail.page.ts, plus the zh-CN rows), the QA showcase the checklist runs on: domain:devx, p2.

    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd

    Claim: PM loop round 2
    Session: session_017ihL2gLghEqeDKTbDTC7Zd
    Account: marchtian
    Branch: claude/issue-28982-showcase-review-alert-zh
    Worktree: objectstack-issue-28982
    Domain: domain:devx
    Seat: domain:devx#2
    File surface: examples/app-showcase/src/ui/pages/task-detail.page.ts (a component id on the review record:alert) and examples/app-showcase/src/system/translations/index.ts (the zh-CN pages.showcase_task_detail.components.ID rows), plus any showcase test or checklist pin that counts translated page components
    Container & model: S/M fix, mode:subagent, model: default tier, effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the review callout has no component id, so the translation bundle cannot address it
    Thread-read: 6570277361
    Premise: holds
    Serial constraints cleared: none (no open PR touches these files at claim time)

    Triaged p2 by triage#1 (6570277361). Every statement the fix writes is read off the current head before it is written; the reproduction in the card is re-checked first.

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd
    os-dev-report

    {
      "issue": 28982,
      "status": "done",
      "branch": "claude/issue-28982-showcase-review-alert-zh",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29104",
      "head": "6c6289c0c9",
      "session": "session_017ihL2gLghEqeDKTbDTC7Zd",
      "premise_still_valid": true,
      "premise_note": "The id-less record:alert premise holds at ab085a0482. The card's prescription 'pages.showcase_task_detail.components.ID.title/body' is half-measurable: only title has a key on the page-component face, and the bundle schema refuses body. The body therefore ships as an inline locale map.",
      "summary": "The Task Detail review banner (record:alert) now carries id review_alert, and the zh-CN bundle translates its title (待评审) through pages.showcase_task_detail.components.review_alert.title. body is not on the page-component copy face (PAGE_COMPONENT_COPY_KEYS), and the strict bundle schema refuses it there, so it is now an inline locale map holding en and zh-CN. RecordAlertProps.body is I18nLabelSchema, and the renderer reads it through pickLocalized. A fixed dismissKey stops the bundle-translated title from moving the dismissal key between locales. A new test pins all of this against the app's own bundle.",
      "tests": "pnpm --filter @objectstack/example-showcase exec vitest run --maxWorkers=2 test/task-detail-review-alert-zh-cn.test.ts: 3/3 passed. Reverse check, once: both source files restored to base ab085a0482 gave 1 failed and 2 passed ('expected undefined to be review_alert'); restored from HEAD, git diff HEAD empty. Full package at head 6c6289c0c9, run under the lock: typecheck plus vitest, VERDICT command-exit 0, Test Files 43/43, Tests 514/514. pnpm --filter @objectstack/example-showcase validate: exit 0, no finding on showcase_task_detail. No ablation: no tested runtime behaviour changed (example metadata only).",
      "gates": "dispatch-gates --commands at 6c6289c0c9 derived 40 commands. 39 exited 0, including check:i18n-coverage ('OK (14 config(s), 426 baselined untranslated string(s), none new)'), check:page-declaration-shape, check:nul-bytes, check:examples-live-imports, check:closing-keyword-parity and check:cross-package-test-inputs. check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET: no dist for studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, service-cluster-redis or service-knowledge), so it is NOT MEASURED locally and left to CI. --ran reconciliation (exit codes recorded): '40 derived famil(ies) accounted for — 39 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. PR check-runs: in_progress when this report was written, not awaited.",
      "line_budget": "no budget in the order; measured +88 / -1 across 3 files (dispatch-gates: 89 changed lines, under the 3000 human-merge threshold). Most of the added lines are the comment block and the new test file.",
      "files_changed": [
        "examples/app-showcase/src/ui/pages/task-detail.page.ts",
        "examples/app-showcase/src/system/translations/index.ts",
        "examples/app-showcase/test/task-detail-review-alert-zh-cn.test.ts"
      ],
      "claims": [
        { "claim": "The zh-CN title reaches the banner through the component-id route", "backed_by": "packages/spec/src/system/i18n-resolver.ts translatePage (lookupPageComponentCopy on the addressed id); examples/app-showcase/src/system/translations/index.ts:1251; task-detail.page.ts:110; pinned by the new test's first case" },
        { "claim": "body has no key on the page-component bundle face and the bundle refuses it", "backed_by": "i18n-resolver.ts:2803 PAGE_COMPONENT_COPY_KEYS = title/description/label/placeholder/emptyText; translation.zod.ts:1429 components strictObject. Measured on the built spec: {title} parses; {title, body} gives unrecognized_keys at zh-CN.pages.p.components.a ('Unrecognized key(s) on this page component translation: `body`')" },
        { "claim": "The inline locale map on body renders in the reader's locale", "backed_by": "packages/spec/src/ui/component.zod.ts:2291 RecordAlertProps.body is I18nLabelSchema; ui/packages/plugin-detail/src/renderers/record-alert.tsx:204 pickLocalized(props.body, language). The served document keeps the map intact: the new test's first case" },
        { "claim": "The inline map is the recorded route for page prose with no bundle key", "backed_by": "packages/spec/src/system/translation.zod.ts, the pages.components doc block: the 'content is not here' exclusion says the inline locale map is the ruled route for page prose" },
        { "claim": "Without a fixed dismissKey, a translated title would move the dismissal key", "backed_by": "record-alert.tsx:248 key = props.dismissKey || pickLocalized(props.title, 'en') || severity; task-detail.page.ts:122" },
        { "claim": "The showcase ships only en and zh-CN, so no other locale needs the key; en keeps the authored English", "backed_by": "examples/app-showcase/objectstack.config.ts:192 supportedLocales ['en', 'zh-CN']; the en block of translations/index.ts has no pages entry; the new test's second case" },
        { "claim": "The i18n coverage ratchet is unchanged", "backed_by": "pnpm check:i18n-coverage exit 0, 'none new'" }
      ],
      "deviations": [
        "Scope said zh-CN title/body under the bundle key. body cannot go there (see claims), so it ships as an inline locale map on the page. The order's ruling binds the id route, and this applies it to the one key that route can carry.",
        "Added dismissKey: 'showcase_task_review' on the same node. It is a direct consequence of translating the title (see claims). Someone who dismissed the banner under the old English-title key sees it once more.",
        "packages/spec moved on the main side of the single merge (record-page.zod.ts and generated api snapshots); this diff touches no spec file. Spec check:generated was not run locally; CI's TypeScript Type Check owns it.",
        "test:repo (vitest repo project) was not run locally; Test Core in CI runs it.",
        "check:dual-build-cjs-loads NOT MEASURED locally (exit 3, prerequisite), left to CI.",
        "PR body ends with the order's line ('Generated with Claude Code' and the claude.com link) instead of os-dev's session-URL footer form. I followed the order."
      ],
      "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
      "changeset": "none. @objectstack/example-showcase is private: true, so the PR carries skip-changeset (sent with pr_create; read back on the PR).",
      "mcp_calls": "0",
      "api_writes": "2 — (1) relay dispatch POST /repos/objectstack-ai/objectstack/dispatches, carrying pr_create plus its labels leg (skip-changeset), run 41406317116 success, read-back identical, 6576 bytes; (2) this comment through post-stamped.mjs. git push of the branch is not a REST write.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: observation (read-only inference, no browser run) · reach: none measured · evidence: a survey of the 29 exported showcase pages for id-less components carrying copy on the page-component face. showcase_my_work: object-metric label/description (Open Tasks, In Review, At-Risk Projects) and page:card titles Shortcuts and Leadership View. showcase_component_gallery: 4 object-metric blocks and an element:button 'Create Task'. showcase_project_detail: record:line_items and record:related_list title 'Tasks'. Without an id none of these can take a zh-CN bundle key · dedupe words: showcase zh-CN id-less page component; my work KPI English; object-metric label translation · carrier: none · noted, not filed",
        "class: observation · reach: none measured · evidence: several element:text content strings on showcase_my_work, showcase_component_gallery, showcase_contact_form and showcase_page_variables are plain English strings. Their route is an inline locale map, not the bundle · dedupe words: showcase element:text content inline locale map · carrier: none · noted, not filed",
        "class: boundary, not (c) · reach: named producer (this card's prescription wrote body under the bundle key) · evidence: a body key under pages.NAME.components.ID is refused loudly at parse with a located unrecognized_keys error. It is not silently dropped, so it is outside class (c) · carrier: none · noted, not filed"
      ]
    }
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd

    Landed · 2026-11-02T09:07Z · PR #29104 merged as 692e0dc8b9 (reviewed head 6c6289c0c9, seat record ACCEPT on the PR). The showcase task detail review banner now renders in Chinese under zh-CN. Its title comes from the bundle at pages.showcase_task_detail.components.review_alert.title, its body from an inline locale map (the page-component copy face has no body key), and a fixed dismissKey keeps a dismissal valid in both languages. The dev also listed other id-less showcase copy, read from source only. It is noted on the PR record and will be filed once a zh-CN run confirms it. pm:dispatched is removed in this stroke.

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

Metadata

Metadata

Assignees

Labels

area:i18nThe customer's own language, across UI, metadata and notificationsdomain:devxpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions