@finebi/finebi-cli 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -142
- package/package.json +38 -35
- package/skills/finebi-cli-agent/SKILL.md +133 -0
- package/skills/finebi-cli-agent/agents/openai.yaml +7 -0
- package/skills/finebi-cli-agent/references/analysis-dsl-api.md +318 -0
- package/skills/finebi-cli-agent/references/artifact-ordering.md +29 -0
- package/skills/finebi-cli-agent/references/command-workflows.md +194 -0
- package/skills/finebi-cli-agent/references/dashboard-dsl-api.md +1025 -0
- package/skills/finebi-cli-agent/references/dsl-handoff-contract.md +195 -0
- package/skills/finebi-cli-agent/references/file-to-dashboard.md +65 -0
- package/skills/finebi-cli-agent/references/formula-basics.md +102 -0
- package/skills/finebi-cli-agent/references/formula-contexts.md +66 -0
- package/skills/finebi-cli-agent/references/formula-functions.md +247 -0
- package/skills/finebi-cli-agent/references/formula-generation.md +121 -0
- package/skills/finebi-cli-agent/references/formula-glossary.md +17 -0
- package/skills/finebi-cli-agent/references/formula-help-boundaries.md +87 -0
- package/skills/finebi-cli-agent/references/formula-help-index.md +264 -0
- package/skills/finebi-cli-agent/references/formula-parameters-aggregate.md +143 -0
- package/skills/finebi-cli-agent/references/formula-parameters-analysis.md +223 -0
- package/skills/finebi-cli-agent/references/formula-parameters-date.md +236 -0
- package/skills/finebi-cli-agent/references/formula-parameters-math-logic.md +271 -0
- package/skills/finebi-cli-agent/references/formula-parameters-text.md +217 -0
- package/skills/finebi-cli-agent/references/formula-recipes-analysis.md +124 -0
- package/skills/finebi-cli-agent/references/formula-recipes-text-date.md +86 -0
- package/skills/finebi-cli-agent/references/formula-semantics.md +39 -0
- package/skills/finebi-cli-agent/references/formula-syntax.md +70 -0
- package/skills/finebi-cli-agent/references/formula-troubleshooting.md +63 -0
- package/skills/finebi-cli-agent/references/formula-validation.md +36 -0
- package/skills/finebi-cli-agent/references/formula.md +37 -0
- package/skills/finebi-cli-agent/references/handoff-contract.md +210 -0
- package/skills/finebi-cli-agent/references/mapping-rules.md +423 -0
- package/skills/finebi-cli-agent/references/mutation-confirmation-contract.md +150 -0
- package/skills/finebi-cli-agent/references/scenario-workflows.md +75 -0
- package/skills/finebi-cli-agent/references/widget-dsl-api-examples.md +457 -0
- package/skills/finebi-cli-agent/references/widget-dsl-api.md +1340 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/package.json +11 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/access-key-contract.js +2 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/access-key.js +174 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/auth-failure.js +18 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/auth-headers.js +21 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/auth.js +116 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/branding.js +31 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/browser-auth.js +331 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/capability.js +122 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/config-permissions.js +87 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/config.js +189 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/dynamic-command.js +324 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/error-catalog.js +482 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/errors.js +22 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/help.js +467 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/index.js +1343 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/install-skill.js +87 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/output-limits.js +188 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/output.js +33 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/profiles.js +158 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/schema-options.js +265 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/schema-validator.js +194 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/skill-files.js +94 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli-runner-core.mjs +399 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli-runner.mjs +29 -0
- package/src/error-catalog.js +12 -0
- package/src/help.js +15 -0
- package/src/index.js +6 -1
- package/src/install-skill.js +87 -0
- package/src/skill-files.js +94 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# 映射规则
|
|
2
|
+
|
|
3
|
+
## 1. 图表类型映射
|
|
4
|
+
|
|
5
|
+
只允许从下表生成图表类型。
|
|
6
|
+
|
|
7
|
+
表中覆盖 Widget DSL 的规范图表类型,并保留交接对象的既有别名。
|
|
8
|
+
图形通道和字段约束见 `widget-dsl-api.md`;CLI 模板参数以 `finebi-cli widget template --help` 为准,
|
|
9
|
+
不要把交接对象别名直接当作模板参数。
|
|
10
|
+
|
|
11
|
+
| 交接对象 `chartType` | 生成结果 |
|
|
12
|
+
|--------------------|----------------------------|
|
|
13
|
+
| `LINE` | `.chart().partitionLine()` |
|
|
14
|
+
| `sliceLine` | `.chart().partitionLine()`,分区折线图 |
|
|
15
|
+
| `rangeArea` | `.chart().rangeArea()`,两个 AREA 指标依次为下界和差值(上界减下界),标签绑定下界和上界 |
|
|
16
|
+
| `radar` | `.chart().radar()`,折线雷达图;使用 LINE Series,形状及标记通过 `radarOptions` 配置 |
|
|
17
|
+
| `seriesLine` | `.chart().seriesLine()`,多系列折线图 |
|
|
18
|
+
| `custom` | `.chart().custom()`,自定义组合图;x/y 使用维度或指标 Series,可组合多种图形 |
|
|
19
|
+
| `box` | `.chart().box()`,基础箱型图;绘图指标用 `box(measure).granularity(dim)`,按明细粒度形成分布 |
|
|
20
|
+
| `PIE` | `.chart().pie()` |
|
|
21
|
+
| `ROSE` | `.chart().rose()`,玫瑰图 |
|
|
22
|
+
| `MULTI_PIE` | `.chart().multiPie()`,多层饼图 |
|
|
23
|
+
| `KPI_CARD` | `.chart().kpi()` |
|
|
24
|
+
| `GAUGE` / `SLOT_GAUGE` | `.chart().slotGauge()` |
|
|
25
|
+
| `POINT_GAUGE` | `.chart().pointGauge()` |
|
|
26
|
+
| `SEMI_POINT_GAUGE` | `.chart().semiPointGauge()` |
|
|
27
|
+
| `RING_GAUGE` | `.chart().ringGauge()` |
|
|
28
|
+
| `H_THERMOMETER_GAUGE` | `.chart().horizontalThermometerGauge()` |
|
|
29
|
+
| `V_THERMOMETER_GAUGE` | `.chart().verticalThermometerGauge()` |
|
|
30
|
+
| `GROUP_TABLE` | `.chart().table()` |
|
|
31
|
+
| `CROSS_TABLE` | `.chart().crossTable()` |
|
|
32
|
+
| `DETAIL_TABLE` | `.chart().detailTable()` |
|
|
33
|
+
| `CLUSTERED_COLUMN` | `.chart().seriesColumn()` |
|
|
34
|
+
| `BAR` | `.chart().seriesColumn()` |
|
|
35
|
+
| `SERIES_COLUMN` / `seriesColumn` | `.chart().seriesColumn()` |
|
|
36
|
+
| `SLICE_COLUMN` / `sliceColumn` | `.chart().sliceColumn()` |
|
|
37
|
+
| `STACK_COLUMN` / `stackColumn` | `.chart().stackColumn()` |
|
|
38
|
+
| `COMPARE_COLUMN` / `compareColumn` | `.chart().compareColumn()` |
|
|
39
|
+
| `waterFall` | `.chart().waterFall()`,x 维度、y 指标、size 指标均直接用字段引用 |
|
|
40
|
+
| `point` | `.chart().point()`,x/y 各一个字段、至少一轴为指标;`granularity` 区分数据点;不使用 Series |
|
|
41
|
+
| `bubble` | `.chart().bubble()`,size 绑定一个指标,color 或 granularity 绑定维度;允许 x/y 多指标字段并共享图形通道,优先空轴样例,不使用 Series |
|
|
42
|
+
| `rectTree` | `.chart().rectTree()`,color 分类、size 单指标、label 子组;大小、分组维度、图形及 x/y 字段均可选,不使用 Series 或自定义排序 |
|
|
43
|
+
| `wordCloud` | `.chart().wordCloud()`;词语维度放 text、权重指标放 size,可同时放 color;textSize 控制字号,数量仅作模板示范 |
|
|
44
|
+
| `HEAT` / `heat` | `.chart().heat()`;热力区域图,x/y 均绑定维度,热度指标放 color,可选 size 指标;不使用 Series 或地理经纬度 |
|
|
45
|
+
| `AREA_MAP` / `areaMap` | `.chart().areaMap()`,区域地图;x/y 使用同一地理维度的 longitude/latitude 分组,指标放 color,不配置 size |
|
|
46
|
+
| `POINT_MAP` / `pointMap` | `.chart().pointMap()`,点地图;x 经度、y 纬度,size 表达大小,可配置 color |
|
|
47
|
+
| `LINE_MAP` / `lineMap` | `.chart().lineMap()`,流向地图;x 经度、y 纬度,必须用 lineConnect 绑定连线指标 |
|
|
48
|
+
| `HEAT_MAP` / `heatMap` | `.chart().heatMap()`,地理热力图;x 经度、y 纬度,热度指标放 heatColor,可配置 size,不使用 color |
|
|
49
|
+
| `sankey` | `.chart().sankey()`,起终点为 sankeyStart/sankeyEnd,流量为 size;showNodeName 显示节点名称,不强制字段数量 |
|
|
50
|
+
| `funnel` | `.chart().funnel()`,阶段维度放 color 或 y,指标放 size;多指标连续 size,配 colorMetricName 或 granularityMetricName;标签可开 showConversionRate/showMeasureSum |
|
|
51
|
+
|
|
52
|
+
瀑布图按已确认的分类顺序映射排序,y 的累计口径与 size 的原始变化量分别声明;完整示例见
|
|
53
|
+
[Widget DSL API 瀑布图编码](widget-dsl-api.md#421-瀑布图编码)。
|
|
54
|
+
|
|
55
|
+
说明:
|
|
56
|
+
|
|
57
|
+
- `LINE` 默认生成单系列分区折线 `partitionLine()`;编码携带 `SERIES` 维度时生成多系列折线 `seriesLine()`。
|
|
58
|
+
- `CLUSTERED_COLUMN` 与旧值 `BAR` 统一按当前 `seriesColumn()` 入口处理。
|
|
59
|
+
- CLI 模板命令中的 `BAR` / `CLUSTERED_COLUMN` 对应 `sliceColumn`;需要多系列柱形模板时显式使用 `--chart-type seriesColumn`。
|
|
60
|
+
- 不要猜测 `STACKED_COLUMN`、`BAR_CHART`、`COLUMN`、`AREA`、`SCATTER`、`HEATMAP` 或任何未在表中列出的值。
|
|
61
|
+
|
|
62
|
+
## 2. 字段构造
|
|
63
|
+
|
|
64
|
+
字段只能基于交接对象中已经解析确认的来源类型与可读字段身份构造。
|
|
65
|
+
|
|
66
|
+
示例:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
from("销售明细").dim("region")
|
|
70
|
+
from("销售明细").sum("sales_amount")
|
|
71
|
+
from("销售明细").avg("profit_rate", "平均利润率")
|
|
72
|
+
model("销售指标集").dataset("订单明细").dim("地区")
|
|
73
|
+
model("销售指标集").metrics().sum("销售额")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
规则:
|
|
77
|
+
|
|
78
|
+
- 维度字段使用 `dim(...)`
|
|
79
|
+
- `datasetKey` 来源使用 `from(sourceTableName)`;`modelKey` 来源使用 `model(modelName)`。两者互斥,不能因为名称相同而改写来源类型
|
|
80
|
+
- 维度 grouping 按字段类型选择:日期非默认粒度用
|
|
81
|
+
`DimensionGrouping.dateGranularity(...)`;文本选值自定义分组用
|
|
82
|
+
`DimensionGrouping.textGroups([DimensionGrouping.textGroup(...)], otherGroupName)`;数值维度连续区间用
|
|
83
|
+
`DimensionGrouping.numberIntervals(bounds...)`
|
|
84
|
+
- 默认分组不要显式生成:日期 YEAR_MONTH_DAY、文本相同值分组使用 `dim(fieldName)`;
|
|
85
|
+
只需要展示别名时使用 `dim(fieldName, null, alias)`。**数值维度按 `widget-dsl-api.md` 择一表达**:
|
|
86
|
+
`DimensionGrouping.numberSameValues()`(相同值为一组,落 `ID_GROUP`)与 `numberIntervals(...)`(区间分组,
|
|
87
|
+
落 `NUMBER_GROUP`+负载)必须显式写出;只有明细表的原始数值列(不分组)才省略 grouping——
|
|
88
|
+
转维度副本(`TRANSFORM_FROM_NUMBER`)省略 grouping 会得到区间分组,不是相同值为一组
|
|
89
|
+
- 文本分组值必须是非 null 字符串且不能跨组重复;数值边界至少两个、有限且严格递增
|
|
90
|
+
- 总行数使用 `from(sourceTable).count([alias])`;显式依赖维度使用 `count(DimRef[, alias])`
|
|
91
|
+
- 字段去重计数使用 `from(sourceTable).countDistinct(fieldName[, alias])`(已保存计算字段使用
|
|
92
|
+
`measureID("配置 ID").countDistinct()`);只对文本/日期字段及其计算字段变体成立,且该字段须已
|
|
93
|
+
`measure transform --as measure` 转成指标形态——未转换时组件命令报 `UNSUPPORTED_FEATURE` 并指路该命令;
|
|
94
|
+
计算字段变体的公式引用聚合形态字段时同样被拒绝(平台取数校验会再包一层去重计数,报聚合嵌套聚合)
|
|
95
|
+
- 模型级指标必须进入 `metrics()` 子命名空间;模型指标集不提供根级维度或记录数
|
|
96
|
+
- 指定字段聚合使用 `sum/avg/max/min/measure(...)`
|
|
97
|
+
- 主题内已保存计算字段必须使用 `measureID("配置 ID").sum()`;作为维度时使用
|
|
98
|
+
`measureID("配置 ID").dim()`;需要显式分组时使用
|
|
99
|
+
`measureID("配置 ID").dim(DimensionGrouping.*(...))`。数值计算字段维度走指标转维度路径,
|
|
100
|
+
文本和日期计算字段直接绑定,grouping 必须与字段类型兼容;**聚合型计算字段没有维度形态**,
|
|
101
|
+
写 `.dim()` 会被组件命令拒绝(报错给出可执行路径),只能用 `.sum()` 等指标形态
|
|
102
|
+
- 计算字段分**聚合型**与**行级**(`calculated-field info/add/validate` 输出的 `aggregate`:
|
|
103
|
+
`true` = 公式含 `SUM_AGG` 等聚合函数、按组产单值;`false` = 行级逐行计算)。聚合型只能作图表
|
|
104
|
+
指标、富文本动态字段(`.sum()`)或控件 `sortByField` 排序目标;**绑控件筛选字段必须用行级**
|
|
105
|
+
(聚合型保存时直接报错)
|
|
106
|
+
- 指定字段的 `COUNT` 聚合没有糖方法,也没有通用入口(`measure(..., "COUNT", ...)` 立即失败):记录数使用
|
|
107
|
+
`count([alias])` / `count(DimRef[, alias])`,字段去重计数使用 `countDistinct(fieldName[, alias])`
|
|
108
|
+
- 如果交接对象提供了 aggregation,且存在对应糖方法,优先用糖方法;否则使用 `measure(fieldName, aggregation, alias)`
|
|
109
|
+
- 不要把 `displayName`、`transferName`、`datasetId`、`modelId` 或 `fieldId` 当作 DSL 字段标识
|
|
110
|
+
- 模型指标使用 `model(modelName).metrics()`;模型表字段使用 `model(modelName).dataset(datasetName)`;模型计算字段使用 `model(modelName).calculated()`。同一作用域内模型字段展示名不唯一时返回 `BLOCKED`
|
|
111
|
+
|
|
112
|
+
## 3. 编码角色映射
|
|
113
|
+
|
|
114
|
+
### 3.1 通用图表族(PIE / GAUGE)
|
|
115
|
+
|
|
116
|
+
`PIE`、`GAUGE` 使用以下映射。
|
|
117
|
+
|
|
118
|
+
| 角色 | 生成结果 |
|
|
119
|
+
|------------|------------------|
|
|
120
|
+
| `CATEGORY` | `.x(dimRef)` |
|
|
121
|
+
| `VALUE` | `.y(measureRef)` |
|
|
122
|
+
|
|
123
|
+
GAUGE 的专属配置直接跟在 `.chart().gauge()`(或具体仪表盘类型方法)之后:
|
|
124
|
+
|
|
125
|
+
| 配置 | DSL |
|
|
126
|
+
|---|---|
|
|
127
|
+
| 类型 | `.gaugeType(GaugeType.POINT_GAUGE)` 或 `.ringGauge()` 等快捷方法 |
|
|
128
|
+
| 独立指针 | `.pointer(measureRef)`;圆形/半圆可追加多个,其余子类型仅一个。不能与 `.y()`、横轴指标或字段级图形覆盖混用,可用 `.x(dimRef)` 分面 |
|
|
129
|
+
| 目标值 | `.target(number)` 或 `.target(measureRef)` |
|
|
130
|
+
| 样式 | `.gaugeStyle(style)`、`.gaugeScale(scale)`、`.roundRadius(enabled)` |
|
|
131
|
+
| 颜色 | `.gaugeColor(name, color)` |
|
|
132
|
+
|
|
133
|
+
未知角色直接阻塞。
|
|
134
|
+
|
|
135
|
+
### 3.2 折线图族
|
|
136
|
+
|
|
137
|
+
`LINE` 使用以下映射。
|
|
138
|
+
|
|
139
|
+
| 角色 | 生成结果 |
|
|
140
|
+
|------------|------------------------|
|
|
141
|
+
| `CATEGORY` | `.x(dimRef)` |
|
|
142
|
+
| `VALUE` | `.y(line(measureRef))` |
|
|
143
|
+
| `SERIES` | 图表层 `.color(dimRef)` |
|
|
144
|
+
|
|
145
|
+
规则:
|
|
146
|
+
|
|
147
|
+
- 无 `SERIES` 编码时生成 `.chart().partitionLine()`;携带一个 `SERIES` 维度时生成 `.chart().seriesLine()`
|
|
148
|
+
- 多个 `VALUE` 按声明顺序生成多个 `.y(line(...))`
|
|
149
|
+
- 当前 writer 最多允许一个 `SERIES` 维度
|
|
150
|
+
- 如果 `SERIES` 指向 measure,直接阻塞
|
|
151
|
+
|
|
152
|
+
### 3.3 KPI 指标卡
|
|
153
|
+
|
|
154
|
+
`KPI_CARD` 只支持以下映射。
|
|
155
|
+
|
|
156
|
+
| 角色 | 生成结果 |
|
|
157
|
+
|---------|-----------------------|
|
|
158
|
+
| `VALUE` | `.text(measureRef)` |
|
|
159
|
+
|
|
160
|
+
规则:
|
|
161
|
+
|
|
162
|
+
- 至少需要一个 `VALUE`
|
|
163
|
+
- 多个 `VALUE` 按声明顺序生成多个 `.text(...)`
|
|
164
|
+
- 不要生成 `.x(...)` 或 `.y(...)`
|
|
165
|
+
- `CATEGORY` 和其他角色直接阻塞
|
|
166
|
+
|
|
167
|
+
### 3.4 柱状图图表族
|
|
168
|
+
|
|
169
|
+
`CLUSTERED_COLUMN`、`BAR`、`SERIES_COLUMN`、`SLICE_COLUMN`、`STACK_COLUMN`、`COMPARE_COLUMN` 使用以下映射。
|
|
170
|
+
|
|
171
|
+
| 角色 | 生成结果 |
|
|
172
|
+
|------------|-----------------------|
|
|
173
|
+
| `CATEGORY` | `.x(dimRef)` |
|
|
174
|
+
| `VALUE` | `.y(bar(measureRef))` |
|
|
175
|
+
| `SERIES` | 图表层 `.color(dimRef)` |
|
|
176
|
+
|
|
177
|
+
规则:
|
|
178
|
+
|
|
179
|
+
- 多个 `VALUE` 按声明顺序生成多个 `.y(bar(...))`
|
|
180
|
+
- 当前 writer 最多允许一个 `SERIES` 维度
|
|
181
|
+
- 如果 `SERIES` 指向 measure,直接阻塞
|
|
182
|
+
- 除非交接对象明确区分每个序列的颜色语义,否则不要生成低层 `SeriesModel.color(...)`
|
|
183
|
+
|
|
184
|
+
### 3.4.1 警戒线与趋势线
|
|
185
|
+
|
|
186
|
+
值轴需求使用 `.valueAxis(measureRef, ValueAxis.builder()...build())`。双 y 轴要求纵轴区域为 POLY,
|
|
187
|
+
字段 `sum/avg` 不能代替区域指标聚合;主场景使用 `seriesLine/seriesColumn`。
|
|
188
|
+
先确定全部指标左右归属,再给每侧配置范围、标签、逆序、对数和标题;同侧配置不得互相冲突。
|
|
189
|
+
金额/百分比等展示格式仍用 `.numberFormat()`,刻度边界使用原始值,不按百万等单位手工缩放。
|
|
190
|
+
范围公式只生成 `AxisValue.fixed/min/max/average` 与四则运算,引用同轴完整指标身份;
|
|
191
|
+
不要拼接内部 ID 或任意平台公式。完整 API 见 widget-dsl-api.md §4.7.2。
|
|
192
|
+
|
|
193
|
+
`LINE` 与柱状图族只有在分析线目标能唯一对应一个实际绘制的 `VALUE` 时才生成:
|
|
194
|
+
|
|
195
|
+
```js
|
|
196
|
+
.warningLine(valueMeasureRef, WarningLine.fixed("目标", 100))
|
|
197
|
+
.warningLine(valueMeasureRef, WarningLine.average("平均"))
|
|
198
|
+
.trendLine(valueMeasureRef, TrendLine.linear("趋势"))
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
- target 必须复用该 `VALUE` 生成的完整 `MeasureRef`,包括聚合、alias 和快速计算;不能按字段名重建。
|
|
202
|
+
- 警戒线只映射固定值、平均值、最小值、最大值;趋势线只映射线性、指数、对数、多项式。
|
|
203
|
+
- 任意公式、多项式阶数、负预测、非 `#RRGGBB` 颜色或非绘制指标目标直接阻塞,不猜测降级。
|
|
204
|
+
- 警戒线默认虚线并显示值;趋势线默认实线且不预测。只在交接值偏离默认时生成修饰器。
|
|
205
|
+
|
|
206
|
+
### 3.5 分组表
|
|
207
|
+
|
|
208
|
+
| 角色 | 生成结果 |
|
|
209
|
+
|------------|------------------------|
|
|
210
|
+
| `CATEGORY` | `.dimension(dimRef)` |
|
|
211
|
+
| `ROW` | `.dimension(dimRef)` |
|
|
212
|
+
| `VALUE` | `.measure(measureRef)` |
|
|
213
|
+
| `METRIC` | `.measure(measureRef)` |
|
|
214
|
+
|
|
215
|
+
### 3.6 交叉表
|
|
216
|
+
|
|
217
|
+
| 角色 | 生成结果 |
|
|
218
|
+
|----------------------|------------------------|
|
|
219
|
+
| `ROW` | `.row(dimRef)` |
|
|
220
|
+
| `COLUMN` | `.col(dimRef)` |
|
|
221
|
+
| `VALUE` | `.measure(measureRef)` |
|
|
222
|
+
| `METRIC` | `.measure(measureRef)` |
|
|
223
|
+
| `METRIC_NAME_ROW` | `.metricNameInRow()` |
|
|
224
|
+
| `METRIC_NAME_COLUMN` | `.metricNameInCol()` |
|
|
225
|
+
|
|
226
|
+
规则:
|
|
227
|
+
|
|
228
|
+
- 不要生成 `.columnDimension(...)`
|
|
229
|
+
- 如果交接对象要求表达超出 `col(...) + metricNameInCol()` 的复合列表头语义,直接阻塞
|
|
230
|
+
|
|
231
|
+
### 3.7 明细表
|
|
232
|
+
|
|
233
|
+
所有选中列统一生成 `.col(dimRef)`。
|
|
234
|
+
|
|
235
|
+
规则:
|
|
236
|
+
|
|
237
|
+
- 即使源字段是数值列,在明细表 DSL 中也保持 `dim(...)`
|
|
238
|
+
- 明细表不要生成 `.measure(...)`
|
|
239
|
+
|
|
240
|
+
## 4. 过滤映射
|
|
241
|
+
|
|
242
|
+
常用交接操作符映射如下;组件完整算子、值类型与组合条件见 [过滤 API](widget-dsl-api.md#6-过滤上下文):
|
|
243
|
+
|
|
244
|
+
| 交接对象操作符 | 生成结果 |
|
|
245
|
+
|------------|-----------------------------------------------|
|
|
246
|
+
| `EQ` / `NE` | `.filter().field(fieldRef).eq(value)` / `.ne(value)` |
|
|
247
|
+
| `GT` / `GTE` / `LT` / `LTE` | 对应 `.gt(value)` / `.gte(value)` / `.lt(value)` / `.lte(value)` |
|
|
248
|
+
| `IN` | `.filter().field(fieldRef).in(values)` |
|
|
249
|
+
| `BETWEEN` | `.filter().field(fieldRef).between(from, to)` |
|
|
250
|
+
| `NOT_NULL` | `.filter().field(fieldRef).notNull()` |
|
|
251
|
+
| `TOP_N` / `BOTTOM_N` | `.filter().field(fieldRef).topN(value)` / `.bottomN(value)` |
|
|
252
|
+
|
|
253
|
+
规则:
|
|
254
|
+
|
|
255
|
+
- 保持交接对象中的过滤顺序
|
|
256
|
+
- 参数以 `parameter("参数名")` 引用,先核实主题参数目录与类型;各算子参数类型见 `widget-dsl-api.md` §6。
|
|
257
|
+
- 如果某个操作符需要的参数形态超出当前支持范围,直接阻塞
|
|
258
|
+
- schema 不明确的 widget 或 dashboard 自由过滤保持阻塞
|
|
259
|
+
|
|
260
|
+
## 5. 排序映射
|
|
261
|
+
|
|
262
|
+
当前只支持以下排序方向:
|
|
263
|
+
|
|
264
|
+
- `SortOrder.ASC`
|
|
265
|
+
- `SortOrder.DESC`
|
|
266
|
+
- `SortOrder.asc`
|
|
267
|
+
- `SortOrder.desc`
|
|
268
|
+
|
|
269
|
+
生成方式:
|
|
270
|
+
|
|
271
|
+
- 维度排序 -> `.sort(dimRef, SortOrder.ASC|SortOrder.DESC)`
|
|
272
|
+
- 指标排序 -> `.sort(measureRef, SortOrder.ASC|SortOrder.DESC)`
|
|
273
|
+
|
|
274
|
+
规则:
|
|
275
|
+
|
|
276
|
+
- 如果交接对象把 `sort` 挂在 `VALUE` 编码上,则按对应 measure 排序
|
|
277
|
+
- 如果交接对象把 `sort` 挂在维度编码上,则按对应维度排序
|
|
278
|
+
- 自定义顺序数组、依赖 measure 的维度排序,以及混合排序元数据,除非已被归一化为当前 DSL 形态,否则都保持阻塞
|
|
279
|
+
|
|
280
|
+
## 6. Dashboard 翻译
|
|
281
|
+
|
|
282
|
+
### 6.1 组件引用
|
|
283
|
+
|
|
284
|
+
统一使用:
|
|
285
|
+
|
|
286
|
+
```js
|
|
287
|
+
.
|
|
288
|
+
content()
|
|
289
|
+
.reference("组件名")
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
适用于:
|
|
293
|
+
|
|
294
|
+
- `widgetRefs[].source == "REQUESTED"`
|
|
295
|
+
- `widgetRefs[].source == "EXISTING"`
|
|
296
|
+
|
|
297
|
+
不要在 dashboard 产物内联 `WidgetDsl.create(...).build()`。
|
|
298
|
+
|
|
299
|
+
### 6.2 布局兜底
|
|
300
|
+
|
|
301
|
+
默认根结构(自适应配置省略 = 设计器默认):
|
|
302
|
+
|
|
303
|
+
```js
|
|
304
|
+
.
|
|
305
|
+
presentation()
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
位置规则:
|
|
309
|
+
|
|
310
|
+
- 如果交接对象已经提供与 `position(name, col, row, wCols, hRows)` 兼容的显式网格坐标,直接使用
|
|
311
|
+
- 如果只有一个组件引用,且 `layout.description` 明确表达首屏全宽含义(如 `铺满`、`全宽`、`首屏`、`full width`、`full screen`
|
|
312
|
+
),生成 `.position(name, 0, 0, 72, 16)`
|
|
313
|
+
- 其他情况不要猜测位置,直接依赖自动布局
|
|
314
|
+
|
|
315
|
+
### 6.3 不支持的 dashboard 合成
|
|
316
|
+
|
|
317
|
+
以下情况在交接协议扩展出确定性结构之前一律阻塞:
|
|
318
|
+
|
|
319
|
+
- 从自由格式 dashboard 过滤中合成 `ControlItem`
|
|
320
|
+
- 从叙述性布局文本中合成 `TextItem`
|
|
321
|
+
- 仅依据 prose 推断联动、跳转或移动端配置
|
|
322
|
+
|
|
323
|
+
### 6.4 文本组件动态字段值(RichText)
|
|
324
|
+
|
|
325
|
+
文本组件 content 支持动态字段值(见 `docs/dsl/dynamic-field-value-design.md`):
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
TextItem.of("kpi", RichText.of()
|
|
329
|
+
.line("总销售额:", from("Sales").sum("amount"), " 元")
|
|
330
|
+
.line("按地区:", from("Sales").dim("region"))
|
|
331
|
+
.build())
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
- 每行 `String | FieldRef | styled(...) | fieldValue(...)` 混排;聚合与分组由 FieldRef 承载(`.sum()` / `.avg()` / `FieldRefs.count(...)` / `dim(名, DimensionGrouping.dateGranularity(...))`)
|
|
335
|
+
- 字段级配置(排序/时间格式/数值格式/指标条件/显示默认数据)用 `fieldValue(ref).….build()` 链表达;**分组与汇总方式不在此处写**(由字段引用承载)
|
|
336
|
+
- 平台占位符与 fieldsConfig 由 adapter 生成,DSL 不写
|
|
337
|
+
- 字段来源两类:主题字段直引 `from(table)`;引用同一仪表板其他组件的字段用 `componentField("组件名", fieldRef)`(分组/汇总须与目标组件一致,见 dashboard-dsl-api §6.8)
|
|
338
|
+
|
|
339
|
+
## 7. 禁止生成的 DSL 面
|
|
340
|
+
|
|
341
|
+
不要生成:
|
|
342
|
+
|
|
343
|
+
- `graphic(...)`
|
|
344
|
+
- `columnDimension(...)`
|
|
345
|
+
- `FieldConfigModel.of(...)`
|
|
346
|
+
- `fieldsConfig(...)`
|
|
347
|
+
- `BoundsModel.of(...)`
|
|
348
|
+
- `ControlItem.Builder.bounds(...)`
|
|
349
|
+
- `TextItem.withBounds(...)`
|
|
350
|
+
- `GraphicModel.builder()`
|
|
351
|
+
- `GraphicChannelModel.of(...)`
|
|
352
|
+
- `EncodingField.of(...)`
|
|
353
|
+
- `EncodingField.metricName()`
|
|
354
|
+
- `EncodingField.series(...)`
|
|
355
|
+
|
|
356
|
+
这些入口要么只适用于 Java,要么对于当前文本 DSL 生成不稳定。
|
|
357
|
+
|
|
358
|
+
## 普通分类轴
|
|
359
|
+
|
|
360
|
+
`categoryAxis(dim, CategoryAxis.builder()...build())` 绑定唯一 x/y 维度。
|
|
361
|
+
Model → dimension 私有 settings.categoryAxis → Bean 反读 → DSL 输出使用同一 placement;
|
|
362
|
+
不写 widgetMeasures holder 或 viewAttr.left/right。ALL 对应 ellipsis;interval(n) 为非负整数原值透传。
|
|
363
|
+
纵向 labelAlign 非 AUTO 时必须配置自定义 labelFont;自动标题填当前维度名且 modified=false。
|
|
364
|
+
本期不含钻取。完整 API 与默认值见 widget-dsl-api.md §4.7.3。
|
|
365
|
+
|
|
366
|
+
## 表格指标属性
|
|
367
|
+
|
|
368
|
+
明细表的原始数值列使用 DimRef 目标与 `TableColor/TableShape`,判断源同样使用原始数值 DimRef;用法见 [widget-dsl-api.md §4.7.4](widget-dsl-api.md#474-表格指标属性)。
|
|
369
|
+
|
|
370
|
+
分组表/交叉表用 `tableColor/tableShape`,目标是已绑定 MeasureRef 或 `TableTarget.ALL_MEASURES`;固定样式用 `fixed`,判断字段用 `by`,即使规则为空也保留绑定。排名、平均值差、不一致或极值标志使用现有计算能力,属性只按数值区间标记;排序单独声明。最后命中规则生效,逐指标覆盖全部指标。
|
|
371
|
+
不生成属性专属过滤接口;组件 `.filter()` 可能影响结果行和共享字段分组。指标形状 `baseStyle` 不提供未匹配兜底。
|
|
372
|
+
维度使用 DimRef 目标与 `TableDimensionColor/TableDimensionShape`,按 `TableCondition` 显示文本条件标记;`otherwise` 提供颜色/形状兜底。明细表文本/日期列支持此配置。分组表/交叉表的 `tableDrill` 引用主题共享目录,三参数颜色/形状接口设置各层样式。完整 API 与边界见 widget-dsl-api.md §4.7.4。
|
|
373
|
+
|
|
374
|
+
## 表格合计行列映射
|
|
375
|
+
|
|
376
|
+
分组表合计行使用 totalRows(TableTotal.rows()...build());交叉表还支持 totalColumns(TableTotal.columns()...build())。总合计与组内合计分别映射 grand/subtotal,小计维度用 fields([DimRef]) 明确选择。位置对两类合计共同生效,样式分别使用 grandStyle/subtotalStyle。指标合计方式使用 totalBy(measure, TotalCalculation.X),不得把「合计平均」误写成修改指标聚合 avg()。完整 API 见 [widget-dsl-api.md](widget-dsl-api.md)「分组表、交叉表合计行列」。
|
|
377
|
+
|
|
378
|
+
## 组件内边距
|
|
379
|
+
|
|
380
|
+
用户要求组件留白、四边内边距或指标卡无内边距时,使用 chart 链的 padding(Padding.of()...build())。
|
|
381
|
+
四边分别用 top/right/bottom/left;上下联动用 vertical,左右联动用 horizontal,全部为非负整数像素。
|
|
382
|
+
只设置用户要求的边;四边清零用 vertical(0).horizontal(0),恢复默认用空 Builder。
|
|
383
|
+
适用于全部图表与三种表格。完整语句见 [Widget API](widget-dsl-api.md)「组件内边距」。
|
|
384
|
+
|
|
385
|
+
## 表格字体
|
|
386
|
+
|
|
387
|
+
用户要求组件的表头/表身字体时,在三种表格的 chart 链使用 `tableFont(WidgetTableFont.of()...build())`;
|
|
388
|
+
自动模式用 `WidgetTableFont.auto()`。表头对齐用 `TableTextFont.align`,表身维度/指标分别用
|
|
389
|
+
`dimensionAlign/measureAlign`;未要求的属性省略以继承主题。仪表板全局字体仍用 TemplateStyle 的 TableFont。
|
|
390
|
+
字号须使用 [Widget API](widget-dsl-api.md)「表格字体(组件样式)」列出的 18 个离散值,未指定时省略以继承主题;完整语句见该节。
|
|
391
|
+
|
|
392
|
+
## 表格行高
|
|
393
|
+
|
|
394
|
+
用户要求调整表头/表身行高或自动换行时,在三种表格的 chart 链使用
|
|
395
|
+
`tableRowHeight(TableRowHeight.of().headerHeight(48).headerWrap(true).bodyHeight(100).bodyWrap(true).build())`。
|
|
396
|
+
仅配置用户要求的部分;高度 16–200,默认 32,换行默认关闭。开启后高度为最大适应高度。
|
|
397
|
+
完整语句见 [Widget API](widget-dsl-api.md)「表格行高(组件样式)」。
|
|
398
|
+
|
|
399
|
+
## 表格格式
|
|
400
|
+
|
|
401
|
+
分页、序号、行数信息、行列展开和冻结统一放在 `tableFormat(TableFormat.of()...build())`。
|
|
402
|
+
禁止展开收起交互使用 TableExpansion.DISABLED;允许交互时以 COLLAPSED / EXPANDED 指定初始状态。
|
|
403
|
+
明细表用 frozenColumns(0) 关闭冻结,用 1–10 冻结前 n 列;分组/交叉表用 freezeDimensions。
|
|
404
|
+
“显示总行数/总页数”用 TableFormat.totalRows/totalPages,合计行列继续使用 chart.totalRows/totalColumns。
|
|
405
|
+
完整适用范围、默认值和示例见 [Widget API](widget-dsl-api.md)「表格格式(组件样式)」。
|
|
406
|
+
|
|
407
|
+
## 表格风格
|
|
408
|
+
|
|
409
|
+
组件的展示类型、风格、主题色使用 `tableStyle(TableStyle.of()...build())`。
|
|
410
|
+
多列/树状/列表对应 `form(TableForm.MULTI_COLUMN/TREE/LIST)`,只允许分组表、交叉表;
|
|
411
|
+
风格 1–3 对应 `style(TableStyle.STYLE1/STYLE2/STYLE3)`,三种表格均支持。
|
|
412
|
+
表格自适应同样放在 TableStyle:标准适应用 `adaptive(TableAdaptive.STANDARD)`,
|
|
413
|
+
宽度适应(显示全部列)用 `adaptive(TableAdaptive.FIT_WIDTH)`;省略即标准适应,三种表格均支持。
|
|
414
|
+
自动主题色用 `themeColor("")` 或省略,透明用 `themeColor("transparent")`,具体色直接传颜色字符串。
|
|
415
|
+
仪表板全局主题继续用 TemplateStyle;组件未声明风格、主题色时继承主题。
|
|
416
|
+
完整语句见 [Widget API](widget-dsl-api.md)「表格风格(组件样式)」。
|
|
417
|
+
|
|
418
|
+
## 组件背景
|
|
419
|
+
|
|
420
|
+
图表与表格的标题背景用 `titleBackground(WidgetBackground.of()...build())`,
|
|
421
|
+
组件背景用 `widgetBackground(...)`。模式选择 `color` / `image` / `style`;自动颜色用空字符串,
|
|
422
|
+
自定义图片先上传,再引用附件 ID。圆角/边框仅放在组件颜色背景;内置样式编号按标题和组件分别解释。
|
|
423
|
+
完整方法、样式名称及示例见 [Widget API](widget-dsl-api.md)「组件背景(图表与表格通用)」。
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# 变更计划、删除确认与失败清理契约
|
|
2
|
+
|
|
3
|
+
## 1. 目的
|
|
4
|
+
|
|
5
|
+
本契约约束所有非只读命令的计划、复检、执行、验证和失败清理。`add`、`update`、`data-update` 及其他非删除命令不需要人工确认;命令名为 `delete` 的计划必须等待人工确认。人工确认只授权一个内容冻结的删除计划,不授权后续变化或自动清理。
|
|
6
|
+
|
|
7
|
+
## 2. 冻结计划
|
|
8
|
+
|
|
9
|
+
计划必须使用可见且唯一的 `planId`。非删除计划生成后可以直接复检执行;删除计划必须在一个完整 JSON 代码块中展示并等待确认:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"planVersion": "1.0",
|
|
14
|
+
"planId": "PLAN-20260817-001",
|
|
15
|
+
"state": "AWAITING_CONFIRMATION",
|
|
16
|
+
"runtime": {
|
|
17
|
+
"profile": "<profile-name>",
|
|
18
|
+
"capabilityFingerprint": "<fingerprint>"
|
|
19
|
+
},
|
|
20
|
+
"stages": [
|
|
21
|
+
{
|
|
22
|
+
"stage": 1,
|
|
23
|
+
"operation": "widget.delete",
|
|
24
|
+
"mutation": true,
|
|
25
|
+
"target": {
|
|
26
|
+
"resourceId": "<verified-widget-id>",
|
|
27
|
+
"expectedName": "各记录人回款金额"
|
|
28
|
+
},
|
|
29
|
+
"argv": ["finebi-cli", "widget", "delete", "--id", "<verified-widget-id>", "--json"],
|
|
30
|
+
"files": [],
|
|
31
|
+
"expectedEffect": "删除一个组件",
|
|
32
|
+
"risk": "永久删除 FineBI 资源",
|
|
33
|
+
"cleanupCapability": "NONE",
|
|
34
|
+
"precheck": ["目标组件 ID、名称和归属已通过 widget.info 核验"],
|
|
35
|
+
"verification": ["widget.info 应确认资源不存在"]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"batchPolicy": {
|
|
39
|
+
"stopOnFirstFailure": true,
|
|
40
|
+
"cleanupOrder": "REVERSE_DEPENDENCY_ORDER",
|
|
41
|
+
"cleanupRequiresConfirmation": true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
示例中的尖括号仅说明字段含义。实际请求确认时不得使用占位 ID;删除目标必须来自实时只读查询并精确到唯一 ID。只有执行结果才能提供的创建后 ID,应明确标记其来源,执行清理时必须替换为服务端实际返回值。
|
|
47
|
+
|
|
48
|
+
## 3. 确认语法和失效条件
|
|
49
|
+
|
|
50
|
+
仅对包含 `delete` 的计划接受明确指向当前计划的确认:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
确认执行 PLAN-20260817-001
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
“可以”“继续”“按之前方案”“设计确认”均不足以授权执行。计划出现以下任一变化时,确认立即失效:
|
|
57
|
+
|
|
58
|
+
- `resource.command`、参数或阶段顺序变化;
|
|
59
|
+
- 目标名称、ID、归属或当前状态变化;
|
|
60
|
+
- 文件 canonical path、内容或 SHA-256 变化;
|
|
61
|
+
- capability/help/schema 或 `mutation` 属性变化;
|
|
62
|
+
- 影响范围、清理能力或验证方式变化;
|
|
63
|
+
- 批次增加、删除或替换任何命令。
|
|
64
|
+
|
|
65
|
+
失效后生成新 `planId` 并重新请求确认。
|
|
66
|
+
|
|
67
|
+
## 4. 批次规则
|
|
68
|
+
|
|
69
|
+
- 一个计划可以包含完成同一业务目标所需的多个依赖阶段。
|
|
70
|
+
- 每个阶段必须先通过只读验证,才可执行下一阶段。
|
|
71
|
+
- 默认首个失败立即停止,禁止无条件继续。
|
|
72
|
+
- `delete` 操作必须独立成批,不得与 add/update/data-update 混合确认;非删除命令可以在完成复检后自动执行。
|
|
73
|
+
- `cleanupCapability: NONE` 的操作必须单独执行或处于批次最后。
|
|
74
|
+
- `cleanupCapability: RESTORE_ONLY` 的操作只有在旧状态已被完整读取、能够生成并验证恢复命令时,才可位于批次中间;否则按 `NONE` 处理。
|
|
75
|
+
- 不允许把更新已有资源后的 delete 描述为回滚,因为它会扩大数据损失。
|
|
76
|
+
|
|
77
|
+
## 5. 执行前复检
|
|
78
|
+
|
|
79
|
+
每个非只读计划执行前都重新执行所有冻结前提;删除计划在收到确认后复检:
|
|
80
|
+
|
|
81
|
+
1. 重读 capability/help 并计算 `capabilityFingerprint`。
|
|
82
|
+
2. 重查目标 ID、名称、归属和冲突状态。
|
|
83
|
+
3. 重算文件 canonical path 和 SHA-256。
|
|
84
|
+
4. 对比完整 `argv`、阶段顺序、影响和清理能力。
|
|
85
|
+
|
|
86
|
+
存在差异时不得执行任何写阶段。报告差异并生成新计划。
|
|
87
|
+
|
|
88
|
+
## 6. 阶段记账
|
|
89
|
+
|
|
90
|
+
每个阶段记录:
|
|
91
|
+
|
|
92
|
+
- 是否开始、是否返回、是否验证通过;
|
|
93
|
+
- 服务端实际返回的资源 ID 和名称;
|
|
94
|
+
- 响应中的成功项、失败项和警告;
|
|
95
|
+
- 实际执行的 JSON `argv`;
|
|
96
|
+
- 对应只读验证证据;
|
|
97
|
+
- 清理命令所需的实际参数。
|
|
98
|
+
|
|
99
|
+
只有返回成功且只读验证符合预期,阶段才算成功。响应可能部分成功时逐项记账,不得只记录顶层状态。
|
|
100
|
+
|
|
101
|
+
## 7. 失败清理计划
|
|
102
|
+
|
|
103
|
+
某阶段失败时,停止后续写操作,并构建新的清理计划。清理范围包括:
|
|
104
|
+
|
|
105
|
+
1. 失败阶段之前所有已经成功执行且验证通过的写资源;
|
|
106
|
+
2. 失败阶段响应或回查明确证明已成功创建的部分资源;
|
|
107
|
+
3. 不包括未开始、未产生资源或无法证明成功的操作。
|
|
108
|
+
|
|
109
|
+
清理命令按依赖关系逆序排列。优先使用服务端实际返回的 ID;不得根据名称猜测删除目标。
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"cleanupPlanVersion": "1.0",
|
|
114
|
+
"cleanupPlanId": "CLEANUP-20260817-001",
|
|
115
|
+
"sourcePlanId": "PLAN-20260817-001",
|
|
116
|
+
"failedStage": 3,
|
|
117
|
+
"state": "AWAITING_CONFIRMATION",
|
|
118
|
+
"commands": [
|
|
119
|
+
{
|
|
120
|
+
"sourceStage": 2,
|
|
121
|
+
"resourceId": "<actual-dashboard-id>",
|
|
122
|
+
"operation": "dashboard.delete",
|
|
123
|
+
"argv": ["finebi-cli", "dashboard", "delete", "--id", "<actual-dashboard-id>", "--json"],
|
|
124
|
+
"verification": ["dashboard.dsl 应确认资源不存在"]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"sourceStage": 1,
|
|
128
|
+
"resourceId": "<actual-widget-id>",
|
|
129
|
+
"operation": "widget.delete",
|
|
130
|
+
"argv": ["finebi-cli", "widget", "delete", "--id", "<actual-widget-id>", "--json"],
|
|
131
|
+
"verification": ["widget.info 应确认资源不存在"]
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"unavailableCleanup": []
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
示例仅表达结构,所有参数必须以实时 help 和实际响应为准。
|
|
139
|
+
|
|
140
|
+
如果资源没有安全删除命令,将其放入 `unavailableCleanup`,包含实际资源 ID、原操作、不能删除或恢复的原因及最小人工处理建议。即使无法完整清理,也必须列出其余可生成的删除命令。
|
|
141
|
+
|
|
142
|
+
包含 `delete` 的清理计划不自动执行。仅在用户回复 `确认执行 <cleanupPlanId>` 且复检通过后执行;仅包含非删除补偿命令的清理计划按普通计划自动执行。清理过程同样首错即停并逐项验证。
|
|
143
|
+
|
|
144
|
+
## 8. 清理能力分类
|
|
145
|
+
|
|
146
|
+
- `DELETE`:资源由本计划创建,运行时存在准确的 delete 命令。
|
|
147
|
+
- `RESTORE_ONLY`:资源原本存在,只能用冻结的旧状态恢复,不能安全删除。
|
|
148
|
+
- `NONE`:运行时没有删除能力,或操作本身不可逆且没有完整恢复输入。
|
|
149
|
+
|
|
150
|
+
关系替换属于 `RESTORE_ONLY`;新建关系才可以用 `relationship.delete`。`analysis-ds.add` 只创建新表,可对响应 `ids` 中的每个实际 ID 生成 delete;`analysis-ds.update` 覆盖步骤链,只能在旧 DSL 可完整恢复时标记 `RESTORE_ONLY`(该命令由服务器内部试用开关控制,正式版默认不存在,能力清单没有时 `analysis-ds` 不存在步骤覆盖类变更)。公共数据集当前没有 delete 命令,因此 `public-ds.add` 属于 `NONE`。
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Widget 与 Dashboard 场景工作流
|
|
2
|
+
|
|
3
|
+
## 1. 适用范围
|
|
4
|
+
|
|
5
|
+
仅当用户要根据业务描述创建或更新 Widget/Dashboard,且命令需要 JS DSL 文件时使用本文件。资源查询和执行边界仍遵循 `SKILL.md`、`command-workflows.md` 与 `mutation-confirmation-contract.md`;仅 `delete` 命令需要人工确认。
|
|
6
|
+
|
|
7
|
+
本 Skill 负责解析语义和消费已验证 JS 制品,不生成、修改、解析或修复 DSL。
|
|
8
|
+
|
|
9
|
+
## 2. 解析业务语义
|
|
10
|
+
|
|
11
|
+
收集目标主题、字段来源(分析表或模型指标集)、字段、组件/仪表板名称、图表或布局意图、聚合、过滤、排序、已有组件引用和更新目标。分配稳定 artifact key,例如 `widget:payment_by_recorder` 或 `dashboard:payment_overview`。
|
|
12
|
+
|
|
13
|
+
依赖只读命令解析:
|
|
14
|
+
|
|
15
|
+
1. 遍历 `subject.search` 全部分页并用 `subject.info` 确认主题。
|
|
16
|
+
2. 需要按表名解析数据集时,先用用户提供的完整名称搜索 `analysis-ds` 和 `public-ds`,遍历全部分页,并按返回的真实名称全等判断唯一精确匹配。
|
|
17
|
+
3. 没有精确匹配时,对分析表和公共数据集执行关键词搜索,结合字段、位置、主题归属、资源类型、引擎类型和用户意图选择候选;多个候选合理时要求用户选择。
|
|
18
|
+
4. 选定资源为 `public-ds` 时,将其作为来源按前置资源流程创建目标主题内的 `analysis-ds`,使用写响应中的全部实际 ID 逐一调用 `analysis-ds.info` 和必要的 `preview`;转换完成前不得构建语义交接对象,也不得继续查询数据连接。
|
|
19
|
+
5. 只有数据集层没有合理候选时,才查询数据连接和物理表,并按前置资源流程创建所需数据集;不得把物理表标识当作数据集 ID。
|
|
20
|
+
6. 对最终选定或新建的分析表调用 `analysis-ds.info` 确认主题归属、引擎类型和字段元数据。DIRECT 不以 `dataStatus`、`updateStatus` 或摘要 `usable` 阻断,不执行数据集 `data-update`,使用只读 `preview` 验证查询能力;SPIDER 保留状态、可用性和 preview 校验。
|
|
21
|
+
7. 用 `subject.info` 和必要的 `widget.info` 确认已有组件引用。
|
|
22
|
+
8. 对 Dashboard 按名称引用的组件,证明每个已有引用全局唯一,并证明待创建组件名称在创建前不存在冲突。
|
|
23
|
+
9. 模型指标集不走数据集搜索。先从 `subject.info` 返回的 `resources.models` 查看摘要,再用 `model.search --subject-id <subjectId>` 遍历主题内候选,并对选定模型调用 `model.info --subject-id <subjectId> --id <modelId>` 获取指标、数据集字段和模型计算字段。若用户要求使用的指标集尚未属于主题,单独用 `public-ds.search` 确认唯一的 `type=METRIC_SET` 来源和目标主题可编辑性;执行 `model.add --subject-id <subjectId> --id <sourceId>` 后,使用响应中的主题内模型 ID 执行 `model.info` 回查,才可构建交接对象。来源 ID 不得传给 `model.info/delete` 或写进 DSL。模型目录命令未出现在实时 capability 时,既有 `widget dsl` 输出中的 `model(...)` 可作为只读证据;否则进入 `BLOCKED`。不得查询同名分析表后改写成 `model(...)`。
|
|
24
|
+
|
|
25
|
+
不得把公共数据集 ID 当作 Analysis DS ID。物理 DSL 字段语义使用 `analysis-ds.info.name` 返回的表名和字段原始 `name`;模型 DSL 字段语义使用已确认的模型展示名和字段展示名。数据集、模型和字段 ID 仅作为可选验证证据,不进入 DSL。
|
|
26
|
+
|
|
27
|
+
## 3. 前置资源
|
|
28
|
+
|
|
29
|
+
语义交接对象只能引用已经存在并已验证的主题、数据集、字段和组件。如果用户同时要求创建这些前置资源:
|
|
30
|
+
|
|
31
|
+
1. 先按通用命令流程规划相应 add 操作并完成复检后执行,无需请求人工确认。
|
|
32
|
+
2. 执行成功后使用实际资源 ID 完成只读回查。
|
|
33
|
+
3. 再构建 Widget/Dashboard 语义交接对象。
|
|
34
|
+
|
|
35
|
+
搜索命中公共数据集时,`analysis-ds.add` 属于交接所需的前置资源创建:DSL 的 `from(表原始名)` 必须引用已验证的公共数据集原始名(`public-ds search` 返回的 `id`,全局唯一),目标主题通过 `--subject-id` 传入;执行后逐一回查服务端返回的分析表实际 ID。不得在前置资源尚未创建时向交接对象填入公共数据集 ID、预期 ID 或占位 ID。
|
|
36
|
+
|
|
37
|
+
## 4. 语义交接确认
|
|
38
|
+
|
|
39
|
+
按照 `handoff-contract.md` 构建完整 JSON 交接对象并展示。语义交接确认只确认制品生成输入,不授权执行任何 CLI 写命令。用户修改任何影响制品的语义后,原交接确认及已有制品映射均失效。
|
|
40
|
+
|
|
41
|
+
## 5. JS 制品映射
|
|
42
|
+
|
|
43
|
+
仅接收调用方、用户或实际可用生成工作流提供的完整 `artifact key -> absolute JS file path` 映射。每个路径必须:
|
|
44
|
+
|
|
45
|
+
- 是现有 `.js` 文件的绝对路径;
|
|
46
|
+
- 由用户明确提供,或位于为当前任务创建的隔离临时目录;不得根据当前工作目录猜测 `cli/` 或其他项目路径;
|
|
47
|
+
- 成功解析为 canonical/real path;
|
|
48
|
+
- 与其他 artifact key 的规范路径不同;
|
|
49
|
+
- 在冻结写计划时记录 SHA-256。
|
|
50
|
+
|
|
51
|
+
缺少 key、路径不存在、路径重复或文件被修改时进入 `BLOCKED` 或废止当前写计划,不在本 Skill 中修复文件。
|
|
52
|
+
|
|
53
|
+
## 6. 创建 Widget
|
|
54
|
+
|
|
55
|
+
为每个制品生成独立 `widget.add` 阶段。执行前按通用流程冻结完整 JSON `argv` 并复检;`widget.add` 无需人工确认。创建后使用服务端实际 ID 调用 `widget.info`,需要时再调用 `widget.preview`。
|
|
56
|
+
|
|
57
|
+
批量创建多个 Widget 时,每个阶段保存实际 ID。后续阶段失败时,按逆序为所有已成功创建的 Widget 生成 `widget.delete` 清理命令,并请求新的清理确认。
|
|
58
|
+
|
|
59
|
+
## 7. 创建 Dashboard
|
|
60
|
+
|
|
61
|
+
新 Widget 阶段先于 Dashboard 阶段。只有所有 Widget 创建成功、写后回查通过,且每个已有/新建引用仍能唯一解析时,才允许进入 `dashboard.add`。
|
|
62
|
+
|
|
63
|
+
若 Widget 阶段或 Dashboard 阶段失败,停止后续阶段,并对已成功创建的资源按 Dashboard、Widget 的逆依赖顺序生成 delete 清理计划。清理计划不得自动执行。
|
|
64
|
+
|
|
65
|
+
## 8. 更新 Widget 或 Dashboard
|
|
66
|
+
|
|
67
|
+
更新前用 `info`/`preview` 收集目标当前状态,并确认用户指向精确 ID。冻结新的 JS 文件路径和 SHA-256。只有确实存在经过验证、能够恢复旧状态的 JS 制品时,才标记 `RESTORE_ONLY`;否则标记 `NONE` 并将更新放在批次最后或独立执行。
|
|
68
|
+
|
|
69
|
+
删除更新过的既有资源不是回滚,不得作为失败清理方案。
|
|
70
|
+
|
|
71
|
+
## 9. 阻断条件
|
|
72
|
+
|
|
73
|
+
以下情况进入 `BLOCKED`:运行时缺少所需命令;资源/字段/引用存在歧义;主题或数据集归属不匹配;JS 映射不完整或文件无效;无法证明 Dashboard 引用组件唯一;运行时 schema 与冻结计划不一致。
|
|
74
|
+
|
|
75
|
+
只是在等待语义确认、删除计划确认或包含删除的清理计划确认时,状态应为 `AWAITING_CONFIRMATION`,不是 `BLOCKED`。
|