Uh oh!
There was an error while loading. Please reload this page.
fix(data-objectstack): queryDataset 透传服务端 drillRanges,恢复日期分桶钻取 (#3813) - #3824
Merged
Merged
Conversation
…eryDataset (#3813) The runtime half of the hand-picked-envelope family #3613/#3752 fixed on the type face. queryDataset rebuilds its result by picking keys off the REST payload one by one, and drillRanges was never in the list — so the analytics service's #1752 date-range drill sidecar was dropped by the only real adapter in this repo, while five consumer sites were already reading it (DatasetWidget.tsx:471/:593, DatasetReportRenderer.tsx:316/:431/:855). The effect was a MISSING drill, not a degraded one. A dateGranularity dimension groups a span of records into one bucket, which equality filters cannot express, so service-analytics excludes date dims from dimensionFields/drillRawRows and sends a half-open [gte, lt) range per row instead (analytics-service.ts:807+). For a chart or report grouped only by time, drillRanges is therefore the only thing that can make canDrill = !!object && (drillDims.length > 0 || !!drillRanges?.length) true — dropped, the whole drill entry point disappeared. A mixed date + non-date grouping kept its drill but lost the time bound, so clicking June's bar opened every month (a superset). Neither side's tests could see it: the dashboard/report suites mock their own data source and feed drillRanges in directly, and the adapter's suite never asserted the key. The new tests mock the envelope the SERVER actually sends — bare (res.json, no success/data wrapper), carrying sql, and for a date-only grouping carrying object + drillRanges and NO dimensionFields/drillRawRows — then assert the key arrives verbatim and row-aligned, that the consumers' own canDrill predicate is true, and that the shared buildDatasetDrillFilter scopes the list to the clicked bucket (both halves for a mixed grouping). The entry type is @object-ui/core's DatasetDrillRange BY REFERENCE, not a local { field, gte, lt } copy: it is the single in-repo declaration of the shape (what buildDatasetDrillFilter accepts and what both renderers type their state with) and @objectstack/spec does not own it yet, so a restatement would be a third dialect. drillRawTotals (#3214) is deliberately NOT added: zero consumers in this repo, so passing it through would add a declared-but-unexercised key with no user-facing effect. Filed separately as a finding. Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 8, 2026
CollaboratorAuthor
✅ 验收通过(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt)—— undraft + auto-merge。 核验(净 diff 3 文件):透传按原样(仅数组性校验,缺失保持 undefined 不发明空数组);条目类型引用 core 共享 Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 8, 2026 18:01
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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#3813
问题
queryDataset的返回是逐项挑键重建的,drillRanges从来不在那份名单里 —— 于是服务端 framework#1752 的日期区间钻取旁路,被本仓唯一的真实 adapter 静默丢掉,而消费端五处已经在读它。影响不是"钻取变弱",而是"钻取整块消失":
dateGranularity维度把一个时间跨度归成一个桶,等值过滤表达不了,所以service-analytics故意把日期维度排除在dimensionFields/drillRawRows之外,改为每行发一条半开区间[gte, lt)。因此对只按时间分组的图表/报表,drillRanges是唯一能让为真的东西 —— 键被挑掉,整个钻取入口就没了。日期 + 非日期混合分组时钻取还在,但过滤条件缺时间边界,点 6 月的柱子打开的是该地区全时段(超集)。
两侧测试都看不见:dashboard/report 的用例 mock 自己的 data source 直接喂
drillRanges,adapter 自己的用例从没断言过这个键。跨仓证据链
objectui(基线
origin/main@d83f6b3de,即 PR #3817 落地后的现状):packages/data-objectstack/src/index.ts:3355(改前)return { rows, fields, object, dimensionFields, drillRawRows, totals };—— 挑键处,无drillRanges。packages/data-objectstack/src/index.ts:3257是本仓唯一的queryDataset实装(apps/console/src/dataSource.ts:14就是原样 re-export,中间没有二次挑键的包装层)。packages/plugin-dashboard/src/DatasetWidget.tsx:471(读取)、:593(canDrill)、packages/plugin-report/src/DatasetReportRenderer.tsx:316(读取)、:431(行钻hasRange)、:855(透视单元格钻hasRange)。packages/core/src/utils/dataset-format.ts:165的DatasetDrillRange与buildDatasetDrillFilter(把区间落成 ObjectQL{ $gte, $lt })。objectstack(只读实证,@
b4872a868):packages/services/service-analytics/src/analytics-service.ts:741起:等值钻取块的drillDims只收!!d.field && d.type !== 'date'的维度 —— 日期维度被排除,所以只按日期分组时dimensionFields/drillRawRows根本不产出。:807起:rangeDims非空时result.drillRanges = result.rows.map(...),并重新设上object(注释写明:只按时间分组的报表也需要 base object 才能打开列表)。packages/rest/src/rest-server.ts:6284:res.json(result)—— 裸下发,不裁剪、也没有{ success, data }包装。改动
packages/data-objectstack/src/index.ts,两处:const drillRanges = Array.isArray((data as any)?.drillRanges) ? (data as any).drillRanges : undefined;,并加入返回字面量。与drillRawRows同一档校验强度 —— 只校验数组性,不发明空数组(缺失保持undefined)。drillRanges?: Array< Record< string, DatasetDrillRange > >,条目类型是@object-ui/core的DatasetDrillRange,引用而非重述。为什么引用而不是在 adapter 里写
{ field, gte, lt }(#3613/#3752 的同一条纪律):DatasetDrillRange是本仓这个形状的唯一声明 —— 它既是buildDatasetDrillFilter接受的类型,也是 DatasetWidget / DatasetReportRenderer 给 state 标的类型;@objectstack/spec目前不拥有这个形状(产出侧的AnalyticsResultWithDrill是service-analytics的局部类型,未导出),所以共享的仓内接口就是当下唯一可用的契约,在 adapter 里重述一遍等于造它的第三种方言。边界值声明为unknown也是诚实的:这里和drillRawRows一样只校验了数组性,没校验条目内部。没有改成整体透传信封(spread):#3752 已经把"这个信封不是
AnalyticsResult、且刻意不返回sql"钉成了 pin,整体透传会把sql一起带出并让那条 pin 变红 —— 契约边界是故意的,不是遗漏。测试(
packages/data-objectstack/src/queryDataset.test.ts,+4)三条运行时用例都 mock 服务端真实回包形状,而不是理想形状(这正是两侧测试此前失明的原因):裸信封(无
success/data包装)、带sql、且只按日期分组时只有object+drillRanges,没有dimensionFields/drillRawRows。drillRanges原样、按行对齐地到达调用方(通过声明的类型读,不用as any);顺带断言dimensionFields/drillRawRows确为undefined(fixture 一旦被"补全"成理想形状,这条用例就不再覆盖"drillRanges是唯一钻取依据"的场景了);再用消费端自己的判据算出drillDims === []且canDrill === true(issue 的验收锚);最后用共享的buildDatasetDrillFilter断出{ close_date: { $gte: '2026-06-01', $lt: '2026-07-01' } }—— 落到点中的那个桶。NA,不是行里的显示标签 "North America")与时间边界 —— 这正是"超集"那一半影响的反面。drillRanges保持undefined,不发明空数组。Equal钉住条目类型与DatasetDrillRange结构同一(本地{ field: string; gte: string; lt: string }复制品会让这行红)、钉住"按行对齐的数组"与"可选";并在 data-objectstack 的 queryDataset 返回类型漏掉 fields[].percentScale,而 #3136 明令渲染端必须按它缩放 #3752 那条"信封不是 AnalyticsResult"的 pin 里补了HasKey ... 'drillRanges'。命令与输出(仓根
flock+--max-old-space-size=4096+--maxWorkers=2):消费半径定向跑(规则/数据形状的消费者在别的包里,预期零改动零变化 —— 它们 mock 自己的 data source,本改动只是给 adapter 返回多一个可选键):
反向验证(方向先判后跑)
判:①删掉运行时透传 → 只按日期那条与混合那条红,而"服务端没发"那条保持绿(它断言的是
undefined,是"不许发明空数组"的守卫,不是修复检测器 —— 按 fixture 三分法,这条通过是因为"本来就什么都没产出",必须说清而不是记作反向证据);②只删类型声明 → type-check 红、vitest 仍绿(vitest 不做类型检查)。跑,① 删
return {...}里的drillRanges:"服务端没发"那条如判定所述保持绿。
跑,② 只删返回类型里那一段声明(运行时透传留着):
两个方向都与判定一致;两次破坏后均已还原,提交内容只含上述三个文件。
drillRawTotals:按「声明即使用」不补,另立观察项 #3822服务端同样产出
drillRawTotals(analytics-service.ts:756起,framework#3214 小计行钻取),adapter 也同样把它挑掉了。本 PR 故意不补:grep -rn drillRawTotals packages appsobjectui 侧零命中;buildDatasetDrillFilter只被喂drillRawRows)。drillRanges的关键不对称:后者缺失让日期分组图表canDrill恒为 false(功能整块消失、五处在读、有等价判据可断言);前者缺失时,小计行钻取在本仓根本还没有实现面。finding,不带pm:queue)记在 queryDataset 未透传 drillRawTotals(小计行钻取,framework#3214)—— 本仓零消费者,观察项 #3822,不会随本 issue 关闭而丢。changeset
.changeset/dataset-drill-ranges-passthrough-3813.md——@object-ui/data-objectstack: patch,同 #3817 档位先例(运行时修复且用户可见:恢复日期分桶钻取入口、修掉混合分组的超集过滤)。未标major(AGENTS.md 版本策略)。未触content/docs/releases/**。Generated by Claude Code