Repository navigation
Commit fb91e97
fix(plugin-security): translate the built-in positions under zh-CN, ja-JP and es-ES (#26606)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1XMLTWJMvQQWZ5RaZFnBdwkB)_
Fixes #26562
Clause-②: no
Metadata-protocol: none
## 维护者速读
-
**改了什么**:平台内置的七个岗位(平台管理员、组织所有者、组织管理员、组织成员、组织外部成员、全体成员、访客)在中文、日文、西班牙文界面下,名称和说明都按当前语言显示。
- **为什么改**:设置 →
岗位在中文界面下,应用自己的岗位已是中文,平台内置的七个仍是英文,其中包括每条授权都要参照的「全体成员」「访客」。内置权限集早已翻译,岗位漏掉了。
- **风险与回滚**:低。只新增翻译包里的 `positions` 组,英文、岗位本身的定义与授权都不变;回滚即 revert 本 PR。
-
**先看**:`packages/plugins/plugin-security/src/translations/builtin-positions.ts`(三种语言的译文);`translations/index.ts`(三行接入);`translations/builtin-positions.test.ts`。
- **两分钟验证**:`pnpm --filter @objectstack/plugin-security exec vitest run
src/translations/builtin-positions.test.ts`,预期 29/29 通过;或中文界面打开 设置 →
岗位,内置七项显示中文。
- **需要你做的**:无,席位落地。
## What changes
- New
`packages/plugins/plugin-security/src/translations/builtin-positions.ts`:
hand-authored `positions.NAME.label` / `.description` for the seven
built-in positions (`platform_admin`, `org_owner`, `org_admin`,
`org_member`, `org_external`, `everyone`, `guest`) in zh-CN, ja-JP and
es-ES, the locales the built-in permission-set group
(`permission-sets.ts`) covers. Hand-authored for the reason that file
gives: this package's extract runs objects-only, so `os i18n extract`
writes no `positions` group. English needs no entry (an untranslated
locale serves the declaration's own text). Terms follow this bundle's
objects: 岗位 / ポジション / puesto.
- `translations/index.ts`: each translated locale of
`SecurityTranslations` gains `positions` beside `permissions`, outside
`withSourceFallback`'s inputs exactly like the permission-set group
(`enSource` carries neither, so nothing is judged stale).
- New `translations/builtin-positions.test.ts`: per locale, the group
translates exactly the declared built-ins, no two labels repeat, each
label and description is a non-English string naming no machine id, and
`translateMetadataDocument('position', declaration,
SecurityTranslations, { locale })` serves that locale's label and
description with nothing else of the position changed.
- Changeset: `@objectstack/plugin-security` patch.
No `packages/spec/**` change.
## Why
Card #26562 (triage 6437681727, p2): under zh-CN, Setup → Positions
(`/_console/apps/setup/metadata/position`) listed the app's positions in
Chinese and the platform's seven in English.
Reader measured before writing the bundle: the page reads `GET
/api/v1/meta/position`, whose list read (`translateMetaList` in
`packages/rest/src/meta-item-read-gate.ts`) runs
`translateMetadataDocument('position', …)` with the i18n service's
merged bundle; that dispatches to `translatePosition`
(`packages/spec/src/system/i18n-resolver.ts`), which reads
`positions.NAME.label` / `.description`. `SecurityPlugin` loads
`SecurityTranslations` into that service at `kernel:ready`. So the
reader existed and the bundle was missing, as the card says. The
built-ins reach the door as registry declarations
(`builtin-positions.ts`, `registerBuiltinPositions`), keyed by `name`,
which is what the group keys on.
## Tests
Red first on `main` (`a14f3e61`): the new test, before the bundle was
added: `Tests 27 failed | 2 passed (29)` (every per-locale case; the two
population checks pass). On the fix: `Tests 29 passed (29)`.
<details><summary>Package suite and typecheck at the fix</summary>
`pnpm --filter @objectstack/plugin-security build && … typecheck && …
test` under the verify lock: `VERDICT command-exit 0`; `Test Files 230
passed (230)`, `Tests 4991 passed | 45 skipped (5036)`.
Lint: `eslint packages/plugins/plugin-security --no-inline-config` exit
0.
</details>
## Acceptance notes
- `everyone` reads 全体成员 / 全メンバー / Todos, since the description says
every authenticated member holds it; `guest` reads 访客 / ゲスト / Invitado.
- zh-CN `org_admin` (组织管理员) shares its text with the
`organization_admin` permission set's label. They are on different pages
and name the same people, so it is left as is.
- A live probe was not run: the served overlay is proven in-process
through the same `translateMetadataDocument` the REST door calls.
## Verification
Head `352780c3` (the gate loop started on `65852aec`, the same tree
before a commit-message reword; `git diff 65852aec 352780c` is empty).
`node scripts/pm/dispatch-gates.mjs --ran FILE --repo
objectstack-ai/objectstack`: `61 derived famil(ies) accounted for — 61
run, 0 NOT-MEASURED`.
Three families first answered exit 3 (prerequisite, nothing measured)
and were re-run after their prerequisite, each exit 0:
`check-plugin-teardown-shape.mjs --self-test` after `git fetch
--unshallow origin main` (48 cases pass); `check:i18n` and
`check:dual-build-cjs-loads` after a full `turbo run build` (VERDICT
command-exit 0): `check-i18n-bundles: OK (10 package(s) — all bundles in
sync, no undeclared authoring keys)`.
`test:repo` not run locally (the diff touches no repo-project test); CI
Test Core runs it. No dogfood battery: no `!` in the title and no
`(narrowing)` arm.
<details><summary>Every derived family and its exit code</summary>
```
node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0
node scripts/check-tenant-audit-census.mjs :: exit 0
node scripts/check-tenant-audit-census.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm check:changeset-gate-self-tests :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:i18n :: exit 0
pnpm check:i18n-stale-fill :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:pm-changeset-deadline-census :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
```
</details>
Co-authored-by: Claude <noreply@anthropic.com>1 parent ce9bc10 commit fb91e97
4 files changed
Lines changed: 207 additions & 4 deletions
File tree
- .changeset
- packages/plugins/plugin-security/src/translations
| 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 | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
57 | 59 | | |
58 | 60 | | |
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
62 | 64 | | |
| 65 | + | |
63 | 66 | | |
64 | 67 | | |
65 | 68 | | |
66 | 69 | | |
| 70 | + | |
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
70 | 74 | | |
| 75 | + | |
71 | 76 | | |
72 | 77 | | |
0 commit comments