Repository navigation
feat(spec): translate a settings map specifier's column headers - #31484
Conversation
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fxVwyhFFqT657pqUh
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fxVwyhFFqT657pqUh
The platform bundle's settings.<ns>.keys.<key> entry gains keyColumn and
columns.<name>, each { label, help }, spelled as the map specifier spells
its headers. The shipped bundles translate Data Lifecycle's five headers,
the coverage test holds map headers to label coverage, and the console's
map table reads the two groups.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2fxVwyhFFqT657pqUh
…wording Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fxVwyhFFqT657pqUh
|
domain:spec#4 · marchtian · session_017ihL2fxVwyhFFqT657pqUh Independent spec review (Fable, isolated subagent)Scope: the spec contract ( Round 1 (head
Round 2 (delta |
📓 Docs Drift Check4 anchor(s) derived from 2 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 173 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6ebb680482c16e4116ded5b665fea85626d8b039 && git checkout 6ebb680482c16e4116ded5b665fea85626d8b039
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin c65599fae600ab24d7cf517dfee9e33a8d132b0c 7d137518f17b648f28560b3f2d859c964cf2d176 && git checkout -B drift-repro c65599fae600ab24d7cf517dfee9e33a8d132b0c && git merge --no-ff 7d137518f17b648f28560b3f2d859c964cf2d176
node scripts/docs-audit/affected-docs.mjs --json c65599fae600ab24d7cf517dfee9e33a8d132b0c |
|
domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentHolds against cited code. Console-side overlay is right: Implemented-by: VERDICT: PASS |
Requested by 田騏 · project thread
Fixes #31453
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
keyColumn(键列)和columns.列名(各值列),各含label(表头)与help(悬停说明)。数据生命周期三张表的 5 个表头已写进 10 个非英文语言包,控制台表格读取这些翻译。settings。直接 revert 即可回滚。packages/spec/src/system/translation.zod.ts(keys条目新增keyColumn/columns与settingsMapColumnTranslation);ui/apps/console/src/pages/settings/SettingsMapField.tsx(表头读翻译);packages/services/service-settings/src/translations/settings-translation-coverage.test.ts(表头纳入逐语言覆盖校验)。pnpm --dir ui exec vitest run apps/console/src/pages/settings/__tests__/SettingsView.mapRows-31391.test.tsx -t 31453,预期 2 条通过:中文下表头显示「对象 / 行保留时长」,没翻译的列保留英文。What changes
packages/spec/src/system/translation.zod.ts). The platform bundle'ssettings.NAMESPACE.keys.KEYentry gains two optional groups, spelled as themapspecifier spells its headers:keyColumn: the key column,{ label, help };columns: a record keyed by the columnname, each{ label, help }.labeltranslates the specifier column'slabel;helptranslates itsdescription, the spelling the setting entry already uses for a specifier'sdescription. Both are built with the samestrictObject({ surface, history: TRANSLATION_HISTORY, aliases })helper as their siblings. On the setting entry,keyHeaderis answeredkeyColumnandheaders/columnLabelsare answeredcolumns. On a column,title/header/headingare answeredlabel,description/helpText/hintare answeredhelp, and a specifier column pasted in whole gets a prescription forname(it is the record key,columns.NAME) andkind(not translatable), never a rename. A bundle written before this change parses unchanged.ServedTranslationDataSchemaspreads the same shape, so the served document carries the groups with no other change.SpecifierSchema'skeyColumn/columnsTSDoc names the translation address, asconfirmOffTextdoes.@objectstack/service-settings). zh-CN, zh-Hant, ja-JP, ko, es-ES, pt-BR, fr, de, ru and ar translate the five headers oflifecycle.retention_overrides,lifecycle.quotasandlifecycle.quota_defaults(Object,Keep rows for,Expire rows after,Max rows,Lifecycle class). The coverage test holds everymapheader to the same per-locale coverage as the setting's label, and refuses header copy on a setting that is not a map or for a column the map does not declare.ui/files, named in the claim's file surface).keys.KEY.labelis overlaid in the console, byuseSettingsLabel, not on the server; the new leaves are read there too:mapKeyColumnLabel/mapKeyColumnHelp/mapColumnLabel/mapColumnHelp, handed toSettingsMapFieldasheaderText. A miss keeps the manifest's text in the page language (pickLocalized), as every other settings string does.helpis the header's hover text; the key column now shows its declareddescriptionthere too, as the value columns already did, so both declared leaves are read.Served Data Lifecycle page in zh-CN,
retention_overridesheaders (measured by the new console test against the shipped zh-CN strings):maxAgeexpireAfterTests
packages/spec/src/system/translation.test.ts,a map setting's column headers: the leaves parse on the platform face, the platform bundle and the served document; the four entry-level aliases name their targets; an undeclared leaf on a column and on the key column is refused at its path with the alias named; a bare string is refused asinvalid_typeat its path; a pasted specifier column gets thecolumns.NAMEprescription and nonamerename.settings-translation-coverage.test.ts: both new directions. Mutation check: renaming zh-CN'sexpireAfterentry toexpireAtreds bothmissing for lifecycle: key:retention_overrides.columns.expireAfterandundeclared settings copy: lifecycle.key:retention_overrides.columns.expireAt.SettingsView.mapRows-31391.test.tsx, new top-leveldescribein the existing harness: zh-CN headers and hover text through the realSettingsViewrender path, an untranslated column keeps its literal, the translated header still names the row's cells and key picker, and a one-column map reads its own key. Reverse check: withheaderTextunwired, both cases red ([ 'Object', 'Keep rows for', … ]).Acceptance notes
keyColumnas a plain string because the specifier's key column "carries onlylabel". Measured:SpecifierMapKeyColumnSchemadeclareslabelanddescription, andSpecifierMapColumnSchemadeclareslabel,description,kindandname.descriptionis user-visible text (the value columns render it as the header'stitle). So both groups are{ label, help }objects, which also leaves no string-to-object change owed later.Metadata-protocol: nonegrades every entrypatch(scripts/check-changeset-no-major.mjs), so@objectstack/specispatch, not theminorthe order suggested.noneholds becausesettingsis platform-only: both application doors refuse it by name, andauthorable-surface/does not move.settings, not a new top-level group.SpecTranslationDatain@object-ui/i18nforwardssettingsopaquely, and nothing inui/enumerates settings-key leaves exceptuseSettingsLabel, which this PR extends.@object-ui/consoletype-check is green.resolveSettings*helper ini18n-resolver.ts: that family has no in-repo caller for settings keys, and theconfirmOffTextprecedent added none.namealias, a detached TSDoc block, one loose test assertion, wording in four locales), all fixed; delta re-review PASS.Verification
dispatch-gates: 97 derived, 97 run, 0 NOT-MEASURED
All 97 derived commands exit 0 on this head's tree after
git merge origin/main. Nine first exited 3 (prerequisite: a stale specdist/, unbuilt packages, the teardown fixture commit missing from the shallow clone) and exit 0 afterturbo run build --filter=./packages/**and fetching the fixture commit.check:test-typecheckneeds a larger heap locally (NODE_OPTIONS=--max-old-space-size=12288); the debt file was not regenerated. Also:pnpm --filter @objectstack/spec check:generatedexit 0,check:doc-authoringexit 0, eslint on every touched file exit 0,@object-ui/consoletype-check exit 0, spectranslation.test.ts+src/shared1224 pass, service-settings translations 135 pass, console map/label suites 22 pass.🤖 Generated with Claude Code