refactor(types): 台账燃尽批次 1/8 — 报表/图表/查询簇 11 符号 - #3167
Merged
os-zhuang merged 2 commits intoAug 1, 2026
Conversation
…p wearing spec names
Batch 1 of the objectstack#4115 debt ledger (objectui#3155): 11 `@object-ui/types`
collisions, triaged one by one against `@objectstack/spec` 17.0.0-rc.0. Ledger
115 -> 105; ALLOW 5 -> 6.
Six were pure name collisions — same name, different concept — so they are
renamed to local dialects. Each new name was run past the guard first
(objectui#3074's `PageComponentSchema` lesson) and is pinned absent from the
spec's export set:
ChartSeries -> ChartDataSeries (ours carries literal `data: number[]`;
ChartSeriesSchema -> ChartDataSeriesSchema spec's is a dataset-bound descriptor)
QueryAST -> SqlQueryAST (compiled SQL tree vs ObjectQL request)
QuerySchema -> DriverQueryConfig (TS config vs the spec's zod value)
DriverInterface -> SqlDriverInterface (SQL client vs runtime driver contract)
DatasourceSchema -> DatasourceRegistration (live record vs authored document)
Renames were done declaration-and-barrel first, letting tsc enumerate the break
points, never by global string replace — half these names exist on both sides.
Three are now DERIVED, converging on the `ListViewSchema` paradigm. Two carried
live defects, both of the silent-stripping kind a `z.object()` produces:
- DashboardWidgetSchema declared 10 of the spec's 22 keys, so `objectui
validate` deleted the other 12 in silence — chartConfig, colorVariant,
filter, responsive, aria, action{Url,Type,Icon}, compareTo, suppressWarnings
and the requiresObject/requiresService capability gates the renderer honours
at runtime. The TS interface declared most of them all along.
- GlobalFilterSchema took `scope` as a free-form string; it now uses the spec's
widget|dashboard vocabulary.
- AppContextSelectorSchema was a full restatement.
Every pinned divergence is one a runtime normalizer already backs, and each is
asserted in both directions so it dies the day the spec adopts it.
ListViewSchema resolves as a pair: the zod node now names the spec in its own
initializer instead of one hop away through a local const (which is why the
repo's own best-practice derivation was sitting in the ledger), and the TS twin
moves to ALLOW — the spec's `ListViewSchema` is a zod VALUE, so there is no spec
type to alias, and the objectui node intersects non-serialisable runtime props.
JoinedReportBlock is NOT burnable and stays in the ledger: the spec declares
`JoinedReportBlockSchema` as `z.ZodTypeAny`, so its exported type resolves to
`unknown` — re-exporting it would delete the block type outright. This is one
variant wider than the objectstack#4171 cases already pinned: those erase to
`any`, which `0 extends (1 & T)` detects, while this erases to `unknown`, which
that probe reports as safe. Guard header and an inverted pin now say so; it
belongs to ledger batch 8.
Verification: guard green; `--ledger` diff removes exactly these 10 and adds
nothing, other packages byte-identical; type-check 78/78 after rebuilding the
types dist; 9326 assertions across 798 files green; mutation-tested both ways
(hand-copying GlobalFilterSchema back and un-renaming SqlQueryAST each fail by
name and file, and the parity test fails alongside).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Jdef6ZFhJmiNRhNCd4DW3
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
August 1, 2026 14:44
objectui#3169 (ledger batch 3, `@object-ui/app-shell`) landed first and edited the same DEBT block — the expected hot spot for parallel batches. Resolved by REGENERATING the whole block with `--ledger` against the merged working tree rather than picking conflict lines, so the guard's two-way ratchet (a missed deletion and an over-deletion both fail) certifies the result. Verified against the post-#3169 main: removed is exactly this batch's ten symbols, added is empty, and 17 of 18 packages are byte-identical — including `@object-ui/app-shell`, which stays fully burned down. 87 -> 77. The guard header's new case 2b (`unknown` erasure, objectui#3155) and the `@object-ui/types:ListViewSchema` ALLOW entry merged cleanly; #3169 touched neither, so nothing of either side was dropped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Jdef6ZFhJmiNRhNCd4DW3
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
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.
Closes #3155. Part of objectstack-ai/objectstack#4115 (台账燃尽 1/8)。
@object-ui/types报表/图表/查询簇 11 条碰撞逐条分诊。台账 87 → 77,ALLOW 5 → 6。分诊按守卫文件头的三说谎点先跑探针再下判断,并额外比了 zod 的
_input;结果是三种处置各占一部分,外加一条上游阻塞。每条符号的判决
ChartSeriesChartDataSeriesdata: number[]必填);spec 的是数据集绑定的序列描述符(type/stack/yAxis/variant),根本没有data。两侧互不可赋值ChartSeriesSchemaChartDataSeriesSchemaQueryASTSqlQueryASTselect/from/join/group_by);spec 的是 ObjectQL 请求描述符(object/fields/where/expand)。互不可赋值QuerySchemaDriverQueryConfigQueryASTBuilder的输入 TS 接口;spec 把这个名字用作 zod schema 值,键集也不同DriverInterfaceSqlDriverInterfacequery(sql, params));spec 的是平台运行时驱动契约(supports/execute/findStream)DatasourceSchemaDatasourceRegistrationDatasourceManager持有的内存注册记录(driver是活的实例);spec 的是可编写的元数据文档(driver是名字)DashboardWidgetSchemaGlobalFilterSchemaAppContextSelectorSchemaListViewSchemaJoinedReportBlock派生修好的两个活缺陷
都是
z.object()静默丢键那一类,也就是 Navigation 簇(#3088)已经记录过的形态:DashboardWidgetSchema只声明了 spec 22 个键里的 10 个,另外 12 个被objectui validate一声不吭地删掉:chartConfig、colorVariant、filter、responsive、aria、actionUrl/actionType/actionIcon、compareTo、suppressWarnings,以及requiresObject/requiresService这两个渲染器在运行时真的执行的能力门控。complex.ts的 TS 接口一直声明着其中大部分 —— 所以一个 widget 能在 objectui 里类型检查通过,却在校验时丢掉一半配置。三份表述(TS / zod / 渲染器)各自漂移的又一现场。GlobalFilterSchema.scope是自由字符串,任何拼写错误都能通过校验;现在按引用取 spec 的widget | dashboard。运行时没有任何地方读scope,收紧零成本。钉住的有意分歧(每条都有运行时归一化器背书)
DashboardWidgetSchema:id保持可选(存量仪表盘与 legacy 格式不带 id)、type保持放宽(objectui 的DASHBOARD_WIDGET_TYPES另有list/custom,spec 的 19 族枚举不建模)、componentlegacy 信封保留。GlobalFilterSchema:裸字符串options简写、归一化后的{ preset }日期默认值(framework#4475)、optionsFrom.labelField可选 —— 三条分别对应normalizeFilterOptions/normalizeDateDefault/ 回落到valueField。AppContextSelectorSchema:label放宽到 objectui 的 i18n 信封,因为AppContextSelectors一直用resolveI18nLabel渲染它。每条都做了双向断言 —— spec 哪天自己放宽了,断言翻红,该删的就是本地覆盖。
ListViewSchema一对两解SpecListViewFields.shape),守卫只看一层。现在把specFieldsExcept(SpecListViewSchema.shape, …)直接写进声明的初始化器,派生在声明处可见。语义不变。ListViewSchema是个 zod 值,没有可 alias/extends 的 spec 类型;而且本地节点还要 intersectListViewRuntimeProps(回调与命令式刷新触发器,不是可序列化的视图元数据,不可能存在于任何 schema)。分歧边界由 zod 派生约束,漂移守卫是既有的list-view-spec-parity.test.ts。JoinedReportBlock:上游阻塞,请挪到批次 8spec 把
JoinedReportBlockSchema声明为z.ZodTypeAny,于是导出的JoinedReportBlock类型解析为unknown。re-export 会把本地精确的块接口(name/columns/groupingsDown/groupingsAcross/filter/chart)整个删掉。这比 objectstack#4171 已钉住的三条宽一档,值得写进修法模板:那三条擦除成
any,0 extends (1 & T)探针抓得到;这条擦除成unknown,同一个探针报false—— 只筛any的分诊会把它当成"可安全派生"放行。已在守卫文件头补上 2b 情形与[unknown] extends [Spec]探针,并配了会在 spec 修好当天报红的反向 pin。跨包协同:
ChartSeries(批次 4)@object-ui/core的ChartSeries是{ dataKey, label }——buildChartSeries产出的渲染器内部序列描述符,和 types 侧的内联数据序列、spec 侧的数据集绑定描述符三者互不相同。本 PR 把 types 侧定为ChartDataSeries;core 侧建议ChartSeriesBinding之类,决定已在 objectstack#4115 评论记录,批次 4 可直接沿用。台账变化
与 objectui#3169 的 DEBT 块冲突,按规约整块
--ledger重生成而非逐行挑拣,再对合并后的 main 逐条 set-diff:验证
合并 main 后全部重跑:
node scripts/check-spec-symbol-derivation.mjs绿(6 declared dialects / 77 untriaged / 18 packages)pnpm turbo build --filter=@object-ui/types重建 dist,再pnpm turbo type-check --force→ 78/78spec-symbol-parity.test.ts同跑 50 条全绿)eslint改动文件 0 errorGlobalFilterSchema改回手抄z.object({…})→ 守卫报const GlobalFilterSchema packages/types/src/zod/complex.zod.ts:331,同时 parity 测试picks up the spec scope vocabulary by reference报红;SqlQueryAST改回QueryAST→ 守卫报interface QueryAST packages/types/src/data-protocol.ts:299;QueryAST塞回重生成后的 DEBT → 守卫报lists 1 symbol in DEBT that no longer collide。施工规约遵守情况
ChartSeries/QueryAST/QuerySchema这些名字两边都有。tsc 抓出的断点只在packages/core/src/query/(SQL AST builder 及其测试),逐个确认是本地概念后才改。.d.ts,类型与值都覆盖 —— 六个里有五个是类型,只查运行时命名空间会白过)。content/docs/releases/;变更以 changeset 形式记录。需要人拍板 / 遗留
JoinedReportBlock需要挪到批次 8(台账燃尽批次 8/8 · 被 objectstack#4171 阻塞的 any 擦除簇,3 符号——上游解除后处理(objectstack#4115) #3162),并在 objectstack#4171 登记unknown擦除这一变体。DashboardWidgetSchema的responsive仍是any:渲染器读的是按断点的 record,spec 的是单个responsive对象,两者收敛需要产品决定,本轮只在声明处写明未擅自调和。Generated by Claude Code