Repository navigation
Commit 0161c7f
* wip(spec): #5022 measurement checkpoint — drillDown carrier evidence (no code yet)
断点位置:测量完成,**尚未写任何 spec 代码**。测量结果与裁决前提冲突,
倾向 needs_decision(见下)。分支上目前是空提交,仅承载证据。
## 已完成的测量(objectui @91757a7 + objectstack @41e605ec70)
### A. ObjectChart 实际读取词汇(反推自 packages/plugin-charts/src/ObjectChart.tsx)
读到的键(:602 起,经 @object-ui/core drill-down.ts):
enabled? boolean isDrillEnabled: 无 config=关;{}=开;enabled:false=关
filter? Record<string,unknown> computeDrillFilter,支持 ${event.*} 插值
title? string resolveDrillTitle,支持 ${event.*} 插值
target? 'drawer'|'dialog' :755 — **只分支 'dialog',其余一律 Sheet**
columns? string[] :762 → accessorKey/header
maxRows? number :761 → pageSize
ObjectChart **不读**:mode / view / report / sort,且 **不实现 target:'navigate'**
(navigate 只在 DrillDownDrawer.tsx:84 实现,ObjectChart 自绘 Sheet/Dialog,不走它)。
objectui 侧已有 TS 接口 DrillDownConfig(packages/types/src/data-display.ts:897),
是 5 个 widget 共享的更宽形状:{enabled,mode,target(含 navigate),filter,title,
view,report,columns,sort,maxRows}。其中 view/sort 无任何渲染器读取。
### B. 载体测量 —— 与裁决前提("渲染器已在读的 drillDown,objectui 零改动,挂 chart config")冲突
1. widget.chartConfig.drillDown → **无人读**。
DashboardRenderer.tsx 全文 0 处 chartConfig;DatasetWidget.tsx:595-605 只取
showLegend 一个键,注释自陈 "the rest of chartConfig stays unforwarded";
:632 构造的 chart schema 里没有 drillDown。
2. widget.options.drillDown → DashboardRenderer.tsx:494/:570/:531 确实读,但**全部在
isObjectProvider(widgetData) 的 legacy inline 分支内**;而 DashboardWidgetSchema
要求 dataset(dashboard.zod.ts:427,非 optional),datasetBound 恒真,
DashboardRenderer.tsx:691/:720 恒走 <DatasetWidget>,componentSchema 被丢弃。
⇒ 对 v17 合法 widget,options.drillDown 永不被读。
3. ADR-0021 正路 DatasetWidget 的 drill 是**从 dataset 结果派生、不可配置**的:
canDrill 由 dimensionFields/drillRanges 决定,DrillDownDrawer 只收
{objectName, filter, title, dataSource} —— 上述词汇一个都不认。
4. 唯一真活的面是 **react tier**:ChartConfigSchema 的键在 react 块上是**扁平 prop**
(react-blocks.ts:226-247 dataProps),所以 <ObjectChart drillDown={…}> 确实生效;
但 drillDown 既不在 spec dataProps/interactions,也不在 objectui registry inputs
(ObjectChart.tsx:822-830),SDUI save gate 会报 unknown-prop(warning,不拦)。
⇒ 结论:挂 chart config 在 **react tier 交付、dashboard 元数据面不交付**;
挂 options 在两面都不交付。任一选择都会造出 #5011 "same key, two fates" 的形状。
## 剩余步骤(若维护者裁定后继续)
1. [待裁决] 定载体:(A) 只挂 react 块契约 /(B) 挂 ChartConfigSchema 并明写
dashboard 面不转发 /(C) 挂 options 并在 objectui DatasetWidget 落地实现(非小改动)。
2. [待裁决] 定形状:chart 诚实子集 {enabled,filter,title,target:'drawer'|'dialog',
columns,maxRows} vs objectui 共享 DrillDownConfig 全集。
3. 写 ChartDrillDownSchema(strictObject,surface/history/guidance),JSDoc 与
ReportSchema.drilldown 双向点名消歧。
4. 逐键验收测试 + 调和 chart.test.ts:464 的批 15 钉子。
5. liveness/dashboard.json 分类 + check:strictness-ledger 台账行。
6. changeset(minor,v17 pre 模式);objectui 侧把 (schema as any).drillDown 换成声明类型。
7. 合 origin/main(#5154/#5162 已入队)后重跑 check:strictness-ledger + check:generated。
## 顺带发现(超范围,待立 issue)
- widget.chartConfig 在 dashboard 面只有 showLegend 落地,其余 11 个已声明键全惰性;
liveness/dashboard.json 的 chartConfig 行写 "chart-config bag forwarded",高估。
- objectui DrillDownConfig.view / .sort 无渲染器读取;ObjectChart 忽略 target:'navigate'。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
* feat(spec,lint): declare the chart segment drill as ChartDrillDownSchema, on the tier that reads it (#5022)
`drillDown` drove a real capability with no protocol declaration behind it:
objectui's ObjectChart read `(schema as any).drillDown` and really did open a
filtered record drawer from it, while `grep drillDown packages/spec` found only
a comment — the one #3752 wrote prescribing the key as a migration target. That
inverted Prime Directive #10: delivered, never declared.
Declared now, additively, at the one surface measured to read it.
## The shape is the six keys ObjectChart reads
`{ enabled?, filter?, title?, target?: 'drawer' | 'dialog', columns?, maxRows? }`,
each reverse-engineered from a read point: `isDrillEnabled` (absent = off, `{}` =
on), `computeDrillFilter`, `resolveDrillTitle`, the `'dialog'` branch, the column
map, the page size. objectui's own `DrillDownConfig` is wider because it is
shared with the table / pivot / metric widgets, and copying that union would have
promoted four keys a chart ignores — two of which NO widget reads (objectui#3354)
— into protocol-declared capabilities. Each absent key is a `guidance` entry
naming where it does apply, not a rename.
## The carrier is the react block, NOT chart config or the widget options bag
Both candidates in the issue measured dead on the dashboard metadata path:
`DashboardRenderer` never reads `chartConfig`, and `DatasetWidget` forwards
exactly one key out of it (`showLegend`); `options.drillDown` is read only in
`DashboardRenderer`'s legacy `isObjectProvider` branch, which a spec-legal v17
widget cannot reach, because `dataset` is required and `datasetBound` therefore
discards that component schema unrendered. An ADR-0021 dataset-bound widget
drills through the semantic layer and honours no drill config at all — which
`content/docs/ui/dashboards.mdx` already said. So the declaration rides
`react-blocks.ts`'s interaction overlay, deliberately not `ChartConfigSchema`,
whose members a dashboard widget's `chartConfig` also parses. A member there
would have been authorable, parse-clean and unread.
The three places an author reaches for it now answer instead of shrugging:
`chartConfig.drillDown` → the react prop; `widget.drillDown`/`widget.drilldown` →
dashboard drill is AUTOMATIC, plus both configurable drills named;
`report.drillDown` → back to the chart prop.
## Two-way disambiguation with ReportSchema.drilldown
Same word, one letter apart, two capabilities. Edit distance actively gets this
wrong — the spellings are distance 1, so a bare "did you mean" sends an author to
the boolean slot where their config object fails a second time. Both gates name
the TYPE difference, not just the spelling.
## Declared = enforced, in the same commit
`.strict()` is a property of a parse, and nothing on the react surface called
one. `validate-react-page-props.ts` now PARSES the schema against a static
`drillDown={{…}}` literal (`react-chart-drilldown-invalid`) instead of
re-deriving the rules the way `CHART_FUNCTIONS` does for `aggregate` beside it —
the fix the strictness ledger's `chart.zod.ts` row has been waiting on, shown on
one key. A value from React state is skipped: unresolvable is not wrong
(ADR-0072 D1).
## Instruments
- 批 15's pin (`chart.test.ts`) is RECONCILED, not relaxed: the ChartInteraction
prescription still must not say a bare `drillDown`, now because that schema is
reached from both tiers and cannot tell which, so the advice would be a dead
end for half its readers.
- 20 new assertions: per-key acceptance, `{}` enables, absent stays optional,
unknown key rejected with the surface named, each non-chart key rejected with
its reason, `target:'navigate'` prescribed (and a plain wrong value NOT given
that text), the carrier verdict pinned in both directions, and the published
react type string derived-checked against the schema shape.
- 10 lint-gate tests; ledger row and site counts updated (`ui/` 198 → 199).
Filed, not fixed here: #5175 (`chartConfig` delivers 1 of 12 keys on the
dashboard path; the liveness row's evidence overstates it) and objectui#3354
(`DrillDownConfig.view`/`.sort` read by nothing; `navigate` silently degrades).
Fixes #5022
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent d9971d3 commit 0161c7f
17 files changed
Lines changed: 741 additions & 29 deletions
File tree
- .changeset
- content/docs/references/ui
- docs/audits
- packages
- lint/src
- spec
- scripts
- src/ui
- skills/objectstack-ui
- contracts
- references
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | | - | |
| 21 | + | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
116 | 132 | | |
117 | 133 | | |
118 | 134 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
| 84 | + | |
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| |||
161 | 161 | | |
162 | 162 | | |
163 | 163 | | |
164 | | - | |
| 164 | + | |
165 | 165 | | |
166 | 166 | | |
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
170 | | - | |
| 170 | + | |
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
| |||
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
181 | | - | |
| 181 | + | |
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
| |||
0 commit comments