@guandata/guanmetric 0.1.22 → 0.1.23

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## @guandata/guanmetric 0.1.23 - 2026-10-29
4
+
5
+ - 适配 BI 8.4 指标及公共维度协议。
6
+
3
7
  ## @guandata/guanmetric 0.1.22 - 2026-10-19
4
8
 
5
9
  - 新增指标 DSL 创建与编辑流程,支持预览、文档生成、计划核对和应用。
package/README.md CHANGED
@@ -53,6 +53,10 @@ guanmetric metric-tree update-config <metric_tree_id> --file metric_tree_config.
53
53
 
54
54
  ## 版本更新
55
55
 
56
+ ### @guandata/guanmetric 0.1.23
57
+
58
+ - 适配 BI 8.4 指标及公共维度协议。
59
+
56
60
  ### @guandata/guanmetric 0.1.22
57
61
 
58
62
  - 新增指标 DSL 创建与编辑流程,支持预览、文档生成、计划核对和应用。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guandata/guanmetric",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "观远 BI 指标写操作工具 - 指标创建编辑删除、指标目录、公共维度、Excel 标准化",
5
5
  "bin": {
6
6
  "guanmetric": "bin/run.js"
@@ -41,11 +41,11 @@
41
41
  "node": ">=14"
42
42
  },
43
43
  "optionalDependencies": {
44
- "@guandata/guanmetric-darwin-arm64": "0.1.22",
45
- "@guandata/guanmetric-darwin-x64": "0.1.22",
46
- "@guandata/guanmetric-linux-x64": "0.1.22",
47
- "@guandata/guanmetric-linux-arm64": "0.1.22",
48
- "@guandata/guanmetric-win32-x64": "0.1.22"
44
+ "@guandata/guanmetric-darwin-arm64": "0.1.23",
45
+ "@guandata/guanmetric-darwin-x64": "0.1.23",
46
+ "@guandata/guanmetric-linux-x64": "0.1.23",
47
+ "@guandata/guanmetric-linux-arm64": "0.1.23",
48
+ "@guandata/guanmetric-win32-x64": "0.1.23"
49
49
  },
50
50
  "publishConfig": {
51
51
  "registry": "https://registry.npmjs.org/",
@@ -95,6 +95,8 @@ guanmetric fetch POST /api/metric-platform/<unwrapped_endpoint> --file request.j
95
95
 
96
96
  复合指标和衍生指标的单条创建/编辑必须使用 `composite create|edit`、`derived create|edit` 专用命令。三类编辑命令优先读取草稿;仅当结构化业务状态明确表示草稿不存在时才回退正式详情,然后把读模型转换成对应 Update DTO 白名单再合并 patch。原子 `edit --replace` 已停用。禁止把详情响应直接交给 `fetch` 回写;`fetch` 会先按服务端路由语义解码并规范化 URL,再硬拒绝三类指标已封装的 create/edit 写路由,百分号编码、点段或矩阵参数不能绕过,只用于尚未封装的低层端点或诊断。指标定义写入时,专用命令和其余允许的 `fetch` 请求都会规范化并校验顶层 `filter`:将兼容别名和 `not: true` 转成 Web 编辑器可识别的明确筛选类型,为空值筛选补 `filterValue: []`,并从当前指标或基础指标的 `applicableDims` 补齐字段元数据;无法无损转换时拒绝提交。业务限定衍生指标还会确认每个条件的 `fdId` 都存在于基础指标 `applicableDims`。
97
97
 
98
+ 涉及 BI 8.4.0 及以上的指标、公共维度、查询加速或版本探测时,先读取 `references/metric-bi84-compatibility.md`;不得把多候选列表当作单个绑定。低版本继续使用旧协议,无法获取有效版本则报错。
99
+
98
100
  构造或解析指标创建、编辑、详情和列表请求时,先读取 `metric-api-contracts.md`。其中包含三类指标的真实脱敏响应、原子字段/表达式两种模式、六种衍生配置、JSON Schema 以及读模型到写模型映射。详情响应是读模型:`fdInfos`、对象数组形式的 `applicableDims`、对象形式的 `timeDim`、`baseMetric` 和用户对象不能原样提交;编辑请求必须按对应 Update DTO 白名单显式构造。列表请求的 `subTypes` 是逗号分隔字符串,不是 JSON 数组。
99
101
 
100
102
  构造或解析指标主题/指标目录的创建、编辑、详情/列表/目录树和删除请求时,先读取 `metric-hierarchy-api-contracts.md`。主题编辑只提交 `name/icon/iconColor`;目录编辑只提交 `name/parentDirId/dirType`,其中 `dirType` 固定为 `METRIC_PLATFORM`。指标目录没有单条详情接口,`directory get` 是从指定 Project 的目录树按 ID 提取节点。创建和编辑必须写后回读;删除默认只展示目标,必须追加 `--confirm`。本轮不提供指标 move 或指标 owner 转移命令。
@@ -0,0 +1,66 @@
1
+ # BI 8.4 指标与公共维度协议
2
+
3
+ 协议来源:BI commit `4f27c3f0fdb7df5d9cce88f8475195497ccca1f1` 的 Spring Controller、RO/DTO;版本回退端点来源为 BI commit `903af2e077cfba2cba5a966fb028fb87d64c92d3`(MR 23223)。本文件补充旧契约,旧示例和旧 Schema 定义继续适用于 BI < 8.4.0。
4
+
5
+ ## 版本选择
6
+
7
+ 先 GET `/api/server-version`。仅 HTTP 403 或结构化 BI 错误 `status=1004` 时 GET `/api/metric-platform/server-version`。401、404、5xx、网络错误、成功响应没有有效 `version` 均直接报“无法获取 BI 版本”,不会猜测版本或继续提交。比较基础数字版本,兼容 `_00`、`_GALAXY-*`、`-hf*` 后缀;忽略 `dataVersion`。
8
+
9
+ BI >= 8.4.0 使用下述结构;较低版本保持旧请求和输出结构。dry-run 会读取版本和必要元数据,只证明请求可构造。旧接口无权限且新版本端点尚未部署时会报错,应先交付 BI MR 23223。
10
+
11
+ ## 公共维度
12
+
13
+ 新建/编辑新增可选字段:`alias`、`dirId`、`description`、`valueSource: {dsId, fdId}`。详情的值来源为 `{dsInfo, fdInfo}`,编辑会转换回 ID,并保留未修改的新增字段。`valueSource: null` 表示明确清空。目录属于 `DIMENSION_CENTER`,不能使用指标的 `METRIC_PLATFORM` 目录。
14
+
15
+ `public-dim fd-map <dsId>` 保持原有 `fdId -> 单个对象` 返回,不能用于证明 8.4 字段只有一个公共维度。
16
+
17
+ 使用 `public-dim fd-candidates <dsId>` 获取 `fdId -> [{id,name,...}]` 全部候选(仅 BI >= 8.4.0)。同一字段可以有多个候选,不得取第一项或以旧版“字段已占用”规则拒绝新结构。真实类型、权限、依赖和严格维度规则由服务端裁决。
18
+
19
+ ## 原子指标与查询加速
20
+
21
+ `applicableDims` 仍是物理字段 ID 数组。公共身份单独传递:
22
+
23
+ ```json
24
+ {
25
+ "dsId": "ds_orders",
26
+ "applicableDims": ["fd_city"],
27
+ "applicableDimMappings": [
28
+ {"fdId": "fd_city", "publicDimensionId": "pd_city"}
29
+ ]
30
+ }
31
+ ```
32
+
33
+ 未提供绑定时,只自动采用唯一候选;多个候选会报错,必须在 JSON/Flow 请求中显式指定。候选为空时不构造绑定,是否允许由服务端严格维度配置决定。显式 `[]` 表示清空,不触发自动选择;`null` 不是数组,会报错。编辑保留原有有效公共身份;删除适用维度时移除对应的继承绑定,显式不合法的输入绑定会报错。
34
+
35
+ 查询加速在新版本始终传 `applicableDimMappings` 数组,无维度时为 `[]`。`--dim`、`--time-dim` 会从数据集元数据唯一解析为字段 ID;重名需使用 ID。编辑从详情的字段对象还原物理 ID 与公共身份。
36
+
37
+ DSL 可明确选择公共身份:
38
+
39
+ ```javascript
40
+ .dimensions(publicDimension(field(DS.orders, "城市"), "pd_city"))
41
+ ```
42
+
43
+ 该包装只接受注册 catalog 字段。原子指标创建与编辑都会生成绑定;复合和衍生指标的有效公共维度由服务端计算,不能手工复制候选列表。Excel/Flow 生成后的远程 plan 走同一协议适配层;歧义必须修正计划中的 `applicableDimMappings`,不能通过换个候选重试。
44
+
45
+ `publicDimensionMap` 表示服务端有效映射,也可能来自唯一候选回退;`applicableDims[].publicDimensions` 是候选列表。读取有效映射不能证明绑定在数据库中显式持久化,也不能通过回读映射是否为空来证明显式清空。
46
+
47
+ ## 查询输出与参数
48
+
49
+ guancli 在新版本将有效 `publicDimensionId` 连同物理 `dsId/fdId` 传入维度、筛选、忽略筛选和排序;日期子维度继承公共身份。低版本不会新增该字段。JSON `metric get` 与 `search --with-detail` 的 `dimensions[]` 可新增 `publicDimension:{id,name}` 和 `publicDimensionCandidates:[{id,name}]`,旧字段和 schemaVersion 保持不变;`--raw` 仍为后端原始响应。
50
+
51
+ ## Domain and Contract / PAT
52
+
53
+ | CLI method/path | BI 生效路由 | 权限 |
54
+ | --- | --- | --- |
55
+ | GET `/api/server-version` | GET `/server-version`,MiscNgController | CARD / READ,pId=1/read |
56
+ | GET `/api/metric-platform/server-version` | GET `/metric-platform/server-version`,MetricServerVersionNgController(上述 BI MR) | METRIC_PLATFORM / READ,pId=90/read |
57
+ | GET `/api/metric-platform/public-dimensions/dataset/{dsId}/fdId-pubdims-map` | 去掉 `/api`,PublicDimManagementNgController | METRIC_PLATFORM / READ,pId=90/read |
58
+ | GET `/api/data-source/{dsId}`(加速字段解析) | GET `/data-source/{dsId}`,dataset/DataSourceNgController | DATASET / READ,pId=10/read;另需数据集资源权限 |
59
+
60
+ `guancli metric query` 的基础取数仍使用隔离卡片编辑会话;其 GET `/api/card/{cdId}/edit`(Spring `/card/{cdId}/edit`,CardMetaNgController)要求 `PAGE/UPDATE`,映射 pId=1/update。仅 90/read 的 PAT 能查询指标详情、公共维度候选和新版本接口,但该基础取数链会在此返回 403;test71 已实测额外授予 1/update 后取数通过。版本回退不改变这条既有权限要求;不要把有权读取版本等同于有权执行全部查询。加速字段解析还需 10/read,缺失时数据集接口返回 403。
61
+
62
+ 目录/公共维度及指标写入仍沿用已有 POST 端点,本次仅适配 body。PAT scope 的默认全局候选白名单包含 1/read、90/read、10/read;实际 token 必须被授予相应 scope,用户当前权限与 Domain 全局策略也必须允许。新增回退避免仅有指标读取 scope 的用户被 CARD/READ 阻断,不会绕过指标权限。
63
+
64
+ 兼容测试使用本地 transport/HTTP/replay,覆盖新旧版本与后缀、权限回退、失败分支、候选歧义、空数组、编辑保留、日期子维度、筛选排序和输出投影。2026-10-26 已在 test71 的 BI 8.4.0 完成登录态与 PAT 环境验证,覆盖公共维度和原子指标真实创建/编辑/回读、查询加速、DSL/Flow 及版本回退;范围、修复和限制见 `metric-bi84-test71-validation.md`。低版本分支仍由本地兼容测试验证,test71 实测不代表旧 BI 环境验证。
65
+
66
+ 编排一致性:版本与元数据按一次命令执行时读取;服务端仍会重新校验真正写入,计划与提交之间的变更不能保证无冲突。候选按字段关联,不混合不同字段或选择列表首项;绑定输出按 fdId 排序。任一版本/候选/字段解析失败阻止提交,Flow 不记录为成功。批量查询保持输入顺序和逐项错误语义。
@@ -0,0 +1,54 @@
1
+ # BI 8.4 指标适配:test71 验证记录
2
+
3
+ 验证日期:2026-10-26。环境:`test71`,Domain:`testing`,同一 ROBOT 测试账号。
4
+ BI 返回 `8.4.0_codex_metric-server-version_2026102616_00`。
5
+ 客户端为 `guanbi-skills` 当前工作区源码临时编译的 guancli、guanmetric;未以全局已安装版本替代待验证源码。
6
+
7
+ ## 范围与结果
8
+
9
+ | 场景 | 实测结果 |
10
+ | --- | --- |
11
+ | 会话版本查询 | 旧 `/api/server-version` 成功,保留既有 License 输出 |
12
+ | PAT 版本回退 | 仅指标 scope 时,真实请求顺序为旧接口 403 → 新 `/api/metric-platform/server-version` 200;有仪表板读取 scope 时只请求旧接口 |
13
+ | 公共维度创建与编辑 | alias、description、DIMENSION_CENTER 根目录 dirId、valueSource 写入及详情回读成功;修改 description 保留其他新字段;显式 valueSource=null 真实清空成功 |
14
+ | 字段多候选 | 同一临时数据集城市字段关联两个公共维度;fd-candidates 返回两个候选;旧 fd-map 不能作为候选全集 |
15
+ | 创建及绑定 | 唯一候选自动生成 applicableDimMappings;多候选未指定时 dry-run 拒绝;显式选择后编辑成功,回读保留被选公共身份及完整候选列表 |
16
+ | 编辑兼容 | 只改口径保留原绑定;切换公共身份成功;移除适用维度后旧字段绑定被移除,真实更新及回读成功;显式 [] 的 dry-run 保持空数组 |
17
+ | 指标 get / search --with-detail | JSON 保持 schemaVersion=1.0,维度包含 publicDimension 与 publicDimensionCandidates |
18
+ | 筛选、排序、日期粒度 | 城市筛选、金额排序、日期排序、按月分组均取数成功;explain 中日期子维度和排序保留公共维度 ID,城市筛选带选中身份 |
19
+ | 批量查询 | 城市和月份两项均 success,保持输入顺序,结果与单查询一致 |
20
+ | 查询加速 | 创建、列表、编辑 dry-run、真实编辑与回读成功;字段 ID 和公共身份保留;数据结果正确并实际命中所建加速指标 |
21
+ | DSL / Flow | DSL preview、plan、apply(create)、checkout、plan(edit)、apply(edit) 成功;Flow plan、apply 及 usable 回读/取数验收成功;公共维度身份保留 |
22
+ | PAT 读写与拒绝 | 90/read 可读取指标、公共维度及候选;无 update 的真实公共维度写入 403;90/read+update 的公共维度及指标编辑、回读成功;仅仪表板 scope 读取指标和候选 403 |
23
+ | 缺失资源 | 公共维度详情不存在时,会话与 PAT 都保留服务端 HTTP 500 / businessStatus=1002。候选接口对不存在的数据集返回 200 / {},双方一致;不能据此判断数据集存在 |
24
+ | 数据集 PAT scope | 加速字段解析使用 GET /api/data-source/{id};10/read 下成功,只有 90/read 时直接数据集读取 403 |
25
+ | 本地低版本兼容 | 本地 transport/HTTP/命令测试覆盖 <8.4 旧结构、>=8.4 新结构、版本后缀、错误回退边界;test71 为 8.4,未据此声称旧 BI 环境实测通过 |
26
+
27
+ 数据集为 APITestSpecific 目录中的隔离 CSV:杭州 10、20;上海 30、40,日期为 2026-10-01/02。
28
+ 校验结果为杭州 30、上海 70、按月 100、逐日 40/60;DSL COUNT=4、Flow AVG=25。
29
+ 加速查询命中源指标 `j948574745e1248b0a638de4` 对应的加速指标 `j9429bd17432a40a18007544`,该列表仅一个加速项,对应页面查询顺序 1;后端 acceleratePriority=2 是权重。
30
+
31
+ ## 环境验证发现并修复的问题
32
+
33
+ 1. 原子 `create --dry-run` 跳过了版本协议准备,未输出公共绑定,也未提前拒绝候选歧义。创建现在于计划、save-precheck 和提交前共用协议准备。
34
+ 2. 原子 `edit` 减少适用维度时保留了已移除字段的继承绑定。8.4 编辑路径现在重新解析保留维度,移除旧绑定;显式 null 映射仍交给数组校验拒绝,不被通用 merge-patch 静默吞掉后自动选择。
35
+ 3. 公共维度 `valueSource=null` 被通用 merge-patch 删除,未按新协议发出显式清空。只在 8.4 的该字段保留 null;低版本通用合并行为保持不变。
36
+
37
+ 新增命令级与协议回归:`metric_create_protocol_test.go`,覆盖旧/新版本 dry-run、候选歧义、dry-run 无 POST、减少维度、值来源 null/省略及映射 null 拒绝。
38
+ `go test ./guancli/... ./guanmetric/...`、`go vet ./guancli/... ./guanmetric/...`、`go build ./guancli/... ./guanmetric/...` 均通过。
39
+
40
+ ## 已确认的 PAT 限制
41
+
42
+ 仅 90/read 的 PAT 执行基础 `guancli metric query`,在 GET `/api/card/{cdId}/edit` 返回 403。
43
+ 该路由的 Spring `CardMetaNgController.getForEdit` 要求 PAGE/UPDATE(pId=1/update)。
44
+ 本轮额外授予 1/read+update、90/read+update、10/read 的临时 PAT 后,基础取数与加速编辑成功。
45
+ 因此,新版本端点和指标详情的权限问题已解决,但仅指标 scope 的基础取数仍受这条既有卡片接口权限限制;本轮未变更 BI 的权限设计,也未用 session 混入 PAT 请求绕过校验。
46
+
47
+ ## 清理与边界
48
+
49
+ 按依赖顺序清理:1 个加速指标、3 个原子指标、3 个公共维度、1 个指标主题及其自动根目录、1 个临时数据集。
50
+ 按唯一前缀搜索指标为 0、公共维度列表 count=0;主题不在列表,数据集详情返回 1002。
51
+ PAT 测试每次前确认账号无存量令牌;结束恢复 patEligible=false、活动 PAT 数 0、grants 数 0。Domain 策略未修改。
52
+ 仅临时资源被修改;此前已有业务资源只读。CSV 导入数据集名称的连字符不适用于主题名,主题创建首次被服务端 1012 拒绝,改为字母数字前缀后成功。
53
+
54
+ 详细命令输出与不含认证头的 PAT 请求路径/状态记录保存在本机 `/tmp/test71-skills/evidence/`;这些运行产物不纳入源码契约,也不提交账号配置或令牌。
@@ -22,6 +22,50 @@
22
22
  "properties": {"name": {"$ref": "#/$defs/nonEmptyString"}, "businessOwner": {"$ref": "#/$defs/nonEmptyString"}, "relatedFields": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/relatedFieldWrite"}}},
23
23
  "additionalProperties": false
24
24
  },
25
+ "writeRequest84": {
26
+ "type": "object",
27
+ "required": [
28
+ "name",
29
+ "businessOwner",
30
+ "relatedFields"
31
+ ],
32
+ "properties": {
33
+ "name": {
34
+ "$ref": "#/$defs/nonEmptyString"
35
+ },
36
+ "businessOwner": {
37
+ "$ref": "#/$defs/nonEmptyString"
38
+ },
39
+ "relatedFields": {
40
+ "type": "array",
41
+ "minItems": 1,
42
+ "items": {
43
+ "$ref": "#/$defs/relatedFieldWrite"
44
+ }
45
+ },
46
+ "alias": {
47
+ "type": "string"
48
+ },
49
+ "dirId": {
50
+ "type": "string"
51
+ },
52
+ "description": {
53
+ "type": "string"
54
+ },
55
+ "valueSource": {
56
+ "anyOf": [
57
+ {
58
+ "$ref": "#/$defs/relatedFieldWrite"
59
+ },
60
+ {
61
+ "type": "null"
62
+ }
63
+ ]
64
+ }
65
+ },
66
+ "additionalProperties": false,
67
+ "description": "BI >= 8.4.0; source commit 4f27c3f0fdb7df5d9cce88f8475195497ccca1f1 PublicDimensionRO"
68
+ },
25
69
  "mutationResponse": {
26
70
  "type": "object",
27
71
  "required": ["result", "response"],
@@ -4,6 +4,8 @@
4
4
 
5
5
  构造或解析请求和响应前先读取 `metric-public-dimension-api-contract-examples.json` 与 `metric-public-dimension-api-contract.schema.json`。样例于 2026-09-21 在 test153 使用隔离临时公共维度和账号密码认证完成 create、detail/list、edit、depend-check、delete 后脱敏;PAT 尚未验证。仓库测试会按 Schema 校验这些真实快照的必需字段和类型,后端新增可选字段不会误报,但刷新快照时若 CLI 依赖字段缺失或变型会失败。
6
6
 
7
+ BI >= 8.4.0 的字段、多候选、值来源与目录规则优先按 `metric-bi84-compatibility.md`。下文“已被其它公共维度使用”的排他规则只描述旧版行为,不适用于新版本;新版本使用 `public-dim fd-candidates` 查询全部候选。
8
+
7
9
  ## 命令入口
8
10
 
9
11
  ```bash