docs(api): /analytics/query 的 fields[] 只有 name / type —— 删掉示例里的 label / format,并写明两层的分工 (#6369) - #6441
Merged
Conversation
…`label` / `format` 并写明两层的分工 (#6369) `POST /analytics/query` 的响应示例给 `data.fields[]` 三个条目都标了 `label`、 中间那个还标了 `format`,而这个端点的任何一条产出路径都只发 `{ name, type }`。 照文档写的客户端读 `fields[i].label` 渲染表头、读 `format` 格式化金额,拿到的 是 `undefined` —— 不像拼写错误那样当场 400,而是安静地渲染出空表头。 删掉这四个键,并补一段 Callout 说明两层的分工:display name 与 format 是 cube 的 metric/dimension **定义**的属性(`MetricSchema.label` / `.format`), 从 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 18:59
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 #6369
范围严格按分诊 15:52Z 钉死的路线 (a):只改
content/docs/api/data-api.mdx,不给运行时加键。一、前提复核(⛔ 不照抄任何卡片的引用块)
分诊提醒过「line 360 当时读作
"name": "revenue.sum",实现时重读」。重读结果:#6291 / PR #6372 已合并,origin/main(5d022a1)上那三行已是revenue_sum,并且行号也变了 —— 不是 359–361,而是 373–377。全程按内容定位,不按行号。每个
fields.push站点的自测(自己 grep,不照抄 issue 的表)packages/services/service-analytics/src/strategies/native-sql-strategy.ts:789Array< { name: string; type: string } >/analytics/query:794fields.push({ name: dim, type: d?.type || 'string' })/analytics/query:799fields.push({ name: m, type: 'number' })/analytics/querypackages/services/service-analytics/src/strategies/objectql-strategy.ts:1175/analytics/query:1179/:1183{ name, type }/analytics/querypackages/services/service-analytics/src/dataset-executor.ts:893 / 932 / 1052 / 1055{ name, type: 'number' };:1052是result.fields.push(f)透传packages/services/service-analytics/src/preview-evaluator.ts:252-255{ name, type }packages/drivers/driver-memory/src/memory-analytics.ts:470 / 475 / 485{ name, type }/analytics/query自测相对卡片的两处实质修正
卡片的 producer 表不完整。 issue 正文只点了
service-analytics,漏掉第二个IAnalyticsService实现packages/drivers/driver-memory/src/memory-analytics.ts(:470声明Array< { name: string; type: string } >,:475/:485两处 push)。结论不变,但审计面补全了。另外dataset-executor.ts是四处不是三处,preview-evaluator.ts是 252–255 不是 251–254。「运行时从不发
label/format」这句话本身过宽 —— 需要按端点收窄。 实测:packages/services/service-analytics/src/analytics-service.ts:1100-1101明确写着f.label = m.label/f.format = m.format(ADR-0021)。但那段在queryDataset()(:824–1183) 里,不在query()(:774–798) 里。POST /analytics/query的实际链路是packages/runtime/src/domains/analytics.ts:95-105→AnalyticsService.query()→strategy.execute()直接 return,无任何 enrich;带label/format的是另一张面POST /analytics/dataset/query(packages/rest/src/rest-server.ts:6975)。⇒ 本页这一节的前提成立,但成立的理由比 issue 正文窄。因此新增的那段话我限定在本端点,没有写成「查询结果从不带
label/format」—— 那对 dataset 面是假的。二、改前 / 改后(并排)
改前(
origin/main):改后:
外加一个
type="info"的 Callout 区块(紧跟响应示例之后),说明fields[]描述的是列而不是呈现,display name 与 format 住在 cube 的 metric/dimension 定义里。分诊原话是这条的实质:"deleting two keys without it leaves the next reader to re-derive why they were wrong to expect them"。三、新增句子的事实锚(file:line,逐条读过原文,非推断)
定义处:
packages/spec/src/data/analytics.zod.ts:56—MetricSchema:58—label: z.string().describe('Human readable label'):72—format: z.string().optional()(分诊给的:72复核无误):81—DimensionSchema.label:117—CubeSchema.measures: z.record(z.string(), MetricSchema)暴露端点:
packages/runtime/src/domains/analytics.ts:110-117—GET /analytics/meta→analyticsService.getMeta(cube)packages/services/service-analytics/src/analytics-service.ts:1184-1204— 把measure.label/dimension.label映射为titlepackages/spec/src/contracts/analytics-service.ts:89-99—CubeMeta.measures: Array< { name: string; type: string; title?: string } >线上契约旁证(本仓自己已经写对过):
packages/spec/src/api/analytics.zod.ts:68-79—AnalyticsResultResponseSchema声明fields: z.array(z.object({ name, type }))content/docs/references/api/analytics.mdx:84— 生成的参考页早已印着fields: { name: string; type: string }[]也就是说改动前的
data-api.mdx同时与 spec schema 和本仓自己的生成参考页矛盾。分诊原句是「display name 与 format ... 由
GET /analytics/meta暴露」。实测format并不由该端点暴露:getMeta投影成CubeMeta,measures 只保留{ name, type, title },format在投影中被丢弃。所以新增句子里我只对 label 说「
GET /analytics/meta以title报出」,对 format 只说它是 metric 定义的属性 —— 没有把 format 也算进「meta 暴露」。这个缺口另立了单 #6442,不在本 PR 修。四、反向验证(先申报方向,后执行)
两个 json 代码块由脚本
JSON.parse后比较(沿用 #6291 那位 dev 的做法),不肉眼比对。声明 A(键已清干净) —— 改后响应示例
fields[]每个条目的键集恰为{name, type};同一脚本跑origin/main应当红(3 个label+ 1 个format)。实测:
声明 B(请求/响应仍一致) —— #6291 刚钉的「请求
measures/dimensions↔ 响应行 key ↔fields[].name三者逐字一致」在改前已经绿,本次改动不得把它弄红。实测(改前改后各 4 项全 PASS):
声明 C(新增句子有事实支撑) —— 两个锚点必须给得出 file:line 且逐条读原文核对,不得写推断。
实测:见第三节,全部为读原文所得;并附带一处对分诊措辞的实测修正(
format不由/analytics/meta暴露)。五、门禁(
git add之后跑,逐条 EXIT)pnpm check:doc-authoringdoc authoring guard: 365 files cleanpnpm check:role-wordOK (44 baselined file(s), no new occurrences)pnpm check:nul-bytesOK (scanned 6070 tracked text file(s) ... no raw ASCII control bytes)pnpm check:docs-audit-scopescope is in sync with content/docs/: 178 hand-written doc(s)pnpm --filter @objectstack/lint run check:doc-formula-expressions22 record-scoped formula example(s) across 378 files / 1393 TS blocks judged cleanpnpm check:quick-reference-countspnpm check:adr-anchorsOK (37 anchored file(s))另:
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'自扫改动文件 —— 无命中。本 PR 正文最初写「派单提到的
check:doc-formula-expressions本仓不存在」—— 那是错的,我当时只 grep 了根package.json。它是包内脚本(packages/lint),由.github/workflows/lint.yml:914-915在TypeScript Type Check作业里跑。已补跑,EXIT=0(首次跑因新 worktree 未构建依赖而ERR_MODULE_NOT_FOUND,pnpm --filter '@objectstack/lint^...' build之后通过 —— AGENTS.md §9 那个陈旧产物陷阱的镜像)。六、CI(已等到收敛,非本地绿即报)
Check docs formula examples are valid CEL)openedrun 的首步实时重读标签时skip-changeset尚未落地),确认标签在位后rerun_failed_jobs一次 ⇒ successPR 标签读回:
["documentation", "skip-changeset"]——skip-changeset由本 agent 写入(写时标签集为空,故并集即其本身),documentation随后由 Auto Label 追加,两者共存未互相清除。Validate Package Dependencies未在本 PR 出现红(#6407 / PR #6427 的 lock 面与本 PR 零交集)。七、不在本 PR 里
fields[]增加label/format—— 分诊已按 startup-phase focus 原则裁掉(新键在有具名消费者拉动时才发布)。若出现真实消费者,那是domain:services的另一张卡。packages/**(全部只读核实)。content/docs/releases/**。skip-changeset。顺带发现,已另立单 #6442(Prime Directive #10,未自我认领)
GET /analytics/meta的已声明响应契约与实际响应不是同一个形状:plugin-rest-api.zod.ts:1230为该路由指定AnalyticsMetadataResponseSchema,后者声明data: { cubes: CubeSchema[] }(生成参考页content/docs/references/api/analytics.mdx:49已照此发布),而运行时返回的是data: CubeMeta[]—— 一个裸数组、且是更窄的投影。顺带后果就是上面第三节那处:metric 的format在投影里被丢掉,没有任何读端点暴露它。查重已做(analytics meta cubes response schema/AnalyticsMetadataResponseSchema/CubeMeta/getMeta cube metadata format label):无同题单。