docs(api): /analytics/query 示例的 measure 拼写改为 revenue_sum,并写明合法拼写 (#6291) - #6372
Merged
Merged
Conversation
示例里 `revenue.sum` 的首段 `revenue` 不是 cube 名(cube 是 `account`), 所以它不是 cube 名限定符。#5918(PR #6292)落地后,这条示例在运行时得到 400 INVALID_FIELD 并点名 `revenue.sum` 本身,且不执行任何查询 —— 即照 文档抄的查询跑不通。 六处同批改正(请求 + 响应两个半边,避免出现「文档化的请求与文档化的 响应 key 对不上」),并在 data-api.mdx 的 /analytics/query 段落写明合法 拼写:对象自己的字段 + 聚合后缀,或 Cube 声明的 measure 名;点号仅在 作 cube 名限定符时合法。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
hotlong
marked this pull request as ready for review
August 7, 2026 15:38
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 #6291
纯文档修正。示例里
revenue.sum的首段revenue不是 cube 名(cube 是account),所以它不是 cube 名限定符,而是一个点号 measure —— 而点号 measure 今天被运行时明确拒收。一、前提复核(在 worktree 对
origin/maind8e8d9c 实测)分诊(14:05Z)把范围从正文的三处扩到六处。实测与分诊完全一致,六处:
全仓(不限
content/)同样只有这 6 处,revenue_sum改前 0 处。一处措辞订正(不影响处数与站点):分诊表把
:360记为「columns条目」,该数组在页面上的实际 JSON 键是fields,不是columns。站点、行号都对,仅名称记错。失败模式已随 #5918 变化,前提仍然成立:issue 正文描述的是 #5918 之前的行为(静默剥前缀 → 对列
sum聚合 →400点名页面上没有的sum)。#5918 的运行时半边已作为 PR #6292(commit2bc1876)落到 main。今天的实际失败是点名原拼写的 400 且不执行任何查询(下方 C 段实测)。两种情况下「照文档抄跑不通」都成立,故前提有效;只是文档从「跑不通且报错莫名」变成了「平台明确拒收的写法仍写在文档里」。二、请求 / 响应三段并排(声明 B)
改前请求已是
revenue.sum,响应 key 也是revenue.sum—— 两边一致地错。只改请求不改响应会把页面变成「文档化的请求与文档化的响应 key 对不上」,比今天更糟,所以六处同批。measures[0](data-api.mdx:338)"revenue.sum""revenue_sum"rows[0]的 key(:355→:369)"revenue.sum": 150000"revenue_sum": 150000rows[1]的 key(:356→:370)"revenue.sum": 80000"revenue_sum": 80000fields[1].name(:360→:374)"revenue.sum""revenue_sum"机器复核(把两个 json 代码块真的
JSON.parse后比对,不是肉眼):三、后缀约定的运行时证据(file:line,均为只读核实,本 PR 不动
packages/**)分诊给了这句话的措辞,但按要求没有照抄当事实,逐条回到代码核实:
packages/services/service-analytics/src/analytics-service.ts:1905-1922——mintableMeasureKey():if (member.slice(0, dot) === cubeName) return member.slice(dot + 1);否则throw invalidMemberError(...)400+INVALID_FIELD+ 点名调用方原拼写packages/services/service-analytics/src/dataset-refusal.ts:179-196——err.code = INVALID_FIELD; err.status = 400; err.member = meta.member;packages/services/service-analytics/src/analytics-service.ts:1946-1953——inferMeasure()的suffixes:_count_distinct/_sum/_avg/_average/_min/_maxcount是COUNT(*)(示例里另一个 measure)analytics-service.ts:1942-1944(inferMeasure('count'))+:1730(即席路径固定注入measures.count)analytics-service.ts:243-263(declaredMemberEntry)、:1272-1276与:1743-1748两处铸造循环都先 verbatim 查声明< field >_sum/< field >_avgpackages/services/service-analytics/src/cube-registry.ts:104-115analytics-service.ts:1390-1393与:1916均写'< field >_sum' / '_avg' / '_min' / '_max' / '_count_distinct'两处与分诊措辞不符,以实测为准:
count。 照它的措辞写死(「对象自己的字段 + 聚合后缀,或 Cube 声明的 measure 名」),同一个示例里紧挨着的"count"会显得非法 —— 而count恰恰合法。故本 PR 的句子把count明确写进合法拼写,否则这句话会和它自己脚下的示例打架。_average作为_avg的别名(analytics-service.ts:1950)。本 PR 有意不在文档里推广它:运行时自己的两处报错消息教的都是那五个规范后缀,文档跟着教规范拼写;宣传别名等于把宽松消费面写进契约。此处如实报告,不改代码。另记(不写进文档、不在本 PR 处理):
inferMeasure对无法识别的 key 兜底成sum(key)(:1963),但当字段探针可用时会被assertMeasureFields拦下。这是代码里明确注释过的 best-effort 设计,非缺陷,故未立单。四、反向验证(先申报,后执行)
声明 A —— 全覆盖
申报:改后
git grep -n 'revenue\.sum' -- content/零命中;revenue_sum命中数 == 改动处数(6)。实测:申报的字面形式被证伪 —— 而且是有意的,不是遗漏。 新增的防复发句子故意把
revenue.sum作为反例引用,所以content/里必然还剩 1 处命中。把申报按其真实意图精化为「任何可照抄的代码块内零命中」后重测:按 fence 内外分类统计,不是整文件 grep。结论:六处示例站点全部改正,页面上仅存的
revenue.sum是被明确标注为「会被拒收」的反例。声明 B —— 请求/响应一致
申报:请求
measures元素、响应行 key、fields[].name三者逐字一致。实测:CONSISTENT(见第二节的JSON.parse比对)。声明 C —— 运行时可跑
申报:能起栈就实跑改后的查询取证,起不来则如实报「未实跑」。
实测 —— 这一条是真实跑的,不是读代码推断。 在 worktree 内
pnpm --filter "@objectstack/service-analytics..." build(EXIT=0)后,直接驱动 built dist 的AnalyticsService,喂文档里那条一模一样的 query(cube: account、dimensions: ['industry']、where: {status:'active'}、limit: 100),两种策略各跑一遍:三点判读:
400点名revenue.sum本身、一条语句都没执行。revenue求和」 ——SUM(revenue),别名revenue_sum,与文档响应里的 key 逐字相同。account.revenue_sum合法且解析到同一 measure(SUM(revenue)),但输出列名保留调用方发的那个拼写(AS "account.revenue_sum")。初稿写的是「限定符会被剥掉」,实测发现只在解析度量时剥、响应列名不剥,已据实改成「响应列名保留你发的那个拼写」。取证口径:驱动用的是 stub(照搬
__tests__/dotted-measure-refusal.test.ts的makeService()形状),所以rows是我喂给它的、不构成对行 key 的证据;真正由服务产出、因而可作证据的是生成的 SQL 别名和fields[]描述符 —— 而真实驱动的行正是按 SQL 别名成 key 的。五、门禁(均在
git add之后运行)pnpm check:doc-authoring365 files clean — no bare metadata literalspnpm check:role-wordOK (44 baselined file(s), no new occurrences)pnpm check:nul-bytesscanned 6010 tracked text file(s) … no raw ASCII control bytespnpm check:docs-audit-scopescope is in sync with content/docs/: 178 hand-written doc(s)pnpm --filter @objectstack/lint check:doc-formula-expressions22 record-scoped formula example(s) across 378 files / 1397 TS blocks judged cleancheck:doc-formula-expressions首跑红过一次,原因是@objectstack/formula未构建(ERR_MODULE_NOT_FOUND … formula/dist/index.mjs)—— 新 worktree 的依赖未构建,与本改动无关;pnpm --filter "@objectstack/formula..." build后复跑 EXIT=0。没有绕过任何门。补充自检:对两个改动文件跑
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]',无命中。链接面:
lychee在本容器未安装,未能本地预扫;但本 PR 未新增/未修改任何链接(diff 里没有](或裸 URL 的增减),故对 Check Documentation Links 的风险为零 —— 以 PR 上该 job 的实际结论为准。六、不在本 PR 里
packages/**一行未动,仅只读核实。analytics 自动推断路径:measures上的关系穿越点号 member 仍被剥成基表列 ——owner.region_count_distinct静默聚合基表region(#5739 裁决未覆盖的第四个铸造点) #5918 的运行时半边已由 PR fix(service-analytics): 响亮拒收 dotted measure,点名调用方原拼写 (#5918) #6292 落地。_average别名不写进文档(理由见第三节),也不改代码。label/format键 —— 实测查询结果的fields[]由五处产出(native-sql-strategy.ts:794,799、objectql-strategy.ts:1179,1183、dataset-executor.ts:893,932,1055、preview-evaluator.ts:251-254)全部只发{ name, type },文档却标了label和format。这是同一示例的另一个事实面、且先于本单存在,按 Prime Directive chore: version packages #10 已独立立单 docs:/analytics/query的响应示例给data.fields[]标了label/format—— 运行时只发{ name, type }#6369,不在本 PR 顺手改。.changeset/:纯文档、不发布任何包,改走skip-changeset标签。Generated by Claude Code