@guandata/guancli 1.0.30 → 1.0.32

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.
@@ -0,0 +1,166 @@
1
+ # 指标通用配置
2
+
3
+ 本文记录原子指标、复合指标、衍生指标共享的写操作规则、通用字段和业务属性处理方式。处理任一指标创建/编辑任务时,都应先读取本文,再读取对应类型文档。
4
+
5
+ ## 环境与查询
6
+
7
+ - 默认使用用户当前已登录环境,不询问“创建到哪个 profile”。可先执行 `guancli auth status` 确认登录态。
8
+ - 只有用户明确指定其它环境时,才统一追加 `--profile <profile>`。
9
+ - 用户只给中文名称时,先查询并展示候选;查不到或有多个候选再向用户确认。
10
+ - 常用查询:
11
+ - 指标主题:`guancli metric project [keyword] -f json`
12
+ - 指标目录:`guancli metric tree -f json`
13
+ - 指标:`guancli metric search <keyword> -f json`
14
+ - 指标详情:`guancli metric get <metric_id> --brief`
15
+ - 数据集:`guancli ds search <keyword>`、`guancli ds get <dsId> --brief`
16
+
17
+ ## 通用字段
18
+
19
+ | 字段 | 中文 | 适用范围 | 说明 |
20
+ | --- | --- | --- | --- |
21
+ | `projectId` | 主题 ID | 创建/编辑 | 指标所属主题 |
22
+ | `subType` | 指标类型 | 创建/编辑 | `ATOMIC`、`COMPOSITE`、`DERIVED` |
23
+ | `name` | 指标名称 | 创建/编辑 | 最长 50;仅中文、字母、数字、下划线 |
24
+ | `engName` | 英文名称 | 可选 | 最长 50;仅字母、数字、下划线 |
25
+ | `desc` | 业务口径 | 创建/编辑 | 最长 1000;必须能解释业务含义 |
26
+ | `format` | 数据格式 | 可选 | 指标数值展示格式;省略或传 `{}` 表示默认格式 |
27
+ | `parentDirId` | 保存至/所属文件夹 | 创建必填 | 指标目录 ID |
28
+ | `businessOwner` | 责任人 | 创建必填 | 用户 ID,默认可用当前登录用户 |
29
+ | `publish` | 保存方式 | 创建/编辑 | `true` 保存并上线;`false` 保存为草稿 |
30
+ | `bizMetricId` | 关联业务字典 ID | 可选 | 关联后业务口径/业务属性通常会同步 |
31
+ | `bizAttrs` | 业务属性 | 条件必填 | 由环境中的指标属性配置决定 |
32
+ | `filter` | 业务限定/筛选 | 可选或条件必填 | 业务限定衍生指标必填 |
33
+ | `dynamicParameters` | 动态参数默认值 | 可选 | 表达式或最近 N 配置引用动态参数时使用 |
34
+
35
+ ## 数据格式 `format`
36
+
37
+ `format` 是指标数值的展示格式,创建和编辑原子指标、复合指标、衍生指标时都可设置。保存指标时写入 Web 表单使用的 UI 配置,不要写转换后的 d3 `specifier`、Excel format 或预览接口返回值。
38
+
39
+ 省略 `format` 或传 `{}` 表示使用默认格式。用户没有明确要求时,不要为了补全字段强行设置格式;用户提到“保留两位小数”“显示百分比”“人民币”“万元”“不要千分位”“加后缀”等,再按下面字段生成。
40
+
41
+ | 字段 | 中文 | 说明 |
42
+ | --- | --- | --- |
43
+ | `formatType` | 格式类型 | `NUMBER` 数值、`CURRENCY` 货币、`PERCENTAGE` 百分比、`ADVANCED` 高级自定义 |
44
+ | `decimalPlaces` | 小数位数 | `null` 表示 0 位;也可传 `1` 到 `15` |
45
+ | `useThousandsSeparator` | 是否使用千分位 | `true/false` |
46
+ | `prefix` | 前缀/货币符号 | 货币常用 `¥`、`$`、`€`、`£`;后端兼容旧字段 `currencySymbol`,新建优先写 `prefix` |
47
+ | `suffix` | 后缀 | 如 `元`、`人`、`单`、`次`;没有则省略或传空字符串 |
48
+ | `prefixUnit` | 数量级单位 | `null` 无,`K`、`M`、`万`、`亿` 或 `auto` 自动 |
49
+ | `showPrefixUnit` | 是否展示数量级单位 | 数值/货币格式可用;`prefixUnit=auto` 时应为 `true` |
50
+ | `divideDataBy` | 百分比是否除以 100 | 百分比格式可用;`1` 适合底层值是比例小数如 `0.85`,`100` 适合底层值已是百分数如 `85` |
51
+ | `customFormat` | 高级自定义格式 | `formatType=ADVANCED` 时使用;除非用户给出现成格式串,否则不要主动生成 |
52
+ | `suffixSizePercent` | 后缀字号比例 | 部分卡片展示场景使用,指标创建/编辑通常不需要 |
53
+
54
+ 常用模板:
55
+
56
+ ```jsonc
57
+ // 默认格式:省略 format 或传 {}
58
+ "format": {}
59
+
60
+ // 数值:千分位,保留 2 位小数
61
+ "format": {
62
+ "formatType": "NUMBER",
63
+ "decimalPlaces": 2,
64
+ "useThousandsSeparator": true,
65
+ "prefixUnit": null,
66
+ "showPrefixUnit": true,
67
+ "prefix": "",
68
+ "suffix": ""
69
+ }
70
+
71
+ // 货币:人民币,千分位,保留 2 位小数
72
+ "format": {
73
+ "formatType": "CURRENCY",
74
+ "decimalPlaces": 2,
75
+ "useThousandsSeparator": true,
76
+ "prefix": "¥",
77
+ "prefixUnit": null,
78
+ "showPrefixUnit": true,
79
+ "suffix": ""
80
+ }
81
+
82
+ // 百分比:底层值为 0.85 时展示为 85.00%
83
+ "format": {
84
+ "formatType": "PERCENTAGE",
85
+ "decimalPlaces": 2,
86
+ "divideDataBy": 1,
87
+ "useThousandsSeparator": false,
88
+ "prefix": "",
89
+ "suffix": ""
90
+ }
91
+
92
+ // 百分比:底层值为 85 时展示为 85.00%
93
+ "format": {
94
+ "formatType": "PERCENTAGE",
95
+ "decimalPlaces": 2,
96
+ "divideDataBy": 100,
97
+ "useThousandsSeparator": false,
98
+ "prefix": "",
99
+ "suffix": ""
100
+ }
101
+
102
+ // 数值:按万元展示
103
+ "format": {
104
+ "formatType": "NUMBER",
105
+ "decimalPlaces": 2,
106
+ "useThousandsSeparator": true,
107
+ "prefixUnit": "万",
108
+ "showPrefixUnit": true,
109
+ "prefix": "",
110
+ "suffix": "元"
111
+ }
112
+ ```
113
+
114
+ ## 业务属性 `bizAttrs`
115
+
116
+ `bizAttrs` 是管理员配置的指标自定义业务属性,不是固定字段。创建或编辑指标前读取当前环境配置:
117
+
118
+ ```bash
119
+ guancli fetch GET /api/metric-attr-config
120
+ ```
121
+
122
+ 响应关键字段:
123
+
124
+ | 字段 | 中文 | 说明 |
125
+ | --- | --- | --- |
126
+ | `id` | 属性 ID | 写入 `bizAttrs[].id` |
127
+ | `name` | 属性名称 | 用于向用户提问 |
128
+ | `description` | 属性描述 | 可作为输入提示 |
129
+ | `valueType` | 属性值类型 | `ENUM_SINGLE`、`ENUM_MULTIPLE`、`TEXT`、`TEXT_AREA` |
130
+ | `defaultValue` | 默认值 | 用户未指定且允许默认时可采用 |
131
+ | `optionValue` | 枚举选项 | 枚举单选/多选必须从这里选择 |
132
+ | `required` | 是否必填 | `true` 且 `enabled=true` 时必须收集 |
133
+ | `enabled` | 是否启用 | 只处理启用的属性 |
134
+
135
+ 处理规则:
136
+
137
+ - 只展示和写入 `enabled=true` 的属性;其中 `required=true` 是必填项。
138
+ - `ENUM_SINGLE`:`values` 只能有一个值,且必须来自 `optionValue`。
139
+ - `ENUM_MULTIPLE`:`values` 可以有多个值,且都必须来自 `optionValue`。
140
+ - `TEXT`:写入 `values[0]`,Web 单项最大 50 个字符。
141
+ - `TEXT_AREA`:写入 `values[0]`,Web 单项最大 200 个字符。
142
+ - 如果关联了业务字典 `bizMetricId`,业务口径和业务属性通常由业务字典同步;仍需确认最终 payload 中 `desc` 和 `bizAttrs` 已有值。
143
+
144
+ 示例:
145
+
146
+ ```json
147
+ "bizAttrs": [
148
+ { "id": "attr_region", "values": ["华东"] },
149
+ { "id": "attr_tags", "values": ["销售", "核心"] },
150
+ { "id": "attr_owner_note", "values": ["用于经营分析月报"] }
151
+ ]
152
+ ```
153
+
154
+ ## 保存与确认
155
+
156
+ - 先生成 JSON 文件并做 dry-run 或人工摘要,不直接提交。
157
+ - 摘要至少包含:当前环境、主题、目录、指标类型、名称、核心计算方式、适用维度/时间维度、数据格式、业务属性、保存方式。
158
+ - 用户确认后按类型执行 save-precheck 或 validate-update-impact。
159
+ - 如果校验返回冲突或影响下游资源,展示冲突指标、受影响指标、受影响卡片,并等待二次确认。
160
+ - 写入成功后回读 `guancli metric get <metric_id> --brief`。
161
+
162
+ ## 发布状态判断
163
+
164
+ - 用户说“先别上线”“保存草稿”:`publish=false`。
165
+ - 用户说“直接上线”“发布”:`publish=true`,提交前提醒会创建或更新在线指标。
166
+ - 不要把 `publish=true` 自动当成用户已经确认所有冲突;冲突/影响校验仍需要单独二次确认。
@@ -0,0 +1,146 @@
1
+ # 复合指标创建与编辑
2
+
3
+ 复合指标用于通过公式组合已有指标,例如“客单价 = 销售额 / 订单数”。
4
+
5
+ ## 触发场景
6
+
7
+ - 用户说“创建复合指标”“基于多个指标算一个指标”。
8
+ - 用户描述的口径是已有指标之间的四则运算。
9
+ - 用户要编辑一个 `subType=COMPOSITE` 的指标。
10
+
11
+ ## 创建必填信息
12
+
13
+ | 字段 | 中文 | 说明 |
14
+ | --- | --- | --- |
15
+ | `projectId` | 主题 ID | 指标所属主题 |
16
+ | `subType` | 指标类型 | 固定 `COMPOSITE` |
17
+ | `name` | 指标名称 | 最长 50 |
18
+ | `formula` | 计算公式 | 使用已有指标 ID,形如 `[metric_sales] / [metric_orders]` |
19
+ | `useExpressionMetricCommonDims` | 是否沿用公式指标共有维度 | Web 默认 `true` |
20
+ | `applicableDims` | 适用维度 | 引用指标的共有维度字段 ID 数组;手动选择时不能为空 |
21
+ | `desc` | 业务口径 | 最长 1000 |
22
+ | `parentDirId` | 保存至/所属文件夹 | 创建时需要 |
23
+ | `businessOwner` | 责任人 | 创建时需要 |
24
+ | `publish` | 保存方式 | `true` 上线,`false` 草稿 |
25
+
26
+ 专属可选字段:
27
+
28
+ | 字段 | 中文 | 说明 |
29
+ | --- | --- | --- |
30
+ | `timeDim` | 时间维度 | 最终适用维度中存在时间字段时选择一个 |
31
+
32
+ 通用可选字段见 `metric-common-fields.md`。
33
+
34
+ ## 公式与引用指标
35
+
36
+ 复合指标公式在最终 payload 中使用指标 ID,而不是指标中文名:
37
+
38
+ ```text
39
+ [metric_sales_amount] / [metric_order_count]
40
+ ```
41
+
42
+ 处理规则:
43
+
44
+ - 涉及复合指标 `formula` 时,先读取 `metric-expression-rules.md`。
45
+ - 先用 `guancli metric search <关键词> -d <projectId> -f json` 查询公式中的指标,再用 `guancli metric get <metric_id> --brief` 核对名称、类型、状态和适用维度。
46
+ - 公式只能引用数值型指标;不要引用当前正在编辑的指标本身。
47
+ - 公式支持 `+`、`-`、`*`、`/`、括号、数字和 `[指标ID]`;不要主动生成函数、窗口函数或 SQL 片段。
48
+ - 公式中的 `[xxx]` 会被后端解析为上游指标 ID,并参与循环引用校验。
49
+ - 如果用户用中文名描述公式,先转换成 ID 公式,再把“中文公式”和“ID 公式”都展示给用户确认。
50
+
51
+ ## 适用维度
52
+
53
+ 复合指标的适用维度来自公式中引用指标的共有维度:
54
+
55
+ - `useExpressionMetricCommonDims=true`:沿用表达式中指标的共用维度。需要根据引用指标详情整理共有维度;如果没有共有维度,Web 会报“计算公式来源指标无共有适用维度,请检查”。
56
+ - `useExpressionMetricCommonDims=false`:从共有维度中手动选择 `applicableDims`,至少选择一个。
57
+ - 如果最终适用维度中有时间类型字段,需要选择一个 `timeDim`。
58
+ - 不要把某个上游指标独有的维度写进 `applicableDims`。
59
+
60
+ ## 信息收集
61
+
62
+ 如果用户只说“帮我创建一个复合指标”,先收集:
63
+
64
+ 1. 指标主题和保存目录。
65
+ 2. 公式中要引用哪些已有指标;中文名先搜索确认唯一指标。
66
+ 3. 计算公式,转换成 `[metric_id]` 形式。
67
+ 4. 是否沿用共有维度;如果手动选择,确认具体维度和时间维度。
68
+ 5. 数据格式:默认、数值、货币、百分比;如需指定,确认小数位、千分位、货币符号/前后缀、数量级单位、百分比是否除以 100。
69
+ 6. 指标名称、业务口径、是否保存并上线。
70
+ 7. 责任人和必填 `bizAttrs`。
71
+
72
+ ## JSON 模板
73
+
74
+ ```json
75
+ {
76
+ "projectId": "<metric_project_id>",
77
+ "subType": "COMPOSITE",
78
+ "name": "客单价",
79
+ "engName": "avg_order_value",
80
+ "formula": "[<sales_amount_metric_id>] / [<order_count_metric_id>]",
81
+ "useExpressionMetricCommonDims": true,
82
+ "applicableDims": ["<common_dim_fd_id_1>", "<common_dim_fd_id_2>"],
83
+ "timeDim": "<time_dim_fd_id>",
84
+ "format": {
85
+ "formatType": "NUMBER",
86
+ "decimalPlaces": 2,
87
+ "useThousandsSeparator": true,
88
+ "prefixUnit": null,
89
+ "showPrefixUnit": true,
90
+ "prefix": "",
91
+ "suffix": ""
92
+ },
93
+ "desc": "销售金额除以订单数,用于衡量平均每笔订单贡献的销售额。",
94
+ "parentDirId": "<metric_dir_id>",
95
+ "businessOwner": "<user_id>",
96
+ "publish": false
97
+ }
98
+ ```
99
+
100
+ 没有时间维度时删除 `timeDim`;没有英文名称时删除 `engName`;未指定数据格式时删除 `format` 或传 `{}`。如需业务属性,按 `metric-common-fields.md` 补充 `bizAttrs`。
101
+
102
+ ## 创建步骤
103
+
104
+ `guancli metric create` 当前是原子指标专用 endpoint;复合指标创建使用 `guancli fetch`。
105
+
106
+ 1. 生成 `/tmp/composite_metric.json`。
107
+ 2. 本地/人工检查 JSON、公式引用指标、共有适用维度、必填业务属性。
108
+ 3. 按 `metric-common-fields.md` 向用户摘要并确认。
109
+ 4. 用户确认后,不调用原子指标 `save-precheck`;复合指标 Web 创建没有 save-precheck。
110
+ 5. 提交真实创建:
111
+
112
+ ```bash
113
+ guancli fetch POST /api/metric-platform/metrics/composite-metrics --stdin < /tmp/composite_metric.json
114
+ ```
115
+
116
+ 6. 响应返回指标 ID 后回读:
117
+
118
+ ```bash
119
+ guancli metric get <metric_id> --brief
120
+ ```
121
+
122
+ ## 编辑步骤
123
+
124
+ 复合指标没有原子指标的 save-precheck;主要校验公式或筛选变化是否影响下游指标/卡片。
125
+
126
+ 1. 读取当前详情:
127
+
128
+ ```bash
129
+ guancli metric get <metric_id> -f json
130
+ ```
131
+
132
+ 2. 基于当前详情生成完整编辑 payload,例如 `/tmp/composite_metric_update.json`。至少包含 `projectId`、`subType`、`name`、`formula`、`useExpressionMetricCommonDims`、`applicableDims`、`desc`、`publish`。
133
+ 3. 如果修改了 `formula` 或 `filter`,先调用影响校验:
134
+
135
+ ```bash
136
+ guancli fetch POST /api/metric-platform/metrics/composite-metrics/<metric_id>/validate-update-impact --stdin < /tmp/composite_metric_update.json
137
+ ```
138
+
139
+ 4. 如果返回 `hasChanged=true` 且 `affectedMetrics` 或 `affectedCards` 非空,展示受影响指标和卡片,等待用户二次确认。
140
+ 5. 提交真实编辑:
141
+
142
+ ```bash
143
+ guancli fetch POST /api/metric-platform/metrics/composite-metrics/<metric_id> --stdin < /tmp/composite_metric_update.json
144
+ ```
145
+
146
+ 6. 保存后回读确认。
@@ -0,0 +1,70 @@
1
+ # 指标删除
2
+
3
+ 指标删除适用于原子指标、复合指标、衍生指标和快捷引用指标。删除流程是通用的,不需要按指标类型走不同 endpoint。
4
+
5
+ ## Web 同款行为
6
+
7
+ Web 的单指标删除弹窗会先做删除影响校验:
8
+
9
+ ```bash
10
+ guancli fetch GET /api/metric-platform/metrics/<metric_id>/validate-delete-impact
11
+ ```
12
+
13
+ 响应结构与编辑影响校验一致:
14
+
15
+ | 字段 | 中文 | 说明 |
16
+ | --- | --- | --- |
17
+ | `hasChanged` | 是否存在变更影响 | 删除校验通常为 `true` |
18
+ | `affectedMetrics` | 下游指标 | 仍引用该指标的指标列表 |
19
+ | `affectedCards` | 下游指标卡片 | 仍引用该指标的卡片列表 |
20
+
21
+ 如果 `affectedMetrics` 或 `affectedCards` 非空,Web 会提示“指标已被以下资源使用,暂无法删除”,只允许用户查看影响并关闭弹窗,不会提交删除。
22
+
23
+ 只有影响列表为空时,Web 才展示“删除后无法恢复”的确认弹窗;用户确认后调用:
24
+
25
+ ```bash
26
+ guancli fetch POST /api/metric-platform/metrics/<metric_id>/delete
27
+ ```
28
+
29
+ ## CLI 推荐流程
30
+
31
+ 优先使用封装命令:
32
+
33
+ ```bash
34
+ guancli metric delete <metric_id>
35
+ ```
36
+
37
+ 该命令默认只执行删除影响校验并输出结果,不会真实删除。输出 `deletable=true` 时,再向用户确认“删除后无法恢复”。
38
+
39
+ 用户明确确认后执行:
40
+
41
+ ```bash
42
+ guancli metric delete <metric_id> --confirm
43
+ ```
44
+
45
+ `--confirm` 也会先重新执行删除影响校验;如果此时发现下游指标或卡片,仍然阻断删除,不会调用 delete 接口。
46
+
47
+ ## 信息收集
48
+
49
+ 如果用户只说“帮我删除一个指标”,先收集或查询:
50
+
51
+ 1. 指标 ID;如果只给名称,先用 `guancli metric search <关键词> -f json` 查候选。
52
+ 2. 用 `guancli metric get <metric_id> --brief` 核对指标名称、类型、主题、目录和状态。
53
+ 3. 运行 `guancli metric delete <metric_id>` 查看删除影响。
54
+ 4. 如果可删除,向用户确认删除对象和“删除后无法恢复”。
55
+ 5. 用户明确确认后执行 `guancli metric delete <metric_id> --confirm`。
56
+
57
+ ## 影响展示
58
+
59
+ 影响校验返回下游资源时,需要向用户展示:
60
+
61
+ - 下游指标:`id`、`name`、`subType`;若有 `linkMetricId`,说明是快捷引用关联的原始指标。
62
+ - 下游卡片:`id`、`name`。
63
+
64
+ 存在下游资源时不要提供 `--confirm` 继续删除的建议;应提示用户先调整或删除引用关系。
65
+
66
+ ## 常见判断
67
+
68
+ - 删除是不可恢复操作,即使 `publish=false` 的草稿也要明确确认。
69
+ - 不要把“删除影响校验通过”说成已经删除成功。
70
+ - 删除成功后可尝试 `guancli metric get <metric_id> --brief` 或重新搜索确认资源已不可见;如果后端返回已删除/不存在,视为删除完成。