Uh oh!
There was an error while loading. Please reload this page.
fix(examples): name form/page sections and translate headings into zh-CN (#8231) - #8514
Conversation
…-CN (#8231) For each section flagged by translation-section-name-missing, add a stable snake_case name plus a real (non-echoed) zh-CN bundle entry — 9/9 in app-crm, 12/15 in app-showcase. The remaining 3 in app-showcase (TaskViews' edit/quick, ContactViews' create) are pinned nameless as regression fixtures by packages/lint's own test suite, which is out of this PR's declared file surface; #8231 stays open for that follow-up. Extends the seed.test.ts / adds an i18n-sections.test.ts harness so a name alone (with no real translation) fails the sweep. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ARidKDYSCD56LaygrvDPnk
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
os-zhuang
commented
Aug 13, 2026
PM review — ⭐ |
Uh oh!
There was an error while loading. Please reload this page.
Part of #8231 — 21 of the 24 flagged sections are named and translated; 3 remain out of scope for the reason below. #8231 stays open for that follow-up rather than closing on this merge.
What was measured
Both example builds emitted
translation-section-name-missingon every run — aform/
record:detailssection with alabelbut nonamehas no key a bundlecan carry (
objects.{object}._sections.{name}.label), so its heading rendersin the source locale in EVERY locale, permanently, while every neighbouring
field label on the same object translates fine.
What changed
Every named section gets BOTH a stable snake_case
nameAND a real(non-echoed) zh-CN
_sectionsentry keyed by that name — naming alone wouldhave silenced the warning with zero translation delivered, which is exactly
the trap this card calls out.
app-crm (9/9 named + translated):
activity_detailsrelated_recordsnotescontact_uslead_informationqualificationconversionnotesopportunityapp-showcase (12/15 named + translated):
projectbudget_scheduleshowcase_project_detailoverviewshowcase_project_detailfinancialsshowcase_project_detailtimelineshowcase_task_detailoverviewshowcase_task_detailscheduleshowcase_task_detaildetailstell_us_about_yourselfunitshowcase_settingsappearanceshowcase_settingsnotificationsThe three
showcase_taskdetail-page sections reuse the exact names ANDzh-CN copy
ui/views/task.view.ts'stabbedform view already declares (andsystem/translations/index.tsalready translates) — no new bundle entriesneeded there, and the wording elsewhere follows the same house vocabulary
already established in the bundle (预算/排期/概览/财务信息/时间线/通知 are all
reused from existing entries, not re-minted).
Not addressed here — a
packages/**conflict, not a scope choiceThree
app-showcasesections are deliberately left unnamed:showcase_task·formViews.edit· "Task"showcase_task·formViews.quick· "Quick Edit"showcase_contact·formViews.create· "Who is this?"packages/lint/src/validate-translatable-sections.test.ts("reports bothnameless headings the shipped task container declares",
"reports the sparse create override and nothing from the named default
form") and
validate-translation-references.test.ts("still reports asection name nothing declares") import
TaskViews/ContactViewsdirectlyfrom this app and pin their current nameless state as the regression
fixture that proves the lint rule fires on real, shipped metadata. Naming any
of the three flips those pinned findings from present to absent, which needs
a coordinated
packages/linttest update —packages/**, outside thiscard's declared file surface. Verified:
packages/lint's test suite(
validate-translatable-sections.test.ts+validate-translation-references.test.ts,68 tests) still passes unmodified against this branch.
#8231 is not addressed for these 3 — it stays open as a follow-up once the
packages/lintfixture update is in scope.Verification
Reverse verification (predicted RED before running): reverted the
crm_opportunityfix to the pre-fixorigin/maincontent, watchedi18n-sections.test.tsgo red on exactly that section (and only that one),then restored from the committed fix — file byte-identical afterward
(
git statusclean).Both example test suites gained an i18n-coverage sweep
(
examples/app-crm/test/i18n-sections.test.ts,extended
examples/app-showcase/test/seed.test.ts) that asserts, for everysection it can see, BOTH that it has a
nameAND that the zh-CN bundlecarries a real, non-ASCII label for it — an echoed-English or missing entry
fails the sweep, closing the "name it and stop" vacuity trap.
Gates run
node scripts/pm/dispatch-gates.mjs(given this PR's changed paths) named:check:changeset-gate-self-tests,check:objectui-changeset,check:adr-0087-registration,check:changeset-no-major,check:empty-changeset— all green. Convention-triggered by the new testfiles:
check:query-options-erasure,check:type-check-coverage— bothgreen. On judgment:
check:nul-bytes(green),check:i18n-coverage(green,none new— the newly-named sections are translated at birth so theuntranslated-string ratchet is unmoved).
check:objectui-pin-freshis red in this environment, but it is unrelated tothis diff: it fires on any changeset's presence, not its content, and reports
the sibling
objectuicheckout's local fetch history is behind the pin'supstream —
.objectui-shaitself is untouched by this branch (last moved byan unrelated commit) and this PR touches nothing under
packages/consoleorobjectui.
Pulled and merged current
origin/mainbefore opening this PR (AGENTS.md§10); rebuilt
packages/spec's dependency closure and re-ran the fullbuild/test/typecheck/gate sweep above post-merge with identical results.
Changeset
.changeset/crm-showcase-section-name-i18n.md— patch on@objectstack/example-crmand@objectstack/example-showcase.Generated by Claude Code