Skip to content

fix(service-datasource): serve the datasource driver form's labels and help in the requester's language - #30685

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-b5t886
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-b5t886

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Fixes #30563

Clause-②: no
Metadata-protocol: none

domain:server#1 card thread · session session_016WV4czJVaL8SDBxjng4RLk · branch claude/project-thread-b5t886 (the card thread's platform-assigned branch, named in claim amendment 6670256081).

维护者速读

  • 改了什么:新建数据源对话框里的驱动名称、驱动说明和每个连接字段的标题与说明(文件名、自动迁移表结构、主机、端口等),现在由服务端按请求语言返回;平台语言表上的 11 种语言全部齐全(简体、繁体、西、阿、法、葡(巴西)、俄、德、日、韩,英文为源文),英文界面不变。
  • 为什么改:这些文字全部来自 GET /api/v1/datasources/drivers,控制台自己没有对应的翻译键,所以中文界面里这一块一直是英文,和对话框其他中文文字混在一起。
  • 风险与回滚:只改返回的文字,驱动 id、图标、字段类型、默认值和校验都不变;繁体读者(zh-TW、zh-HK)拿到繁体,不会落到简体;平台表之外的语言和产品名照旧返回英文。回滚即还原本 PR。
  • 先看:packages/services/service-datasource/src/driver-catalog.ts 的 driverCatalogLocaleOf 与 driverCatalogFor;src/driver-catalog-translations.ts 的十种语言表;src/admin-routes.ts 里 drivers 路由那一行。
  • 两分钟验证:pnpm --filter @objectstack/service-datasource exec vitest run src/__tests__/driver-catalog.test.ts src/__tests__/admin-routes.test.ts,预期 2 个文件 70 例全绿,其中 zh-CN 读到「文件名」,zh-TW 读到「檔案名稱」,fr-FR 读到 Nom de fichier,en-US 读到 Filename。
  • 需要你做的:无,席位落地。

What changes

  • GET /api/v1/datasources/drivers reads the requester's language the way the REST metadata door and the settings routes read it (the top Accept-Language tag, else a string ?locale=) and serves driverCatalogFor(locale) instead of the fixed English DRIVER_CATALOG. The console already sends its own language as Accept-Language on every API call (createAuthenticatedFetch reads the html lang attribute), so no ui/ change is needed.
  • driverCatalogLocaleOf (new, driver-catalog.ts) reads the requested code through the platform locale table's own reader, platformLocaleTagOf (@objectstack/spec/system), shortened one subtag at a time (RFC 4647 lookup), the shape the storage connection test uses (PR fix(service-storage): Setup storage Test connection answers in the caller's language (#30335) #30627). So zh-TW, zh-HK, zh-MO and zh-Hant-TW reach zh-Hant and never the Simplified text; zh, zh-CN, zh-SG and zh-Hans-CN reach zh-Hans; pt and pt-PT reach pt-BR; fr-CA reaches fr. driverCatalogFor overlays that language's entry label / description and each top-level field's JSON-Schema title / description on the English catalog. The spec's projected schema is copied, never written.
  • driver-catalog-translations.ts (new) holds the translations, service-local beside the catalog's English curation, keyed by the platform table's tags. Every non-English language on the table (zh-Hans, zh-Hant, es, ar, fr, pt-BR, ru, de, ja, ko) covers all five offered drivers (In-Memory, SQLite, PostgreSQL, MySQL / MariaDB, MongoDB) and every field word the form draws. Each language is written once as its distinct words and laid out per driver, so a field the drivers share (host, port, password) reads one way. Product names and technical terms (SQLite, URL, URI, SSL/TLS, knex searchPath, application_name) are kept as they are.
  • Fallback: no locale, en, a code the platform table does not name (it, nl-NL), and the product-name labels are served the English text, never a key. A translation only replaces a word the English form shows; it never adds a title to a field that has none.
  • Changeset: @objectstack/service-datasource patch.

Tests

  • src/__tests__/driver-catalog.test.ts, two new top-level describes. driverCatalogFor: Simplified Chinese words for SQLite (文件名, 自动迁移表结构, the driver description) and the network drivers (主机, 端口, 密码); a SQLite filename title of its own in each of the ten languages, asserted against PLATFORM_LOCALE_TAGS; zh-TW, zh-HK, zh-MO, zh-Hant, zh-hant, zh-Hant-TW, zh-Hant-HK reach zh-Hant (檔案名稱) and zh, zh-CN, zh-cn, zh-SG, zh-Hans, zh-Hans-CN reach zh-Hans; ten alias and regional codes (ja-JP, es-MX, pt-PT, fr-CA, …) reach their table language; ids, icons, field keys, types and defaults equal the English entry's in all eleven languages; undefined, empty, en, en-US, en-GB, it, nl-NL, constructor, __proto__ return DRIVER_CATALOG itself; product-name labels stay English; the spec projection and DRIVER_CATALOG still read Filename after every language is served. DRIVER_CATALOG_TRANSLATIONS coverage walks PLATFORM_LOCALE_TAGS, not the table's keys: the table carries exactly the ten non-English languages; each names only drivers and fields the catalog serves; each translates every driver description, every non-product label and every field word the English form shows, so a missing language or a field the spec adds goes red.
  • src/__tests__/admin-routes.test.ts, one new case on the real HonoHttpServer: Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 serves 文件名, 自动迁移表结构, 主机, 端口 and the zh MySQL description with the English SQLite label; ?locale=zh-CN with no header serves zh; zh-TW,zh;q=0.9 serves 檔案名稱 and 連接埠; fr-FR,fr;q=0.9 serves Nom de fichier; en-US and it-IT serve Filename and Host.

Acceptance notes

  • Languages. All eleven languages on the platform locale table (PLATFORM_LOCALES), English as the source, per the maintainer's one-list ruling (no language tiers).
  • Out-of-scope finding (class a). The dialog's own strings (the console's studio namespace: the dialog title, Name, Display name, Driver, Schema mode and its hints) exist in English and Chinese only (ui/packages/i18n/src/namespaces/studio/ holds en.ts and zh.ts), so a console in any of the other nine languages now reads these driver words in its own language inside an English dialog. Reach: the New datasource dialog under Setup, console language set to any table language other than en / zh-Hans; read from the tree, not measured live. Not fixed here (ui/** is outside this card's surface). Dedupe words: studio namespace locales, datasource dialog i18n, studio en zh only.
  • ?locale= read. The route now reads ?locale= (string only, as the settings routes and the metadata door do). It had no query read before and declares no closed query set; converting this route to refuseUnknownQueryParams is not done here.
  • Stale translations are not detected. If the spec revises an English field description, the zh-CN text stays as written; the coverage test catches added and removed fields, not revised wording. Noted, not filed.
  • Nested schema words (the memory driver's persistence variants) are not translated: the dialog draws only top-level properties.
  • DRIVER_CATALOG keeps its value and stays the English catalog; the QA checklist row that verifies the drivers body against it (docs/qa/platform-checklist/areas/integration-system.json) still holds for an English request.

Verification

At head 2289fe00 (round 1 rework), after the @objectstack/service-datasource dependency closure build.

Package suite and typecheck
  • pnpm --filter @objectstack/service-datasource test (under os-verify-lock): Test Files 72 passed (72), Tests 1239 passed (1239), VERDICT command-exit 0.
  • pnpm --filter @objectstack/service-datasource typecheck: VERDICT command-exit 0 (tsc --listFiles includes both changed test files).
  • pnpm lint (eslint . --no-inline-config): exit 0.
Ablations (scripts/ablation-replace.mjs, each restored to blob == HEAD, git diff HEAD empty)
  • Route ignores the requester (driverCatalogFor(requestLocaleOf(req)) to driverCatalogFor(undefined)): 1 failed / 69 passed, the route case.
  • Title overlay deleted in localizeField: 4 failed / 66 passed (Simplified words, every-language titles, Traditional codes, route case).
  • Schema written in place (Object.assign(configSchema, …) instead of a copy): 3 failed / 67 passed (English fallback, spec projection untouched, route case).
  • Subtag shortening removed (only the whole code is looked up): 3 failed / 67 passed (Traditional codes via zh-Hant-TW, regional codes such as fr-CA and es-MX, route case via fr-FR).
Derived gates (dispatch-gates --commands)
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 61 families derived at 2289fe00; every one exit 0 on the first pass (the round-0 prerequisites, the teardown fixture commit and the whole-tree build, were still in place).
  • --ran reconciliation: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN.
  • pnpm lint: exit 0. check-commit-card-trailers --range origin/main..HEAD: exit 0 (2 commits).
  • Families CI runs beyond the derived set: read from this PR's check-runs. The round-0 TypeScript Type Check red at b475fae0 was the aggregator over a lane cancelled by the push of 2289fe00 (run 42121322456: consumer gates cancelled, the other three lanes success), not a type error.

Generated by Claude Code

…ester's language

GET /api/v1/datasources/drivers served every driver label, description and
connection field title/description in English, so a Chinese console's New
datasource dialog read Filename, Auto-migrate schema, Host and Port in English.
The route now reads the requester's language (Accept-Language, else ?locale)
and serves driverCatalogFor(locale), which negotiates through
resolveLocaleAmong and overlays a service-local zh-CN table on the English
catalog. Any word without a translation stays English.

Claude-Session: https://claude.ai/code/session_016WV4czJVaL8SDBxjng4RLk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/service-datasource, touching 36 documentable anchor(s).

2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/data-modeling/drivers.mdx (via applicationName (symbol, a field of const object ar; a field of const object de; a field of const object es; a field of const object fr; a field of const object ja; a field of const object ko; a field of const object ptBR; a field of const object ru; a field of const object zhHans; a field of const object zhHant; a field of interface CatalogWords), authSource (symbol, a field of const object ar; a field of const object de; a field of const object es; a field of const object fr; a field of const object ja; a field of const object ko; a field of const object ptBR; a field of const object ru; a field of const object zhHans; a field of const object zhHant; a field of interface CatalogWords), autoMigrate (symbol, a field of const object ar; a field of const object de; a field of const object es; a field of const object fr; a field of const object ja; a field of const object ko; a field of const object ptBR; a field of const object ru; a field of const object zhHans; a field of const object zhHant; a field of interface CatalogWords), statementTimeout (symbol, a field of const object ar; a field of const object de; a field of const object es; a field of const object fr; a field of const object ja; a field of const object ko; a field of const object ptBR; a field of const object ru; a field of const object zhHans; a field of const object zhHant; a field of interface CatalogWords), /api/v1/datasources/drivers (route, a path literal in a comment on a changed line))
  • content/docs/deployment/cli.mdx (via autoMigrate (symbol, a field of const object ar; a field of const object de; a field of const object es; a field of const object fr; a field of const object ja; a field of const object ko; a field of const object ptBR; a field of const object ru; a field of const object zhHans; a field of const object zhHant; a field of interface CatalogWords))
What this run could not see
  • 11 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 63 of 221 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 103 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 3 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json a2437b560bd8872feece6ec8b57c6fdf21cff1f4 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 4e1c6132ef477810cb2d475eb0d0768575a54abf — the merge of head 2289fe00fe977004f40a205bf7e7b02e1b1504cc into base a2437b560bd8872feece6ec8b57c6fdf21cff1f4, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 4e1c6132ef477810cb2d475eb0d0768575a54abf && git checkout 4e1c6132ef477810cb2d475eb0d0768575a54abf
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a2437b560bd8872feece6ec8b57c6fdf21cff1f4 2289fe00fe977004f40a205bf7e7b02e1b1504cc && git checkout -B drift-repro a2437b560bd8872feece6ec8b57c6fdf21cff1f4 && git merge --no-ff 2289fe00fe977004f40a205bf7e7b02e1b1504cc

node scripts/docs-audit/affected-docs.mjs --json a2437b560bd8872feece6ec8b57c6fdf21cff1f4

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs a2437b560bd8872feece6ec8b57c6fdf21cff1f4 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…form language

The catalog carried Simplified Chinese only, which opened a language tier on a
platform whose locale table lists eleven languages, each complete. The
translations are now keyed by the platform table's tags and cover all ten
non-English languages, written once per language and laid out per driver so a
shared field reads one way. The requested code is read through the table's own
reader, shortened one subtag at a time, so Traditional Chinese codes reach
zh-Hant and never fall to the Simplified text. The coverage test walks
PLATFORM_LOCALE_TAGS, so a missing language goes red.

Claude-Session: https://claude.ai/code/session_016WV4czJVaL8SDBxjng4RLk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl and removed size/m labels Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

席位核对 · ACCEPT · 2026-11-05T23:12Z · #30563

Head-sha: 2289fe0

  • Shape: 6 files, +1029/−3, all in packages/services/service-datasource/ plus one @objectstack/service-datasource patch changeset. That matches the claimed surface (claim 6670164695, amendment 6670256081). Not governed. The translations table is most of the line count; the code change is driver-catalog.ts +101 and admin-routes.ts +17/−2.
  • Round 1 rework answered: the round-0 head carried zh-CN only, against maintainer ruling F ([Decision] One locale list, one completeness rule — the long-term i18n regime across Console, platform metadata, cloud and mobile #29349, one platform language list, no tiers). This head carries every non-English tag on PLATFORM_LOCALE_TAGS (zh-Hans, zh-Hant, es, ar, fr, pt-BR, ru, de, ja, ko). The coverage test walks PLATFORM_LOCALE_TAGS itself, so a missing language or a field the spec adds goes red.
  • Spot check (read in the diff):
    • driverCatalogLocaleOf reads through platformLocaleTagOf with subtag shortening, so zh-TW / zh-HK / zh-Hant-TW reach zh-Hant and never the Simplified text; pinned in both the unit and the HonoHttpServer route case.
    • driverCatalogFor copies the spec's projected schema; the "spec projection still reads Filename" pin guards against writing it in place.
    • Ids, icons, field keys, types and defaults are pinned equal to the English entry in all eleven languages; unknown codes, __proto__ and constructor return DRIVER_CATALOG itself.
    • Ablations are reported for all four seams (requester ignored, title overlay removed, in-place write, no subtag shortening), each turning its pins red.
  • Gates: every check-run on this head has concluded: 37 success, 15 skipped, 0 failure.
  • Accepted deviations: the route now reads a string ?locale= the way the settings routes and the metadata door do; converting it to refuseUnknownQueryParams is not done here. Stale-translation detection (a revised English description) is noted, not filed.
  • Out of scope (class a): the dialog's own studio namespace strings exist in en and zh only (ui/packages/i18n/src/namespaces/studio/), so in the other nine languages these driver words now sit inside an English dialog. Read from the tree, not measured live; ui/** is outside this card's surface.
  • Contract: Clause-②: no, Metadata-protocol: none, confirmed from the diff. Only the served label and help text change; nothing is refused or newly accepted at a door.
  • Landing: ready, then auto-merge, through the relay.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 23:14
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 5, 2026 23:14
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit c35fed1 Nov 5, 2026
53 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-b5t886 branch November 5, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xl tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Datasource driver forms: field labels and descriptions (Filename, Auto-migrate schema, Host, Port) are English in every console language

1 participant