Repository navigation
Commit bdbaf80
fix: Setup form help speaks to an administrator; queue pages, mail status banner and test toast read in Chinese (#30551)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgAb97yDcvm73kZUzyhhNWsN)_
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE
Refs #30208 (rows 1, 2, 3, 7, 8)
Clause-②: yes (widening)
Metadata-protocol: none
Skills-docs: none — `git grep -n -I -E "fail-closed at
resolution|half-open \[from, until\)|graph semantics|root of tenant|HRIS
sync|upstream HRIS|expanded by graph|When true, every member|When true,
the user|task/run attribution|No mail leaves this machine|Sent test
email" -- skills` on `e205cf31` answers 0 lines; no published skill
sentence quotes the replaced help or the mail status text.
## 维护者速读
- 改了什么:Setup 里「新建权限集分配 /
岗位分配」「外出委派规则」「新建业务单元」「编辑组织」「用户」表单的字段说明改成管理员能看懂的话(去掉
fail-closed、半开区间、图谱、Null、HRIS、「为 true
时」等,改为「开启后…」);「队列」「队列成员」两页补上中文;「邮件投递」顶部状态横幅和「发送测试邮件」的提示在中文界面下显示中文。
- 为什么改:真实用户走查 Setup
时,这些说明在描述实现而不是告诉管理员该填什么;队列两页整页英文(按钮显示「新建Queue」);邮件页横幅和测试提示是英文。
- 风险与回滚:只改服务端下发的文字,不改任何字段名、选项值或行为;唯一的接口变化是设置动作处理函数多收一个可选的
`locale`,已有处理函数不受影响。回滚即 revert 本 PR。
-
先看:`packages/plugins/plugin-email/src/live-transport-status.ts`(中英文案表与按语言取文案),`packages/services/service-settings/src/settings-routes.ts`
与 `settings-service.ts` 的
`runAction`(动作路由把请求语言交给处理函数),`packages/plugins/plugin-sharing/scripts/i18n-extract.config.ts`(队列两个对象进翻译包)。
- 两分钟验证:`pnpm --filter @objectstack/plugin-email exec vitest run
src/mail-log-provider.pin.test.ts`,预期 13 条全过,其中 5 条是中文横幅与测试提示。
- 需要你做的:无,席位落地。
## What changes
**Rows 1–3: field help in administrator wording (English source and
zh-CN).** Text only; no field name, key, option value or behaviour
moves.
| Form | Field | Before (zh-CN) | After (zh-CN) |
| --- | --- | --- | --- |
| 权限集分配 / 岗位分配 | `valid_from` | 在解析时以 fail-closed 方式强制执行 |
到时即生效,无需等待任何定时任务 |
| 权限集分配 / 岗位分配 | `valid_until` | 半开区间 [from, until),UTC;智能体授权必填 |
到此时间即失效(按 UTC 计);授予 AI 智能体的分配必须填写 |
| 权限集分配 | `reason` | 智能体授权在此记录任务/运行归属 | 授予 AI 智能体时,请写明它为哪项任务获得授权 |
| 审批委派 | `valid_until` | 半开区间 [from, until) | 规则到此时间即失效(按 UTC 计) |
| 业务单元 | `kind` | 不会改变图谱语义 | 仅用于分类和报表,不会改变该单元在组织中的位置和覆盖范围 |
| 业务单元 | `parent_business_unit_id` | Null 表示租户根节点 | 留空表示顶级单元 |
| 业务单元 | `active` | 为 false 时,图谱查询不会展开该业务单元成员 |
关闭后即停用该单元:授予该单元或其上级单元的共享等访问权限,将不再覆盖其成员及下级单元 |
| 业务单元 | `effective_from` / `effective_to` / `external_ref` | HRIS 同步 /
上游 HRIS | 通常由 HR 系统同步填写 / 在 HR 系统中的编号 |
| 组织 | `require_mfa` | 为 true 时 | 开启后 |
| 用户 | `banned`, `must_change_password` | 为 true 时;403
PASSWORD_RESET_REQUIRED | 开启后;用户必须先修改密码才能继续使用 |
The English sources (`*.object.ts`) say the same in English;
`en.*.generated.ts` follow by extract. The `active` sentence states what
`BusinessUnitGraphService` does with an inactive unit (contributes no
members and stops the descent into its subtree,
`plugin-sharing/src/business-unit-graph.ts`); `must_change_password`
names the admin create, import and reset paths that set it
(`plugin-auth` `admin-user-endpoints.ts`, `admin-import-users.ts`).
**Row 7: the 队列 and 队列成员 pages.** `plugin-sharing`'s extract config now
lists `SysQueue` and `SysQueueMember` beside its three sharing objects
(the `bundle-ownership` list follows). The extract added both objects to
every bundle; zh-CN is written by hand (队列 / 队列成员, every field, help,
the member-type options and the two list-view names). ja-JP and es-ES
carry the extract's English fill, except the member-type options, which
reuse the renderings `sys_record_share` / `sys_sharing_rule` already use
in those bundles (the package's `recipient-vocabulary-consistency` pin
requires one rendering per option key).
**Row 8: Setup → Email.**
- `plugin-email`: `describeLiveMailTransport(source, locale?)` writes
the banner from a per-language copy table (`MAIL_DELIVERY_COPY`, en and
zh-CN; `mailDeliveryCopy` resolves exact, then by language, else
English), the mechanism `service-settings`' currency lock already uses
for its live status. The plugin's live-status provider passes the
`locale` the settings service already hands it. The `mail/test` handler
writes its sent, failed and log-only answers from the same table.
- `service-settings`: `SettingsActionHandler`'s input gains an optional
`locale`; `runAction(namespace, actionId, payload, ctx, display?)`
passes `display.locale` to the handler; the POST action route passes
`requestLocaleOf(req)`, the same reading the GET route gives the live
status. The locale stays out of `ctx`. An existing handler compiles and
behaves unchanged.
## Tests
One pin file per row, plus a route pin:
- `plugin-security/src/translations/assignment-help-wording.test.ts`:
served zh-CN (`SecurityTranslations`) and the English source of
`valid_from` / `valid_until` / `reason` on both assignment objects carry
no `fail-closed`, interval notation or `agent grants` / 智能体授权, and the
zh-CN help is Chinese.
- `plugin-approvals/src/translations/delegation-window-wording.test.ts`:
`sys_approval_delegation.valid_until`, same shape.
- `platform-objects/src/identity/setup-form-admin-wording.test.ts`:
served zh-CN (`SetupAppTranslations`) and the English source of the nine
business unit, organization and user fields carry no graph vocabulary,
null literal, `HRIS`, boolean literal or HTTP status code.
- `plugin-sharing/src/translations/queue-pages-zh-cn.test.ts`: the
served zh-CN bundle names 队列 / 队列成员 and translates every field label,
help and member-type option.
- `plugin-email/src/mail-log-provider.pin.test.ts` (the existing Setup →
Email harness, new top-level `describe`): zh-CN banner for the
out-of-the-box and the delivering transport, the zh-CN test toast, the
zh-CN log-only warning, and a control (`fr-FR` answers English).
- `service-settings/src/settings-routes.test.ts`: the POST action route
hands the handler `zh-CN` from `Accept-Language`, `undefined` without
one, and not in `ctx`.
Red on `main` (the pin commit `0f390750`, before the fix): security 10
failed / 2 passed, approvals 2/2 failed, platform-objects 18/18 failed,
sharing 4/4 failed, email 4 failed / 9 passed (the control passed),
settings routes 1 failed / 34 passed.
Ablation (once, `scripts/ablation-replace.mjs`, anchor hit x1, restored
blob equals HEAD, `git diff HEAD` empty): with the live-status provider
calling `describeLiveMailTransport(this.service)` again (the locale
dropped), exactly the two zh-CN statement pins go red, 2 failed / 11
passed.
## Acceptance notes
- **No closing keyword:** the dispatch's How section spells a closing
line, its rulings say `Refs`; this PR follows the rulings, so merging
leaves the card open for rows 5 and 6 (row 5 needs a settings shape; row
6 waits on the maintainer).
- **ja-JP and es-ES are not re-translated here.** Their leaves for the
help changed in rows 1–3 still translate the old English source (for
example es-ES `valid_from` still says "modo fail-closed"); they are
legacy-trusted (no provenance record), so they keep serving that text.
The queue objects arrive there as English fills, recorded in each
locale's `source-hashes` file. The seat's serial note puts those two
languages with the pending seven-language pass on these packages.
- **Mail copy is en and zh-CN.** ja-JP and es-ES callers get the English
banner and toast, as before. The test handler's input refusals (`SMTP
host is required — nothing was sent.`, `api_key is required`, an
unsupported provider, a transport that cannot be built) stay English;
only the sent, failed and log-only answers moved.
- **Not touched, same class, outside these rows' forms:** `sys_setting`
/ `sys_platform_setting` `encrypted` and `locked` help still say 「为 true
时」 (an internal store, not a Setup form);
`sys_user_position.business_unit_id` help names `readScope/writeScope`.
- `mail.manifest.ts` (`plugin-email` and `service-settings`) is not
touched (another lane's card edits it).
- **`require_mfa` and PR #30529:** that open PR (another seat's card on
the same field) rewrites this help to add that the requirement needs
two-factor on for the deployment, keeping "When true". This PR's help
keeps that sentence beside the administrator wording, in English and
zh-CN, so whichever lands second resolves the textual conflict by taking
this text; #30529's pins (`two-factor authentication on for this
deployment`, `OS_AUTH_TWO_FACTOR=true` in every locale) hold against it.
ja-JP and es-ES for that field are #30529's.
## Verification
<details><summary>Package suites and typechecks (head e205cf3; the
later main merge brought one ui-only commit)</summary>
- `pnpm --filter @objectstack/PKG test` and `typecheck` for
service-settings, platform-objects, plugin-security, plugin-approvals,
plugin-sharing, plugin-email: all exit 0 under the verify lock (VERDICT
command-exit 0). plugin-sharing 66 files / 1409 tests after the ja-JP /
es-ES option fix.
- `pnpm check:i18n`: all ten bundle sets in sync. `pnpm i18n:extract`:
byte-identical.
- `eslint --no-inline-config` on the changed TypeScript files: exit 0.
`pnpm lint` (repository-wide) on `7e4a3272`: exit 0.
</details>
<details><summary>Derived gate families</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on `f63ad0b2` (after the `origin/main`
merge) derived 66 commands over 32 changed paths. Each ran with its exit
code captured before any pipe; `--ran`: 66 derived, 65 run, 1
NOT-MEASURED, 0 UNRUN.
- 64 exited 0 on the first pass.
- `pnpm check:dual-build-cjs-loads`: exit 3, PREREQUISITE NOT MET (it
reads every package's `dist`, and only this card's closure was built).
NOT MEASURED here; CI's `Lint & Repo Gates` runs it.
- `pnpm check:i18n-stale-fill`: exit 1 on the first pass. It found
`sys_approval_delegation.valid_until.help` in ja-JP and es-ES still
holding the byte-identical English fill of the old source. Both now
carry the fill of the new source (recorded by the extract), and the gate
exits 0 on `07d639c3` and on the final head.
After the union two small commits landed: `07d639c3` (those two fills)
and `7e4a3272` (`require_mfa` help, see Acceptance notes). The
changed-path set grew from 32 to 36 paths; the derived gate family did
not move (the same 66 commands). Re-run on `7e4a3272`: `pnpm check:i18n`
exit 0, `pnpm check:i18n-stale-fill` exit 0, `pnpm i18n:extract`
byte-identical, `pnpm --filter @objectstack/platform-objects test` 112
files / 1544 tests, `pnpm --filter @objectstack/plugin-approvals test`
(on `07d639c3`) 112 files / 1471 tests.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CbDNK83SuSb8zsRt2s)_
<!-- signed: domain:server#6 · os-bill ·
session_01Utp6CXCS98uhsFQYk64epE -->
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0e4747a commit bdbaf80
36 files changed
Lines changed: 766 additions & 107 deletions
File tree
- .changeset
- packages
- platform-objects/src
- apps/translations
- identity
- plugins
- plugin-approvals/src
- translations
- plugin-email/src
- plugin-security/src
- objects
- translations
- plugin-sharing
- scripts
- src/translations
- services/service-settings/src
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| |||
557 | 557 | | |
558 | 558 | | |
559 | 559 | | |
560 | | - | |
| 560 | + | |
561 | 561 | | |
562 | 562 | | |
563 | 563 | | |
| |||
995 | 995 | | |
996 | 996 | | |
997 | 997 | | |
998 | | - | |
| 998 | + | |
999 | 999 | | |
1000 | 1000 | | |
1001 | 1001 | | |
| |||
1006 | 1006 | | |
1007 | 1007 | | |
1008 | 1008 | | |
1009 | | - | |
| 1009 | + | |
1010 | 1010 | | |
1011 | 1011 | | |
1012 | 1012 | | |
| |||
1022 | 1022 | | |
1023 | 1023 | | |
1024 | 1024 | | |
1025 | | - | |
| 1025 | + | |
1026 | 1026 | | |
1027 | 1027 | | |
1028 | 1028 | | |
1029 | | - | |
| 1029 | + | |
1030 | 1030 | | |
1031 | 1031 | | |
1032 | 1032 | | |
1033 | | - | |
| 1033 | + | |
1034 | 1034 | | |
1035 | 1035 | | |
1036 | 1036 | | |
1037 | | - | |
| 1037 | + | |
1038 | 1038 | | |
1039 | 1039 | | |
1040 | 1040 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| |||
557 | 557 | | |
558 | 558 | | |
559 | 559 | | |
560 | | - | |
| 560 | + | |
561 | 561 | | |
562 | 562 | | |
563 | 563 | | |
| |||
995 | 995 | | |
996 | 996 | | |
997 | 997 | | |
998 | | - | |
| 998 | + | |
999 | 999 | | |
1000 | 1000 | | |
1001 | 1001 | | |
| |||
1006 | 1006 | | |
1007 | 1007 | | |
1008 | 1008 | | |
1009 | | - | |
| 1009 | + | |
1010 | 1010 | | |
1011 | 1011 | | |
1012 | 1012 | | |
| |||
1022 | 1022 | | |
1023 | 1023 | | |
1024 | 1024 | | |
1025 | | - | |
| 1025 | + | |
1026 | 1026 | | |
1027 | 1027 | | |
1028 | 1028 | | |
1029 | | - | |
| 1029 | + | |
1030 | 1030 | | |
1031 | 1031 | | |
1032 | 1032 | | |
1033 | | - | |
| 1033 | + | |
1034 | 1034 | | |
1035 | 1035 | | |
1036 | 1036 | | |
1037 | | - | |
| 1037 | + | |
1038 | 1038 | | |
1039 | 1039 | | |
1040 | 1040 | | |
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
| 124 | + | |
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | | - | |
| 148 | + | |
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| |||
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
227 | | - | |
| 227 | + | |
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
233 | 233 | | |
234 | | - | |
| 234 | + | |
235 | 235 | | |
236 | 236 | | |
237 | 237 | | |
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
241 | | - | |
| 241 | + | |
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
248 | 248 | | |
249 | | - | |
| 249 | + | |
250 | 250 | | |
251 | 251 | | |
252 | 252 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
404 | 404 | | |
405 | 405 | | |
406 | 406 | | |
407 | | - | |
| 407 | + | |
408 | 408 | | |
409 | | - | |
| 409 | + | |
410 | 410 | | |
411 | 411 | | |
412 | 412 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
981 | 981 | | |
982 | 982 | | |
983 | 983 | | |
984 | | - | |
| 984 | + | |
985 | 985 | | |
986 | 986 | | |
987 | 987 | | |
| |||
1085 | 1085 | | |
1086 | 1086 | | |
1087 | 1087 | | |
1088 | | - | |
1089 | | - | |
| 1088 | + | |
| 1089 | + | |
1090 | 1090 | | |
1091 | 1091 | | |
1092 | 1092 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
140 | | - | |
| 140 | + | |
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
366 | 366 | | |
367 | 367 | | |
368 | 368 | | |
369 | | - | |
| 369 | + | |
370 | 370 | | |
371 | 371 | | |
372 | 372 | | |
| |||
0 commit comments