Repository navigation
Commit deac7f4
i18n(platform-objects): ship the platform objects, Setup, Studio and Account in Brazilian Portuguese (#31440)
domain:server#3 · os-project-manager · session_01FEkQ5pXkgNXVpCn2GZDjyy
Body: seat final 速读 · 2026-11-08T08:25Z
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X5xwArPxERFNdAjYY2nKcc9)_
Part of #30512
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:给 `@objectstack/platform-objects` 加上巴西葡萄牙语(pt-BR):平台对象、Studio
的元数据表单、Setup/Studio/Account 导航、系统概览仪表板和用户/组织记录页的内嵌文字,做法与已合并的
fr(#31233)逐文件一致。
- 为什么改:pt-BR 是 #30512 要补的第四个语言;语言设为 pt-BR
的用户此前在主页动态里读到葡语句子夹着英文字段名(`Banned`、`Ban Reason`)。
- 风险与回滚:只新增 pt-BR 文件、注册行和测试里的语言列表,不改任何已有语言的文字(其余 21 个生成文件字节不变);新文字同样走
source-hash 回退。回滚即 revert 本 PR。
-
先看:`packages/platform-objects/src/apps/translations/pt-BR.ts`(导航钉住项),`packages/plugins/plugin-audit/src/activity-summary-pt-br-sys-user-labels.test.ts`(新守护测试),`pt-BR.metadata-forms.generated.ts`
里 `widgets.layout` 带上父名的译法(`Layout do widget`)。
- 两分钟验证:`cd packages/plugins/plugin-audit && npx vitest run
src/activity-summary-pt-br-sys-user-labels.test.ts`,预期 3
个测试通过,句子为「Atualizou Usuário "Carl Edited": Banido e Motivo do
banimento」。
- 需要你做的:请 os-zhuang 或 hotlong 批准本 PR。席位契约复审 ACCEPT 在评论
6719237445,`Head-sha: 1d1308b`。PR
含生成文件,超过 3000 行,需人工批准。批准后由席位重合 main、重跑导航 i18n 检查,然后落地。
## What changes
- New `pt-BR` bundles in
`packages/platform-objects/src/apps/translations`:
`pt-BR.objects.generated.ts` (1697 leaves),
`pt-BR.metadata-forms.generated.ts` (1263 leaves), their provenance
table `pt-BR.source-hashes.generated.ts` (88 deliberate byte copies of
`en`, listed under Acceptance notes), the hand-authored `pt-BR.ts` (141
leaves) and `pt-BR.source-hashes.ts` recording the `en` digest of every
hand leaf.
- Registration: the extract config's `--locales` docstring and
`translations:` baseline, `setup.translation.ts`, the `apps` barrel, and
`metadata-translations/index.ts`.
- Inline maps: 36 in `sys-user.page.ts`, 6 in
`sys-organization.page.ts`, and the System Overview null label in
`system.datasets.ts` (`Sistema`).
- Wording pins, as #31233 lists them: `nav_account_approvals` reads as
plugin-approvals' `my_pending` label (`Minhas aprovações pendentes`),
`nav_assignment_rules` as `sys_assignment_rule`'s plural label (`Regras
de atribuição`), each `nav_settings_*` (including
`nav_settings_access_policy`, `Política de acesso`) as its
service-settings hub title, `nav_settings_hub` as the console's
`backToHub` (`Todas as configurações`), and the four #30935 keys:
`grp_account_ai_assistant` = `Assistente de IA`; both
`nav_connect_agent` entries and `pages.connect_agent.label` = `Conectar
um assistente de IA`.
- Changeset `.changeset/30512-platform-objects-pt-br.md` (patch).
## Tests
- `pt-BR` added beside `fr` to the locale lists of every test #31233
widened (vocabulary, nav parity, dead-key tombstone, source-hash,
bu-rename, copy tests, record-page tabs, plugin translation loads), plus
plugin-approvals `approval-status-vocabulary`, plugin-security
`people-org-assignment-nav-contribution` and service-settings
`setup-nav-hub-parity`. No test listing the platform locales was added
on main since #31233. The cli `platform-page-i18n-parity` LOCALE_KEY
shape already accepts `pt-BR`.
- New
`packages/plugins/plugin-audit/src/activity-summary-pt-br-sys-user-labels.test.ts`,
the `pt-BR` twin of the #28107 `fr` test: an i18n service holding what a
booted kernel holds composes a `sys_user` update summary for a reader
whose locale is `pt-BR`, and gets `Atualizou Usuário "Carl Edited":
Banido e Motivo do banimento`; a tracked change names `Motivo do
banimento`. Ablation: with the platform `pt-BR` bundle left out of the
service, two cases fail with `Atualizou User "Carl Edited": Banned e Ban
Reason` and `Ban Reason: spam → abuse`, the English labels inside
Portuguese glue; restored, 3 of 3 pass.
## Acceptance notes
- Every leaf is translated. The 88 byte copies of `en` the extract
records are words Brazilian Portuguese uses as they are (`Status` ×8,
`Namespace` ×6, `Token` ×3, `Kanban`, `Gantt`, `Layout`, `Widget`,
`Widgets`, `Hook`, `Handler`, `Patch`, `Tags`, `Avatar`, `Slug`,
`Global`, `Manual`, `App`, `Web`, `Feeds`, `Shards`), identifiers and
header names (`ID` ×24, `API` ×2, `JWKS`, `JWKS URI`, `Message-ID`,
`Reply-To` ×2, `Cc`, `snake_case`, the SAML `urn:…:emailAddress` NameID
format, the `openid email profile` / `email` / `name` defaults),
lowercase option values that are identifiers (`marketing`, `workflow`,
`cron`, `dlq`, `manual`, `api`, `web`), and the five JSON examples kept
verbatim as every locale keeps them.
- Where a catalog test refuses an `en` echo (`repeater-row-properties`
on `dashboard:widgets.layout`), the leaf names its parent instead
(`Layout do widget`), as `fr` and `es-ES` do.
- Vocabulary follows `ui/packages/i18n` `pt-BR`: straight quotes,
`Excluir`, `Salvar`, `Painel`, `Visualização`, `Função`, `Proprietário`,
`Locatário`; Brazilian forms throughout (`você`, `arquivo`, `usuário`,
`equipe`). The job position is `Cargo`; the add-record button's
`Position` is `Posição` (the place). Adjectives agree with the noun they
qualify (`Todos`/`Todas`, `Ativos`/`Ativas`, `Revogada`, `Desativados`,
…).
- Business units are `Unidades de negócios`; no `sys_business_unit*`
label says `Departamento` (`bu-rename-consistency`).
- `pages.connect_agent.subtitle` is translated from the current `en`
text, so its digest in `pt-BR.source-hashes.ts` is current. The `fr`
table records the digest of the previous `en` subtitle, so `fr` readers
get the `en` subtitle through the fallback today; that is existing `fr`
behaviour, left alone here.
## Verification
- `os i18n extract
packages/platform-objects/scripts/i18n-extract.config.ts
--locales=zh-CN,ja-JP,es-ES,zh-Hant,ar,fr,pt-BR --fill=default
--source-hashes --out=packages/platform-objects/src/apps/translations`:
regenerates the `pt-BR` bundles byte-identical and leaves the 21 other
generated files unchanged (sha256 over all 23, before and after), both
before and after the merge of `origin/main`. `check-i18n-bundles
--filter=platform-objects`: in sync (23 bundles).
- `vitest run` in platform-objects: 120 files, 1796 tests passed.
plugin-approvals `approval-status-vocabulary` (6), plugin-security
`people-org-assignment-nav-contribution` (5), service-settings
`setup-nav-hub-parity` (17), cli `platform-page-i18n-parity` (27) and
the new plugin-audit test (3) passed.
- platform-objects `typecheck`: exit 0.
- `dispatch-gates --ran` at 1d1308b (after the second merge of
`origin/main`): 68 derived families, 68 run, 0 NOT-MEASURED, all exit 0
(including `check:i18n`, `check:i18n-stale-fill`, `check:dts-closure`,
`check:dual-build-cjs-loads`, `check:nul-bytes`).
- `eslint` over the touched packages' changed paths (`pnpm lint`
spelling, scoped): exit 0.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FEkQ5mqoYjnPaGZhS8jzcF)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4941c40 commit deac7f4
37 files changed
Lines changed: 7386 additions & 48 deletions
File tree
- .changeset
- packages
- platform-objects
- scripts
- src
- apps
- dashboards
- translations
- identity
- metadata-translations
- pages
- plugins
- plugin-approvals/src/translations
- plugin-audit/src
- plugin-security/src
- services/service-settings/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
| 227 | + | |
227 | 228 | | |
228 | 229 | | |
229 | 230 | | |
230 | 231 | | |
231 | 232 | | |
232 | 233 | | |
233 | 234 | | |
| 235 | + | |
234 | 236 | | |
235 | 237 | | |
236 | 238 | | |
| |||
256 | 258 | | |
257 | 259 | | |
258 | 260 | | |
| 261 | + | |
259 | 262 | | |
260 | 263 | | |
261 | 264 | | |
| |||
359 | 362 | | |
360 | 363 | | |
361 | 364 | | |
| 365 | + | |
362 | 366 | | |
363 | 367 | | |
364 | 368 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
58 | 60 | | |
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
62 | 64 | | |
63 | 65 | | |
64 | 66 | | |
| 67 | + | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
| |||
136 | 139 | | |
137 | 140 | | |
138 | 141 | | |
139 | | - | |
| 142 | + | |
140 | 143 | | |
141 | | - | |
| 144 | + | |
142 | 145 | | |
143 | 146 | | |
144 | 147 | | |
145 | 148 | | |
146 | 149 | | |
147 | 150 | | |
| 151 | + | |
148 | 152 | | |
149 | 153 | | |
150 | 154 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | | - | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
116 | 117 | | |
117 | 118 | | |
118 | | - | |
| 119 | + | |
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| 64 | + | |
64 | 65 | | |
65 | | - | |
| 66 | + | |
66 | 67 | | |
67 | 68 | | |
68 | 69 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| 30 | + | |
29 | 31 | | |
30 | 32 | | |
31 | 33 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| |||
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| 40 | + | |
39 | 41 | | |
40 | 42 | | |
41 | 43 | | |
| |||
0 commit comments