Skip to content

按平台正式写法补 zh-CN 翻译包(os i18n extract 生成),消除中文界面下的英文对象名与列头 #24

Description

@baozhoutao

背景

界面上对象名与部分字段名显示英文(Assessment Plan、Plan Name、Period Type、Status、Entry Sheet、Final Score 等),用户已选中文仍然如此。成因(2026-09-03 复核):应用元数据标签直接用中文书写,只随附一个 en 翻译包、没有 zh-CN 翻译包;平台运行时查标签走「zh-CN 包 → en 包 → 元数据原文」,zh-CN 包没有 kpi 对象词条,于是凡 en 包覆盖的标签一律英文。平台的 os i18n check 又把中文原文算作默认语言已覆盖,工具与运行时口径不一致,已上报 objectstack-ai/objectstack#14882 待裁定。

平台文档(objectstack-i18n skill)的正式写法是每个支持的语言各带一个翻译包,默认语言的包由 os i18n extract 从元数据标签生成。本单按正式写法整改,不等平台。

范围

  1. 用 os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations 生成 zh-CN 包(dry-run 结果:1290 个词条,全部由元数据中文标签自动填充,不需要人工翻译),按平台生成文件的约定落在 src/translations/(生成文件名保留工具默认,如 zh-CN.objects.generated.ts)。
  2. 在 src/translations/index.ts 注册 'zh-CN' 包;en 包原样保留。
  3. CLAUDE.md「项目约定」中「用户可见文案默认中文(对象/字段 label 直接中文;zh-CN 翻译包只补 en 回退)」一句改为正式写法:label 直接中文,zh-CN 包由 os i18n extract 生成并随元数据改动重新生成,en 包补英文回退。只改这一句。
  4. package.json 增加脚本 i18n:extract(生成命令)与在 verify 中加入 objectstack i18n extract --check(平台文档的新鲜度门禁,保证标签改了包也跟着改);若 --check 在本仓库不可用,如实记录并只加生成脚本。

不做

不改任何对象/字段的 label 文案;不改 en 包内容;不动 src/data/、scripts/、README、docs/;不修改平台包。

验收标准

  1. curl -H "Accept-Language: zh-CN" /api/v1/meta/object/kpi_entry_sheet 返回 label = 填报单、fields.name = 填报单名称、fields.status = 状态、fields.total_score = 最终得分;/api/v1/meta/app/kpi_app 返回「KPI 考核管理」。
  2. Accept-Language: en 请求仍返回 Entry Sheet / Sheet / Status / Final Score(en 包不受影响)。
  3. 浏览器(中文)下:方案版本列表、填报单列表与详情、指标库详情的对象名、列头、相关列表标题全部中文;填报明细相关列表不再出现「指标 / Indicator」两列并存(应为「指标 / 指标名称」)。截图前后对比 ≥ 4 张。
  4. pnpm verify 绿;os i18n check 默认语言零错误;新增的新鲜度门禁通过。
  5. 生成文件只由工具产出,PR 中不得手改词条;评审能用 os i18n extract --check 或重跑生成对账。

测试计划草稿

T1 生成前后 diff 只含生成文件、index.ts、CLAUDE.md、package.json | T2 API zh-CN 标签断言(验收 1) | T3 API en 标签断言(验收 2) | T4 UI 四个页面截图对比 | T5 pnpm verify + i18n check + extract --check

依赖与风险

Activity

  1. self-assigned this
    on Sep 3, 2026
  2. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    认领(调度员占坑,2026-09-03)

    • 会话:local_0e65d2bc-719b-4314-aae2-351176a17e5f(派发 | 软件公司岗位KPI数据集+全流程实测 | 0903,同批第 2 项)
    • 分支:issue-24-i18n-zh-bundle,基线 main @ 4a02994d837bcc4641555520a4da0a95f1cc8bed
    • 环境分配:worktree ../kpi-issue-24-i18n-zh-bundle,dev 端口 3112,数据库 file:./.objectstack/issue-24.db
    • 执行方式:按 os-project-pm-dispatch 派发独立开发子 agent(Opus);调度员只做收单核实与评审闸门,不写代码。
  3. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    需求理解与实现方式(#24 开工确认)

    会话:开发子 agent(Claude Code),分支 issue-24-i18n-zh-bundle,worktree 独立实例(端口 3112 / 库 .objectstack/issue-24.db),基线 main @ 4a02994。

    需求理解

    界面英文的根因不是「翻译写错」,而是缺 zh-CN 翻译包:元数据 label 本身是中文,但仓库只注册了 en 包;平台运行时按「zh-CN 包 → en 包 → 元数据原文」查标签,zh-CN 包不存在 → 凡 en 包覆盖到的键一律落到英文。本单按平台文档的正式写法整改:每个支持语言各带一个翻译包,默认语言(zh-CN)的包由 os i18n extract 从元数据标签生成,不手写词条、不改 label 文案、不改 en 包。

    实现方式(方案分级:低风险)

    项 内容
    改动面 新增 src/translations/zh-CN.*.generated.ts(工具产出)+ 改 src/translations/index.ts 注册 + package.json 加脚本/门禁 + CLAUDE.md 改指定一句
    路径 唯一——平台文档 objectstack-i18n 的标准做法,无自研机制
    是否改已有逻辑 否;不动对象/视图/hook/lib,不改任何 label 文案,不动 en 包
    回滚 删生成文件 + 还原 index.ts 即回到现状

    分级结论:低风险(纯新增 + 注册,路径唯一),可直接开工。

    一处需要说明的偏差(已按验收标准取值,提请复核)

    正文「范围 §1」给出的命令是 os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations;该命令的 --objects-only 是平台默认开启的,只产出 objects / globalActions 子树,不含 apps / dashboards / pages / flows。而「验收标准 §1」明确要求 /api/v1/meta/app/kpi_app 返回「KPI 考核管理」——app 标签正是被 en 包(apps.kpi_app.label = 'KPI Assessment')覆盖的键,不含 apps 的 zh-CN 包救不回来。

    因此实际执行命令加 --no-objects-only(平台文档 objectstack-i18n「Extract Skeletons from Metadata」对此有明确警示:默认 objects-only 会让 app/navigation/dashboard/page/flow 键漏掉、而 os i18n check 仍要求它们)。仍然是纯工具产出、零手改词条,只是覆盖面按验收标准取全。若 PM 认为应严格照正文命令执行(接受 app 名保持英文),请在本单回复,我改回并把验收 §1 的 app 断言标为未实现。

    测试计划(按正文草稿执行)

    T1 diff 面核对 · T2 zh-CN API 标签断言 · T3 en API 对照断言 · T4 UI 四页面前后截图对比(≥4 张) · T5 pnpm verify + os i18n check + extract --check 新鲜度门禁。

  4. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    需求符合度清单(#24,提 PR 前门禁)

    分支 issue-24-i18n-zh-bundle @ 312cb7a。逐条对照工作项正文,三态标注,无「基本实现 / 大致完成」类含糊词。

    范围

    # 需求条目(正文原文) 态 说明
    范围1 用 os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations 生成 zh-CN 包,落在 src/translations/,文件名保留工具默认 ⚠️ 有偏差 见下「偏差 1」。实际命令为 objectstack i18n extract --locales=zh-CN --no-metadata-forms --no-objects-only --filter=kpi_ --out=src/translations;文件名保留工具默认 zh-CN.objects.generated.ts,529 词条,全部由元数据中文 label 自动填充,零人工翻译、零手改
    范围2 在 src/translations/index.ts 注册 'zh-CN' 包;en 包原样保留 ✅ 完整实现 KpiTranslationBundle 首项加 'zh-CN': zhCNTranslations;en 包对象内容一字未改(diff 仅新增 import + 注册行 + 注释块)
    范围3 CLAUDE.md 翻译包那一句改为正式写法,只改这一句 ✅ 完整实现 只动了「用户可见文案默认中文…」这一条,改为「label 直接写中文;zh-CN 包由 os i18n extract 生成、随元数据改动重新生成、禁止手改词条;en 包手工维护英文回退」。std-copy 四条红线原文保留
    范围4 package.json 增加 i18n:extract;verify 中加入 extract --check;若 --check 不可用则如实记录 ✅ 完整实现 --check 在本仓库可用。新增 i18n:extract(生成)与 i18n:extract:check(新鲜度门禁),verify 改为 validate && typecheck && test && i18n:extract:check

    不做(负向核对)

    条目 态 证据
    不改任何对象/字段 label 文案 ✅ diff 未触及 src/objects/
    不改 en 包内容 ✅ index.ts 内 en 对象字面量逐字节未变
    不动 src/data/、scripts/、README、docs/ ✅ 全量改动仅 4 个文件:CLAUDE.md、package.json、src/translations/index.ts、src/translations/zh-CN.objects.generated.ts(新增)
    不修改平台包 ✅ 未触碰 node_modules

    验收标准

    # 验收标准 态 证据
    验收1 Accept-Language: zh-CN 下 kpi_entry_sheet 的 label=填报单、fields.name=填报单名称、fields.status=状态、fields.total_score=最终得分;kpi_app=KPI 考核管理 ✅ 完整实现 五项逐字命中,测试报告 T2
    验收2 Accept-Language: en 仍返回 Entry Sheet / Sheet / Status / Final Score ✅ 完整实现 四项逐字命中,测试报告 T3;UI 对照图 13
    验收3 中文浏览器下方案版本列表、填报单列表与详情、指标库详情的对象名/列头/相关列表标题全部中文;填报明细相关列表不再「指标 / Indicator」并存(应为「指标 / 指标名称」);截图前后对比 ≥ 4 张 ✅ 完整实现 6 组前后对比 + 1 张英文对照,共 13 张,测试报告 T4
    验收4 pnpm verify 绿;os i18n check 默认语言零错误;新增的新鲜度门禁通过 ✅ 完整实现 测试报告 T5;zh-CN 覆盖率 100.0%(1290/1290,missing 0)
    验收5 生成文件只由工具产出,PR 中不得手改词条;评审能用 extract --check 或重跑生成对账 ✅ 完整实现 pnpm i18n:extract:check 报 in sync;负向测试:人为改脏一个词条后门禁报 out of date 并以退出码 1 失败

    ⚠️ 偏差 1(唯一一处):生成命令多了 --no-objects-only --filter=kpi_

    差异是什么:正文范围 §1 的命令未带这两个开关,实际执行带了。

    为什么:

    1. --objects-only 是平台默认开启的,只产出 objects / globalActions 子树,不含 apps。而验收标准 §1 明确要求 /api/v1/meta/app/kpi_app 返回「KPI 考核管理」——应用名正是被 en 包(apps.kpi_app.label = 'KPI Assessment')覆盖的键,不含 apps 的 zh-CN 包救不回来。范围 §1 的字面命令与验收 §1 互相矛盾,本单按验收标准取值。 平台文档(objectstack-i18n)对此有明确警示:默认 objects-only 会漏掉 app/navigation/dashboard/page/flow 键。
    2. 加上 --no-objects-only 后发现:即便同时传 --no-metadata-forms,工具仍把平台 Studio 的 metadataForms 基线(761 个词条,内容是英文)内联进同一个文件。把这份英文基线挂在本应用的 zh-CN 包里分发,会让 Studio 元数据表单在中文下变英文,且这份基线按平台文档「属于一个包,不属于每个插件」。--filter=kpi_ 把范围收在本应用自有的 objects/apps/dashboards/pages 上。
    3. --filter=kpi_ 不造成任何内容损失:带与不带 filter 的两份产物做过逐行 diff,差异有且仅有 metadataForms 整块(1660 行),objects / apps / dashboards / pages 四段逐字节相同。

    仍然守住的红线:词条 100% 工具产出、零手改;命令原样写进 package.json 的 i18n:extract,评审重跑即可对账;新鲜度门禁用的是同一条命令加 --check。

    若 PM 认为应严格照正文字面命令执行(接受应用名保持英文、且接受把平台英文基线打进包里),请回复,我改回并把验收 §1 的 app 断言改标 ❌。

    三出口条款

    无 ❌ 条目;唯一 ⚠️ 条目为实现口径与正文字面命令的取舍,已在上方完整披露差异与理由,并给出改回选项,不属于静默降级。未使用「退回细化 / 挂起 / 失败升级」三出口。

  5. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    测试报告 — #24 zh-CN 翻译包(开发自测)

    项 值
    工作项 #24
    分支 / 提交 issue-24-i18n-zh-bundle @ 312cb7a
    基线 main @ 4a02994
    测试环境 worktree kpi-issue-24-i18n-zh-bundle,OS_PORT=3112,OS_DATABASE_URL=file:./.objectstack/issue-24.db,改动后 rm -rf dist 重启
    账号 admin@objectos.ai / admin123
    数据 演示种子 + node scripts/e2e-flow.mjs 建链(73 PASS / 0 FAIL),提供填报单与填报明细
    执行档位 同会话自测(项目启用清单 H2:暂不具备双实例条件)。为对抗确认偏误,「前」态在改代码之前、同一实例上先行采集并落盘,「后」态复用同一库同一记录 ID,前后可逐图对位
    证据 孤儿分支 acceptance-evidence @ 8c584f20de742d6d6c35c5cb8b6be53aa38168d9,目录 issue-24/

    说明:acceptance-evidence 分支此前在远端不存在(派发说明称已存在),本次按项目约定 E2 新建为孤儿分支。


    T1 改动面 diff 核对 — ✅ 通过

    git show --stat 312cb7a 全量改动 4 个文件,与工作项范围完全一致,零越界:

     CLAUDE.md                                  |    4 +-
     package.json                               |    4 +-
     src/translations/index.ts                  |    9 +-
     src/translations/zh-CN.objects.generated.ts | 1364 +++++++++++++++++ (新增)
    

    未触及禁触碰面:src/data/、scripts/、README.md、docs/、src/objects/、src/views/、src/hooks/、src/lib/、node_modules。CLAUDE.md 只改了指定的那一句。


    T2 API zh-CN 标签断言(验收 1)— ✅ 通过

    Accept-Language: zh-CN,管理员会话:

    断言对象 期望 实测 结论
    kpi_entry_sheet.label 填报单 填报单 ✅
    kpi_entry_sheet.fields.name 填报单名称 填报单名称 ✅
    kpi_entry_sheet.fields.status 状态 状态 ✅
    kpi_entry_sheet.fields.total_score 最终得分 最终得分 ✅
    kpi_app.label KPI 考核管理 KPI 考核管理 ✅

    顺带核到(验收 3 的 API 侧佐证):kpi_entry_line.label = 填报明细、fields.indicator = 指标、fields.indicator_name = 指标名称(改前为 Indicator);kpi_plan = 考核方案 / 方案名称 / 考核周期类型 / 状态;kpi_indicator = 考核指标 / 指标编码 / 指标名称 / 指标类别 / 计分方式。

    改前同一断言的实测(反证根因):zh-CN 请求返回 Entry Sheet / Sheet / Status / Final Score / KPI Assessment,即 zh-CN 包缺失时全部落到 en 包。


    T3 API en 对照断言(验收 2)— ✅ 通过

    Accept-Language: en,同一实例、同一时刻:

    断言 期望 实测 结论
    kpi_entry_sheet.label Entry Sheet Entry Sheet ✅
    kpi_entry_sheet.fields.name Sheet Sheet ✅
    kpi_entry_sheet.fields.status Status Status ✅
    kpi_entry_sheet.fields.total_score Final Score Final Score ✅
    kpi_app.label KPI Assessment KPI Assessment ✅

    en 包不受影响,与改前逐字相同。


    T4 UI 前后对比截图(验收 3)— ✅ 通过

    中文浏览器(Accept-Language: zh-CN,locale: zh-CN),1500×950 @2x,登录后逐页采集。前后同一记录 ID、同一路由。

    # 页面 前(英文) 后(中文)
    1 方案版本列表 01 面包屑 KPI Assessment / Assessment Plan,标题 Assessment Plan 02 KPI 考核管理 / 考核方案,列头 方案名称 / 考核周期类型 / 考核年度 / 状态 全中文
    2 填报单列表 03 标题 Entry Sheet 04 标题「填报单」,列头全中文
    3 填报单详情 05 对象名 Entry Sheet,字段标题 SUBJECT / STATUS / FINAL SCORE 06 对象名「填报单」,字段标题「考核方案 / 主体类型 / 状态 / 最终得分」
    4 填报明细相关列表 07 相关列表标题 Entry Line;两列并存「指标」与「Indicator」;下方 Assessment Result 08 标题「填报明细」;两列为「指标」与「指标名称」——验收 3 的点名项命中;下方「考核结果」
    5 指标库详情 09 面包屑 Indicator,字段标题 DEPARTMENT SEGMENT / SCORING METHOD / STATUS,指标编码/类别无标题 10 面包屑「考核指标」,「部门板块 / 计分方式 / 状态 / 指标编码 / 指标类别」全中文
    6 控制台首页 11 我的应用 KPI Assessment 12 「KPI 考核管理」
    7 英文对照 — 13 Accept-Language: en 下仍为 Entry Sheet / Sheet / Plan / Subject / Status / KPI Assessment,en 包未受影响

    前后对比 6 组(要求 ≥ 4 张,实交 12 张)+ 对照 1 张 = 13 张。


    T5 门禁(验收 4、5)— ✅ 通过

    pnpm verify 全绿(四段):

    段 结果
    objectstack validate 通过(元数据无错)
    tsc --noEmit 通过
    vitest run 6 个测试文件 / 90 个用例全通过
    i18n:extract:check(新增) ✓ 1 bundle(s) are in sync with the schema

    os i18n check:

    zh-CN  ████████████████████████ 100.0%  (1290/1290, missing 0)
    ⚠ Non-default locales have gaps but the default locale is fully covered.
    

    默认语言 zh-CN 零错误、零缺失。en 的 1252 条 warning 为改动前即存在的历史状态(en 包本就只手工覆盖 6 个对象的部分字段),本单「不改 en 包内容」,未新增也未消除。

    新鲜度门禁负向测试(证明门禁不是摆设):人为把生成文件里一个词条改脏 → pnpm i18n:extract:check 报

    ✗ out of date: src/translations/zh-CN.objects.generated.ts
    ✗ Translation bundles have drifted from the schema. Regenerate and commit
    ELIFECYCLE Command failed with exit code 1
    

    还原后重跑即恢复 in sync。门禁能挡住手改词条与元数据漂移两种情况。


    自测结论

    通过。 5 条验收标准全部命中,4 条范围项 3 ✅ 1 ⚠️(⚠️ 为生成命令口径的公开取舍,已在需求符合度清单完整披露并给出改回选项,非静默降级)。未发现回归:en 包输出逐字未变,pnpm verify 与 e2e 链路(73 PASS / 0 FAIL)均绿。

    遗留问题(不在本单范围,记录备查)

    1. en 包覆盖不全:os i18n check 报 en 缺 1252 键(除 6 个对象外的全部 kpi 对象/字段/选项、导航、看板、页面)。英文界面下这些位置回退成中文(见对照图 13 的「主体类型 / 当前节点序号 / 指标数」)。改前即如此,本单「不改 en 包」。影响面:仅英文界面用户的观感,不影响中文界面与任何功能。
    2. 平台 CLI:--no-metadata-forms 抑制不了 metadataForms 内联到单文件。传 --no-objects-only --no-metadata-forms 时,工具仍把 761 条 Studio 英文基线写进 <locale>.objects.generated.ts。本单用 --filter=kpi_ 规避(经逐行 diff 确认只少 metadataForms 一块、应用自有内容零损失)。与已上报的 i18n: metadata label lookup falls through to the en bundle on a zh-CN workspace — localeChain defaults fallbackChain to ['en'] and ignores i18n.fallbackLocale, so an authored Chinese label loses to a courtesy English bundle objectstack#14882 同属 i18n 工具与运行时口径问题;是否合并上报请示。
    3. 平台 CLI:extract --check 失败时打印的重跑命令有误,输出 os i18n extract --locales= --fill=empty --out=src/translations(locales 为空、丢了本仓库实际用的开关),照抄会跑错。仓库侧已用 pnpm i18n:extract 封装规避。属提示文案缺陷,不影响门禁判定正确性。

    遗留 2、3 均为平台侧现象,按项目约定「只上报、不修复」;本会话未在平台仓开单(避免与 #14882 重复上报),是否另行开单请 PM 定。

  6. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    提 PR + 交接验收侧

    请验收侧留意的一处取舍:生成命令比正文范围 §1 多了 --no-objects-only --filter=kpi_,是为满足验收标准 §1 的应用名断言、并避免把平台 Studio 的英文基线打进应用包;理由与「改回」选项都写在需求符合度清单的「偏差 1」里。

    开发侧到此为止,不自行合并 PR。

  7. added a commit that references this issue on Sep 3, 2026
  8. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    合并记录(调度员,2026-09-03)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions