Skip to content

Commit 75ecf33

Browse files
yunqiqiliangcz-cli
andauthored
feat(analytics-agent): batch enable/disable, table columns alias, richer help (#59)
* feat(analytics-agent): batch enable/disable, table columns alias, richer help Address analytics-agent usability findings from the governed-analytics review: - metric/answer-builder enable & disable now accept `--all --domain-id <id>` for batch operations (single positional id still works). Batch lists the domain, skips items already in the target state, applies the rest per-item, and aggregates {total,succeeded,failed,skipped,results}; partial failure exits non-zero. Batch disable reuses the single-item detail+update fallback. - add `table columns <dataset-id>` as a flat alias for `table semantics list`. - add copy-paste examples to metric create/validate and answer-builder create; examples steer users to virtual columns instead of SQL string literals. - add epilogues clarifying simple_metric (metric) vs complex_metric (answer-builder) and that both count toward domain targetCounts. Known backend limitation (not CLI-fixable): metric disable can trigger CZD-99999 (common_reference_relationship.source_id not-null violation) on some environments; both single and batch disable hit it. The CLI faithfully reports the error, exits non-zero, and leaves local state unchanged. Specs and tests updated alongside the code per the spec-driven workflow. Co-Authored-By: cz-cli <noreply@clickzetta.com> * fix(analytics-agent): paginate batch enable/disable list to cover all items Batch `--all` mode listed only the API's default first page (10 rows), so a domain with more metrics/answer-builders silently skipped everything past the first page. Loop the list request by page (200/page) until a short page is returned, so `total` reflects the true count. Found during full-surface verification: `metric enable --all --domain-id 27` reported total=10 while the domain has 14 metrics. Co-Authored-By: cz-cli <noreply@clickzetta.com> * fix(analytics-agent): guard batch pagination against a backend that ignores pageNum Harden the batch enable/disable pagination loop found during corner-case testing: dedup targets by id and stop when a full page contributes no new ids, plus a hard page cap. Prevents an infinite loop / duplicate processing if the backend ever returns the same page regardless of pageNum. Co-Authored-By: cz-cli <noreply@clickzetta.com> * fix(analytics-agent): validate id args locally instead of leaking backend 500s Positional/option id args (domain-id, dataset-id, metric-id, etc.) were sent to the backend even when non-numeric, fractional, zero, negative, or beyond safe-integer range, surfacing as opaque HTTP 500s or backend NPEs — with inconsistent behavior across commands. Add a middleware on the analytics-agent root that validates these ids as positive safe integers before any request, returning a friendly USAGE_ERROR. `parent-id` (0 = root folder) is excluded. Found during corner-case testing: `domain detail abc` returned HTTP 500 while `metric enable abc` already returned USAGE_ERROR — now unified. Two existing tests updated to the unified message wording (the middleware is now the authoritative first-line id check). Co-Authored-By: cz-cli <noreply@clickzetta.com> --------- Co-authored-by: cz-cli <noreply@clickzetta.com>
1 parent 4f9886c commit 75ecf33

11 files changed

Lines changed: 988 additions & 57 deletions

File tree

openspec/specs/analytics-agent-answer-builder/spec.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,42 @@
2626
- **WHEN** 用户执行 `cz-cli analytics-agent answer-builder create --help`
2727
- **THEN** help 中不包含 `--body`
2828

29+
#### Scenario: create help 提供可复制的使用示例
30+
31+
- **WHEN** 用户执行 `cz-cli analytics-agent answer-builder create --help`
32+
- **THEN** help 输出包含 `Examples:`
33+
- **** 示例提示先用 `validate` 校验 `--content` DSL
34+
35+
### Requirement: answer-builder 命令组帮助说明与 metric 的关系
36+
37+
`cz-cli analytics-agent answer-builder --help` MUST 在 epilogue 中说明 answer-builder 是 complex_metric(多步/多表 DSL 分析),单表单聚合应使用 `metric`(simple_metric),且两者都计入 `domain detail` 的 targetCounts,并提示可用 `--domain-id``answer-builder list` 限定到单个 domain。
38+
39+
#### Scenario: answer-builder 组帮助解释 complex/simple metric 关系
40+
41+
- **WHEN** 用户执行 `cz-cli analytics-agent answer-builder`(缺子命令,渲染组帮助)
42+
- **THEN** 帮助输出包含 `complex_metric`
43+
- **** 帮助输出包含 `simple_metric`
44+
- **** 帮助输出提到 `targetCounts`
45+
46+
### Requirement: answer-builder enable/disable 支持按 domain 批量操作
47+
48+
`cz-cli analytics-agent answer-builder enable``disable` MUST 同时支持单条模式(positional `analysis-id`)与批量模式(`--all --domain-id <id>`)。两种模式互斥且至少提供其一。批量模式 MUST 先列出该 domain 下的 answer-builder,跳过已处于目标状态的项,对其余逐个调用单条 enable/disable,并汇总 `total``succeeded``failed``skipped` 与逐项 `results`。批量 disable MUST 复用单条 disable 的 detail+update 回退逻辑。
49+
50+
#### Scenario: 批量 disable 跳过已禁用项并禁用其余
51+
52+
- **WHEN** 用户执行 `cz-cli analytics-agent answer-builder disable --all --domain-id 27`
53+
- **AND** 该 domain 下有 2 个 answer-builder,其中 1 个已是 `DISABLE`
54+
- **THEN** CLI 先调用 answer-builder list
55+
- **** 对已 `DISABLE` 的项标记为 `skipped`,不再调用 disable
56+
- **** 对其余 1 项执行禁用
57+
- **** 输出包含 `total=2``succeeded=1``skipped=1``failed=0`
58+
59+
#### Scenario: 同时传 id 与 --all 时本地拒绝
60+
61+
- **WHEN** 用户执行 `cz-cli analytics-agent answer-builder enable 9 --all`
62+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
63+
- **** 错误信息 MUST 说明二者互斥
64+
2965
### Requirement: answer-builder list 使用扁平过滤参数
3066

3167
`cz-cli analytics-agent answer-builder list` MUST 使用显式过滤参数构造请求体,不把 `--body` 暴露为普通用户主路径。

openspec/specs/analytics-agent-metric/spec.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,73 @@
4949
- **THEN** help 中不包含 `--body`
5050
- **** help 中保留 `--alias`
5151

52+
### Requirement: metric create help 提供可复制的使用示例
53+
54+
`cz-cli analytics-agent metric create --help` MUST 提供至少一个可直接复制的完整示例,帮助用户推断 `--table-name` 全限定格式与 `--expression` 聚合写法,降低首次调用的重试率。示例 MUST 引导用户用虚拟列封装字符串条件,而非在 `--expression` 中直接写字符串字面量(后端 SQL 校验层拒绝字符串字面量)。
55+
56+
#### Scenario: create help 展示全限定表名与聚合示例
57+
58+
- **WHEN** 用户执行 `cz-cli analytics-agent metric create --help`
59+
- **THEN** help 输出包含 `Examples:`
60+
- **** 示例中包含全限定表名格式提示 `catalog.schema.table`
61+
- **** 示例引导用虚拟列(如 `win_flag`)封装条件,而非 SQL 字符串字面量
62+
63+
### Requirement: metric 命令组帮助说明与 answer-builder 的关系
64+
65+
`cz-cli analytics-agent metric --help` MUST 在 epilogue 中说明 metric 是 simple_metric(单表单聚合),多步/多表分析应使用 `answer-builder`(complex_metric),且两者都计入 `domain detail` 的 targetCounts,避免用户混淆两个命令组的定位。
66+
67+
#### Scenario: metric 组帮助解释 simple/complex metric 关系
68+
69+
- **WHEN** 用户执行 `cz-cli analytics-agent metric`(缺子命令,渲染组帮助)
70+
- **THEN** 帮助输出包含 `simple_metric`
71+
- **** 帮助输出提示改用 `answer-builder`
72+
- **** 帮助输出提到 `targetCounts`
73+
74+
### Requirement: metric enable/disable 支持按 domain 批量操作
75+
76+
`cz-cli analytics-agent metric enable``disable` MUST 同时支持单条模式(positional `metric-id`)与批量模式(`--all --domain-id <id>`)。两种模式互斥且至少提供其一。批量模式 MUST 先列出该 domain 下的 metric,跳过已处于目标状态的项,对其余逐个调用单条 enable/disable,并汇总 `total``succeeded``failed``skipped` 与逐项 `results`。批量列表 MUST 翻页覆盖 domain 下的全部 metric,不得只处理服务端默认第一页。批量 disable MUST 复用单条 disable 的 detail+update 回退逻辑。
77+
78+
#### Scenario: 批量 enable 跳过已启用项并启用其余
79+
80+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable --all --domain-id 27`
81+
- **AND** 该 domain 下有 3 个 metric,其中 1 个已是 `ENABLE`
82+
- **THEN** CLI 先调用 metric list
83+
- **** 对已 `ENABLE` 的项标记为 `skipped`,不再调用 enable
84+
- **** 对其余 2 项调用 `/metrics/enable`
85+
- **** 输出包含 `total=3``succeeded=2``skipped=1``failed=0`
86+
87+
#### Scenario: 批量操作翻页覆盖首页之外的项
88+
89+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable --all --domain-id 27`
90+
- **AND** 该 domain 下的 metric 数量超过服务端单页默认条数
91+
- **THEN** CLI MUST 按页请求 metric list 直到取回全部项
92+
- **** 汇总的 `total` 等于 domain 下 metric 的真实总数,而非单页条数
93+
94+
#### Scenario: 批量操作部分失败时返回非零退出码
95+
96+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable --all --domain-id 27`
97+
- **AND** 其中一项调用 enable 时后端返回业务错误
98+
- **THEN** CLI 继续处理其余项,不中断
99+
- **** 输出中该项 `result=failed` 并带 `error`
100+
- **** 命令退出码为非零
101+
102+
#### Scenario: 同时传 id 与 --all 时本地拒绝
103+
104+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable 197 --all`
105+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
106+
- **** 错误信息 MUST 说明二者互斥
107+
108+
#### Scenario: --all 缺少 --domain-id 时本地拒绝
109+
110+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable --all`
111+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
112+
- **** 错误信息 MUST 提示需要 `--domain-id`
113+
114+
#### Scenario: 既无 id 也无 --all 时本地拒绝
115+
116+
- **WHEN** 用户执行 `cz-cli analytics-agent metric enable`
117+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
118+
52119
### Requirement: metric disable 兼容旧状态接口异常并回退到 detail + update
53120

54121
当服务端直接 `disable` 路径返回“对象不存在”这类旧兼容异常时,`cz-cli analytics-agent metric disable` MUST 优先尝试读取 detail,再用完整 update 请求把 `status` 改为 `DISABLE`,避免用户因为旧状态路由异常而无法禁用 metric。
@@ -61,3 +128,14 @@
61128
- **** 再调用 `metric update`
62129
- **** update 请求体包含 detail 中的核心字段与 `status=DISABLE`
63130
- **** 最终命令返回成功
131+
132+
#### Scenario: disable 遇到非 not-found 的后端错误时如实上报
133+
134+
- **WHEN** 用户执行 `cz-cli analytics-agent metric disable 184`
135+
- **AND** 后端返回非 not-found 业务错误(例如 `CZD-99999` 约束违反)
136+
- **THEN** CLI MUST NOT 触发 detail+update 回退(回退仅针对 not-found 类异常)
137+
- **** CLI 如实上报该后端错误码与信息
138+
- **** 命令退出码为非零
139+
- **** metric 本地状态保持不变(不产生部分写入)
140+
141+
> 已知后端限制:在部分环境,metric disable 会触发后端 `CZD-99999``common_reference_relationship.source_id` 非空约束违反),单条与批量 disable 均会命中。此为后端缺陷,CLI 侧仅保证如实透传错误、退出码非零、不改本地状态。

openspec/specs/analytics-agent-table-semantics/spec.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@
1616
- **** 请求包含 open token 鉴权和 `tenantId` query
1717
- **** 输出包含每个字段的 `attrId``attrCode``semanticType``description``hidden`
1818

19+
### Requirement: table columns 作为 semantics list 的扁平别名
20+
21+
`cz-cli analytics-agent table columns <dataset-id>` MUST 作为 `table semantics list <dataset-id>` 的扁平别名,调用同一个 dataset 语义 open API 并返回相同结果,用于缩短查看数据集列语义的命令层级。
22+
23+
#### Scenario: columns 别名命中与 semantics list 相同的端点
24+
25+
- **WHEN** 用户执行 `cz-cli analytics-agent table columns 195`
26+
- **THEN** CLI 调用 `GET /open/api/v1/analytics-agent/datasets/195/semantics`
27+
- **** 输出包含每个字段的 `attrId``attrCode``semanticType``description``hidden`
28+
- **** 输出与 `cz-cli analytics-agent table semantics list 195` 一致
29+
1930
### Requirement: table semantics get 查看单个字段语义详情
2031

2132
`cz-cli analytics-agent table semantics get` MUST 支持按 `datasetId + attrId` 查看单个字段的语义详情。

openspec/specs/analytics-agent/spec.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,34 @@
2222
- **THEN** CLI 返回 usage error
2323
- **AND** 不调用远端服务
2424

25+
### Requirement: id 参数本地校验为正整数
26+
27+
`analytics-agent` 命令族的资源 id 参数(如 `domain-id``dataset-id``attr-id``metric-id``analysis-id``node-id``space-id``join-id``table-id``datasource-id``question-id``session-id` 等)MUST 在发请求前本地校验为正整数(安全整数范围内、> 0)。非数字、小数、0、负数、超出安全整数范围的输入 MUST 直接返回 `USAGE_ERROR`,不得把非法值发给后端而暴露为 HTTP 500 或后端 NPE。表示根节点的 `parent-id`(允许为 0)不受此约束。
28+
29+
#### Scenario: 非数字 id 本地拒绝
30+
31+
- **WHEN** 用户执行 `cz-cli analytics-agent domain detail abc`
32+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
33+
- **** 错误信息 MUST 说明该 id 必须是正整数
34+
- **AND** 不调用远端服务
35+
36+
#### Scenario: 小数 / 0 / 负数 / 溢出 id 本地拒绝
37+
38+
- **WHEN** 用户对任一资源 id 传入 `27.5``0``-1` 或超出安全整数范围的值(如 `99999999999999999999`
39+
- **THEN** CLI MUST 在发请求前直接返回 `USAGE_ERROR`
40+
- **AND** 不调用远端服务
41+
42+
#### Scenario: 合法 id 正常放行
43+
44+
- **WHEN** 用户传入正整数 id
45+
- **THEN** 校验通过并正常调用远端服务
46+
47+
#### Scenario: parent-id 允许为 0(根节点)
48+
49+
- **WHEN** 用户执行 `cz-cli analytics-agent knowledge file list <space-id> --parent-id 0`
50+
- **THEN** CLI MUST NOT 因 `parent-id=0``USAGE_ERROR`
51+
- **** 正常按根节点查询
52+
2553
### Requirement: 输出字段面向用户和 agent
2654

2755
本需求 MUST 按以下场景执行。

0 commit comments

Comments
 (0)