Repository navigation
fix(data-objectstack): 把 queryDataset(selection) 直接声明为 spec 的 DatasetSelection - #3753
Merged
Merged
Conversation
…etSelection The adapter restated the selection contract inline, field by field, and the copy had drifted three ways from the pinned @objectstack/spec@17.0.0-rc.5: - compareTo.dimension was required. It has been optional since objectstack#5011 precisely because the EXECUTOR resolves it (exactly one time dimension carrying a dateRange is shifted; zero or several raises a loud error naming the candidates). Requiring it made the compiler demand from every typed caller the consumer-side dimension guess that change forbids, trading a loud error for a silently wrong comparison window. - timeDimensions was widened to unknown[], erasing the entry shape the executor's resolution reads, and runtimeFilter to Record<string, unknown>, erasing the $and/$or/$not vocabulary the server parses. - dateGranularity was missing entirely: the copy had stopped at whatever the contract looked like the day it was written. The parameter is now the spec type by reference, so there is nothing left to re-sync. Removing the dialect rather than correcting it is the point -- restating a contract owned elsewhere opens a second de-facto dialect of it (AGENTS.md #0/#0.1), and this issue is the instance. queryDataset.test.ts pins structural identity with DatasetSelection plus each of the three drifts individually, checked by this package's tsc --noEmit (its tsconfig includes the whole src tree). A runtime test pins that a dimension-less compareTo reaches the server untouched, so the adapter can never start guessing on the executor's behalf. The response type is deliberately untouched -- it is the REST envelope (object / dimensionFields / drillRawRows), not a restatement of AnalyticsResult. Its own fields[] drift is filed separately as #3752. Fixes #3613
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 8, 2026 12:05
akarma-synetal
pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 10, 2026
…alyticsResult element (objectstack-ai#3752) (objectstack-ai#3817) The return-value half of the drift objectstack-ai#3613/objectstack-ai#3753 fixed on the parameter side. The adapter hand-listed five keys for a result column (name/type/label/format/ currency) and, like every restatement, stopped at the contract of the day it was written: it never grew percentScale, which @objectstack/spec@17.0.0-rc.5 carries on AnalyticsResult.fields[] and documents as mandatory reading — "renderers that receive it must scale by it instead of guessing from the value" (objectstack-ai#3136). Three in-repo consumers (plugin-dashboard, plugin-report, DatasetPreview) read the key through @object-ui/core's local DatasetResultField, so nothing was red here; but an author reading columns through the adapter's DECLARED return type got "Property 'percentScale' does not exist" — the declaration steering them back to the guess-by-magnitude objectstack-ai#3136 banned. fields is now the spec element by reference, additively for existing consumers. The rest of the envelope stays locally declared on purpose: the route adds ADR-0021 D2 drill metadata on top of AnalyticsResult, and this method rebuilds its own object without copying sql (index.ts:3355), so an intersection with AnalyticsResult would advertise a key the adapter structurally cannot return. queryDataset.test.ts pins structural identity with the spec element, pins percentScale as the 'fraction' | 'whole' union rather than a widened string, keeps a negative pin against the five-key shape, pins the envelope as NOT an AnalyticsResult, and reads percentScale off a column through the declared type at runtime. Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 17, 2026
…ields[] (objectstack-ai#3815) (objectstack-ai#4128) `packages/core/src/utils/dataset-format.ts` declared its own six-key interface for the analytics result column under a doc comment describing the server's contract. The key set matched the spec today, so nothing was broken — but this was the last surviving member of the derive-don't-restate family (objectstack-ai#3613/objectstack-ai#3753 parameter side, objectstack-ai#3752 adapter return side), and the member with no compile-time tripwire: three surfaces (DatasetWidget, DatasetReportRenderer, DatasetPreview) consume this name AS the real column type, so the next spec column key would simply never appear here and no build would complain. It is now `AnalyticsResult['fields'][number]`. The exported name is unchanged and the `PercentScale` re-export is untouched. `type` is required again, as the contract has it. The investigation the card asked for found no construction site that could not supply it: every value of this type originates in `ObjectStackAdapter.queryDataset`, which already declares the spec element (objectstack-ai#3752), and the whole downstream type-check closure of `@object-ui/core` (68 tasks) is green with no fixture change. No consumer reads `.type` at all, so the relaxation had bought no caller anything while advertising a `string | undefined` the wire never produces. `packages/core/tsconfig.typetests.json`, chained off the package's `type-check`, compiles the new parity test — core's test tree is still in the type-check coverage script's TEST_DEBT, so without it these pins would be the "declared != enforced" landmine they exist to remove (objectui#3009). Reverting the interface turns five of them red, including the negative pin against the hand-written shape and the `ChartResultField` superset asymmetry. Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3 Co-authored-by: Claude <noreply@anthropic.com>
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 #3613
前提核验(issue 只是线索)
在
origin/main@28364bd上逐条核过,前提成立:packages/data-objectstack/src/index.ts:3202确实仍是compareTo?: { kind: 'previousPeriod' | 'previousYear'; dimension: string }——dimension必填。packages/data-objectstack/package.jsonpin 的是@objectstack/spec@^17.0.0-rc.5,lockfile 解析到17.0.0-rc.5(注意:共享 checkout 当前分支的 lockfile 还停在 rc.2,所以这一条必须按origin/main读)。DatasetCompareTo.dimension确为可选,注释原文:**Optional since #5011, resolved by the EXECUTOR — not by any consumer.**一处与 issue 正文的出入,已按裁定 1「READ the pinned spec package first」核实后照实处理:issue 说该类型在
contracts/analytics-service.ts,但发布出来的包里没有src/contracts/(源码只部分随包)。实际导出名与入口是DatasetSelection/DatasetCompareTo,从@objectstack/spec/contracts子路径导出(本包spec-symbol-batch6.test.ts已在用这个子路径)。名字与 issue 一致,入口按实际的写。改了什么
手写的
selection内联类型换成对 spec 类型的直接引用:删掉的那份副本一共漂了三处(裁定 2 的
timeDimensions只是其中之一):compareTo{ kind; dimension: string }(必填)DatasetCompareTo,dimension?timeDimensionsunknown[]AnalyticsQuery['timeDimensions']runtimeFilterRecord< string, unknown >FilterConditiondateGranularity'day'|'week'|'month'|'quarter'|'year'前两项 issue 点到了。后两项是核验时才浮出来的:
runtimeFilter放宽成Record< string, unknown >抹掉了服务端要解析的$and/$or/$not词汇;而dateGranularity(framework#3588)是副本从来没长出来过的键 —— 这条最能说明问题:重述一份契约不只会在它有的字段上漂移,它还会停在写它那天的样子。这也正是 issue 自己的结论(「重述一份就是给同一契约开第二份方言」),所以这里做的是消灭方言而不是重新同步一遍。为什么这不是纸面问题:
dimension必填等于让编译器向每个按类型调用的作者索要一个执行器本该自己决议的维度 —— 恰好是 objectstack#5011 与 AGENTS.md #0.1 明令禁止的消费端猜维度,把「零个/多个候选时响亮报错并列出候选」换成一个安静的错窗口。今天没有运行时路径撞上(DatasetWidget走selection: unknown),但类型声明不是 dormant code。钉子(裁定 4)
加在
queryDataset.test.ts(与既有运行时用例同处),沿用本包spec-symbol-batch6.test.ts的Assert/Equal/HasKeyidiom:Assert< Equal< Parameters< ObjectStackAdapter['queryDataset'] >[1], SpecDatasetSelection > >—— 用Equal而非双向extends是刻意的:必填的dimension仍然可赋给可选的,双向extends在漂移方向上也是绿的,结构恒等才是手写副本漂移时过不去的那一条。compareTo: { kind: 'previousPeriod' }(不带 dimension)必须原样送到服务端。这一条守的是 adapter 永远不会替执行器"帮忙"补一个 dimension。key-vs-value: 这里守的是
compareTo省略dimension是否为合法的授权/编写形状(一个 key/shape 事实),所以用编译期可赋值性断言;真正的 value 判决(哪个维度被平移)在执行器,本仓无从断言。反向验证 —— 方向是先预测再跑的
预测:把旧内联方言塞回去 →
type-check变红,而vitest保持绿。 因为 vitest 不做类型检查,而那条运行时透传断言测的是 JSON 序列化,类型声明动不了它。这个钉子的承重门是tsc --noEmit,不是 vitest —— 写在这里免得后来的人误以为跑一遍 vitest 就守住了。两个方向都如预测:
type-check红,13 条错误,每条都对得上一处具名漂移:vitest 同时仍是绿的(
Test Files 1 passed (1) / Tests 12 passed (12)),与预测一致。随后已复原。消费者核查(裁定 3)
queryDataset不在@object-ui/types的DataSource接口上,只在本包具体类上,所以类型面只有直接调用方会碰到。全仓调用点三处,全部经any/局部unknown取值,因此没有类型耦合:packages/plugin-charts/src/ObjectChart.tsx:452——ds: anypackages/app-shell/…/previews/DatasetPreview.tsx:73—— 自行 cast 成(d: unknown, s: unknown) => …packages/app-shell/…/previews/ReportPreview.tsx—— 同上--filter "...@object-ui/data-objectstack" type-check(本包 + 33 个下游)全绿,exit 0,零 error,无需任何消费端改动 —— 文件面因此严格停在packages/data-objectstack/。(首轮跑出的
Cannot find module '@object-ui/data-objectstack'是新 worktree 没建产物的 §9 陷阱镜像,先--filter "...@object-ui/data-objectstack..." build后即消失,不是本改动引起。)验证
Changeset:
.changeset/dataset-selection-spec-type-3613.md,patch(公开类型面被修正),英文正文。刻意没做的事
object/dimensionFields/drillRawRows,又不含sql),不是AnalyticsResult的重述,换掉它是判断题而非机械替换。但它的fields[]有同族漂移(漏了percentScale,而 objectui#3136 明令渲染端必须按它缩放),已按 PD [WIP] Enhance every detail of the designer #10 单开 data-objectstack 的 queryDataset 返回类型漏掉 fields[].percentScale,而 #3136 明令渲染端必须按它缩放 #3752(未认领、未打标,连两个方案与倾向一并写在里面),不并入本 PR。DatasetSelection。 从本包再导出一次就是给同一类型开第二条命名路径 —— 正是本 PR 要消灭的东西;调用方直接从@objectstack/spec/contracts取。DatasetWidget/ pivot 代码(裁定 5,DatasetWidget 的交叉表(pivot ≥2 维)丢弃 __compare 列:配了 compareTo 的 pivot 静默无对比 #3614 分单),也没碰content/docs/releases/。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Generated by Claude Code