fix(cli,spec): i18n coverage gates view labels — the defineView() container is no longer skipped (#4123) - #4132
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…tainer is no longer skipped (#4123) `i18n/missing-view` had ZERO producers. The `'view'` source exists in `CoverageIssue`, the walker has code for it, and check-i18n-coverage's header claims listViews is covered — but no view label in this repo had ever been gated, and the ratchet reported green the whole time. `collectExpectedEntries` recognized two view shapes; the compiled config is neither: 1. Object-nested `listViews` — objects do not carry `listViews` once compiled (0 across every example; only hand-authored platform objects use that shape). 2. Top-level NAMED views — guarded by `if (!view?.name) continue`. `defineView()` emits the aggregated View CONTAINER — `{ list, listViews, formViews }` — which per spec (`view.zod.ts`) has no top-level `name`: it is keyed implicitly by its target object at `list.data.object`, exactly as objectql's `resolveMetadataItemName` resolves it. The guard therefore rejected the spec's own container shape, i.e. every view every example declares. Measured on the real compiled configs, same commit, before → after: app-crm total 1402 → 1420 | view 0 → 18 app-showcase total 2210 → 2250 | view 0 → 40 app-todo total 1343 → 1349 | view 0 → 6 No other source moved; the totals rise by exactly the view counts. The container walk emits under the same `objects.<object>._views.<view>.*` convention the runtime resolver reads (`viewLabel` in @object-ui/i18n) and the shipped platform bundles already carry (`sys_user._views.all_users.label`). An unnamed default `list` resolves under `_views.list`, matching the console's `primary.name || 'list'`. A named list view may retarget another object via its own `data`, so its own object wins over the container's. `formViews` stays uncovered on purpose: form views have no counterpart in that resolver convention, so emitting keys for them would expect translations nothing reads. `StrictObjectTranslation` gains the `_views` slot `ObjectTranslationDataSchema` already permits — it is not derivable from the object type (views are declared separately), so it is optional and loosely keyed rather than enumerated like `fields`. Without it, `satisfies StrictObjectTranslation<…>` rejects the very translations the gate now asks for (app-todo). The 35 newly surfaced strings are TRANSLATED, not ratcheted — the precedent from the object-less action: raising the baseline makes the gate green by widening the debt it exists to prevent. Verified the gate is genuinely live on view keys rather than green by accident: deleting one view translation moves app-todo 120 → 121 and fails; restoring it returns to OK. check-i18n-coverage: 665, none new. os lint 0 errors on all three examples. spec 7022 tests, cli 877 tests, showcase 60, crm 20, todo 78. tsc + eslint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xuyushun441-sys
force-pushed
the
fix/i18n-view-coverage-4123
branch
from
July 30, 2026 11:04
a98c8cc to
1f976b7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4123.
i18n/missing-viewhad 零产出。'view'在CoverageIssue的类型里,walker 里有对应代码,check-i18n-coverage的头部注释也声称覆盖 listViews —— 但这个仓库里没有任何一个视图 label 被门禁看到过,而门禁一路报绿。根因
collectExpectedEntries认两种视图形状,编译产物两种都不是:listViews—— 编译后的 object 上没有listViews(三个 example 实测全 0;只有手写的 platform object 用这种形状)。if (!view?.name) continue挡住。defineView()产出的是聚合 容器:{ list, listViews, formViews }。按 spec(view.zod.ts)它没有顶层name—— 它由目标对象隐式定键,对象名在list.data.object,正是 objectqlresolveMetadataItemName的解析方式。所以那个 guard 拒绝的是 spec 自己的容器形状,也就是每个 example 声明的全部视图。度量(同 commit、同配置,修前 → 修后)
其它 source 一条没动,总数正好等于视图增量。
键名依据
容器遍历沿用既有约定
objects.<object>._views.<view>.*,三处独立佐证对齐:viewLabelin@object-ui/i18n)sys_user._views.all_users.label)resolveMetadataItemName一致匿名的默认
list落在_views.list,对应控制台的primary.name || 'list'。具名 list view 可以通过自己的data改指别的对象,此时以它自己的对象为准。formViews有意不覆盖:表单视图在viewLabel/_views.*这套解析约定里没有对应物,为它们发键等于期待没人会读的翻译。附带的类型修正
StrictObjectTranslation补上ObjectTranslationDataSchema本就允许的_views。它无法从对象类型推导(视图是分开声明的),所以是可选、松散键控,不像fields那样枚举。不补的话,satisfies StrictObjectTranslation<…>会拒绝门禁新要求的那些翻译(app-todo 命中)。新增的 35 条:翻译,不抬 baseline
沿用 object-less action 那次立的先例 —— 抬 baseline 等于把这个门禁存在的意义又放宽一次。
验证
门禁是真活的,不是碰巧绿的:删掉一条视图翻译 → app-todo
120 → 121并失败;恢复 → OK。check-i18n-coverage:665,none newos lint:三个 example 各 0 errors发现于 objectui#2960 的验证过程(#4101 加 showcase specimen 时顺带查证 i18n 门禁会不会变红,结果发现它根本不会)。
🤖 Generated with Claude Code