@guandata/guanmetric 0.1.21 → 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.
Files changed (25) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +11 -0
  3. package/package.json +6 -6
  4. package/skills/guanmetric/SKILL.md +49 -1
  5. package/skills/guanmetric/references/metric-api-contracts.md +7 -0
  6. package/skills/guanmetric/references/metric-bi84-compatibility.md +66 -0
  7. package/skills/guanmetric/references/metric-bi84-test71-validation.md +54 -0
  8. package/skills/guanmetric/references/metric-dsl-dependencies-example.json +30 -0
  9. package/skills/guanmetric/references/metric-dsl-dependencies.schema.json +66 -0
  10. package/skills/guanmetric/references/metric-dsl-document-output-example.json +18 -0
  11. package/skills/guanmetric/references/metric-dsl-document-output.schema.json +34 -0
  12. package/skills/guanmetric/references/metric-dsl-generate-1.1.schema.json +57 -0
  13. package/skills/guanmetric/references/metric-dsl-generate-bundle-example.json +35 -0
  14. package/skills/guanmetric/references/metric-dsl-generate-example.json +19 -0
  15. package/skills/guanmetric/references/metric-dsl-generate.schema.json +42 -0
  16. package/skills/guanmetric/references/metric-dsl-selection-example.json +6 -0
  17. package/skills/guanmetric/references/metric-dsl-selection.schema.json +14 -0
  18. package/skills/guanmetric/references/metric-dsl.md +298 -0
  19. package/skills/guanmetric/references/metric-flow-export-example.json +30 -0
  20. package/skills/guanmetric/references/metric-flow-export.schema.json +34 -0
  21. package/skills/guanmetric/references/metric-flow-handoff-example.json +29 -0
  22. package/skills/guanmetric/references/metric-flow-handoff.schema.json +48 -0
  23. package/skills/guanmetric/references/metric-flow.md +15 -1
  24. package/skills/guanmetric/references/metric-public-dimension-api-contract.schema.json +44 -0
  25. package/skills/guanmetric/references/metric-public-dimension.md +2 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## @guandata/guanmetric 0.1.23 - 2026-10-29
4
+
5
+ - 适配 BI 8.4 指标及公共维度协议。
6
+
7
+ ## @guandata/guanmetric 0.1.22 - 2026-10-19
8
+
9
+ - 新增指标 DSL 创建与编辑流程,支持预览、文档生成、计划核对和应用。
10
+ - 支持检出已有指标、对比本地变更及按计划原地编辑。
11
+
3
12
  ## @guandata/guanmetric 0.1.21 - 2026-10-12
4
13
 
5
14
  - 共享配置写入增加并发保护,避免覆盖并发更新的认证配置。
package/README.md CHANGED
@@ -12,6 +12,8 @@ npm install -g --foreground-scripts @guandata/guanmetric
12
12
 
13
13
  安装包会通过 npm `optionalDependencies` 自动选择当前系统的原生二进制。不要使用 `--omit=optional` 或 `optional=false`;企业 npm 镜像也需要同步对应的 `@guandata/guanmetric-<平台>-<架构>` 包。若平台包缺失,CLI 会显示对应包名和重新安装方法。
14
14
 
15
+ `dsl preview`、`dsl document` 和 `dsl diff` 等纯本地命令由安装包内置的 DSL 引擎执行,不需要源码仓库。`dsl init`、`dsl checkout`、`dsl plan`、`dsl apply` 以及其他访问 BI 的命令会通过 `guancli` 或 `guancli-lite` 调用 BI API;客户环境必须将其中一个加入 `PATH`,或用 `GUANCLI_PATH` 指向其原生程序,并按对应 CLI 配置认证信息。
16
+
15
17
  ## 常用命令
16
18
 
17
19
  ```bash
@@ -51,6 +53,15 @@ guanmetric metric-tree update-config <metric_tree_id> --file metric_tree_config.
51
53
 
52
54
  ## 版本更新
53
55
 
56
+ ### @guandata/guanmetric 0.1.23
57
+
58
+ - 适配 BI 8.4 指标及公共维度协议。
59
+
60
+ ### @guandata/guanmetric 0.1.22
61
+
62
+ - 新增指标 DSL 创建与编辑流程,支持预览、文档生成、计划核对和应用。
63
+ - 支持检出已有指标、对比本地变更及按计划原地编辑。
64
+
54
65
  ### @guandata/guanmetric 0.1.21
55
66
 
56
67
  - 共享配置写入增加并发保护,避免覆盖并发更新的认证配置。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guandata/guanmetric",
3
- "version": "0.1.21",
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.21",
45
- "@guandata/guanmetric-darwin-x64": "0.1.21",
46
- "@guandata/guanmetric-linux-x64": "0.1.21",
47
- "@guandata/guanmetric-linux-arm64": "0.1.21",
48
- "@guandata/guanmetric-win32-x64": "0.1.21"
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/",
@@ -32,8 +32,19 @@ guanmetric flow plan --file metric_flow.json
32
32
  guanmetric flow generate --file standard.xlsx --out metric_flow.json
33
33
  guanmetric flow apply --file metric_flow.json --state metric_flow.state.json --confirm
34
34
  guanmetric flow verify --state metric_flow.state.json
35
+ guanmetric flow export --state metric_flow.state.json --out created-metrics.json
35
36
  guanmetric flow reconcile --file metric_flow.json --state metric_flow.state.json --key <flow_key> --metric-id <metric_id>
36
37
  guanmetric flow reconcile --file metric_flow.json --state metric_flow.state.json --key <flow_key> --metric-id <metric_id> --confirm
38
+ guanmetric dsl preview ./metric-project
39
+ guanmetric dsl document ./metric-project --out ./metric-project/.guanmetric/docs
40
+ guanmetric dsl plan ./metric-project --operation create
41
+ guanmetric dsl plan ./metric-project --operation create --key <flow_key>
42
+ guanmetric dsl apply ./metric-project --operation create --state .guanmetric/metric-state.json
43
+ guanmetric dsl apply ./metric-project --operation create --state .guanmetric/metric-state.json --confirm
44
+ guanmetric dsl checkout <metric_id_1> <metric_id_2> -d ./metric-project
45
+ guanmetric dsl diff ./metric-project
46
+ guanmetric dsl plan ./metric-project --operation edit
47
+ guanmetric dsl plan ./metric-project --operation edit --metric-id <metric_id>
37
48
  guanmetric edit <metric_id> --file patch.json --dry-run
38
49
  guanmetric delete <metric_id>
39
50
  guanmetric batch online --id <metric_id_1> --id <metric_id_2> --dry-run
@@ -84,13 +95,37 @@ guanmetric fetch POST /api/metric-platform/<unwrapped_endpoint> --file request.j
84
95
 
85
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`。
86
97
 
98
+ 涉及 BI 8.4.0 及以上的指标、公共维度、查询加速或版本探测时,先读取 `references/metric-bi84-compatibility.md`;不得把多候选列表当作单个绑定。低版本继续使用旧协议,无法获取有效版本则报错。
99
+
87
100
  构造或解析指标创建、编辑、详情和列表请求时,先读取 `metric-api-contracts.md`。其中包含三类指标的真实脱敏响应、原子字段/表达式两种模式、六种衍生配置、JSON Schema 以及读模型到写模型映射。详情响应是读模型:`fdInfos`、对象数组形式的 `applicableDims`、对象形式的 `timeDim`、`baseMetric` 和用户对象不能原样提交;编辑请求必须按对应 Update DTO 白名单显式构造。列表请求的 `subTypes` 是逗号分隔字符串,不是 JSON 数组。
88
101
 
89
102
  构造或解析指标主题/指标目录的创建、编辑、详情/列表/目录树和删除请求时,先读取 `metric-hierarchy-api-contracts.md`。主题编辑只提交 `name/icon/iconColor`;目录编辑只提交 `name/parentDirId/dirType`,其中 `dirType` 固定为 `METRIC_PLATFORM`。指标目录没有单条详情接口,`directory get` 是从指定 Project 的目录树按 ID 提取节点。创建和编辑必须写后回读;删除默认只展示目标,必须追加 `--confirm`。本轮不提供指标 move 或指标 owner 转移命令。
90
103
 
91
- 用户通过对话提出一批相互依赖的指标创建需求时,优先使用 `guanmetric flow`,不要逐个调用 `create`/`fetch` 后自行判断成功。标准模板经用户确认且所有真实指标行为“可创建”后,必须优先执行 `flow generate --file <standard.xlsx> --out <metric_flow.json>`,不要由 Agent 手写计划。该命令会解析数据集字段、当前责任人/唯一用户、业务属性、已有指标和批内引用,生成稳定 key 与占位符,并立即运行 `flow plan`;无法唯一解析时输出带 Sheet/行/列的稳定诊断且不写计划。同一模板不能混合“上线”和“草稿”:全部上线生成 `usable`,全部草稿生成 `draft`,混合时必须拆分模板。提交真实创建前必须检查生成计划中的取数定义(`fdId+aggrType` 或 `formulaField`)、适用维度、时间维度、业务属性、责任人、格式、复合/衍生引用和 `publish` 均与确认后的标准模板一致;任一关键字段缺失都不得执行 `flow apply --confirm`。生成后仍可单独运行 `flow plan`;用户确认后运行带 `--confirm` 的 `flow apply`,并始终提供 `--state` 状态文件以便失败或审批后续跑。`acceptance.mode=usable` 要求请求 `publish=true`,最终状态为 `PUBLISHED`、当前用户 `canUse=true`,且 `guancli metric query --limit 1 -f json` 成功;组合衍生引用带固定高级计算粒度的指标时,Flow 会读取引用定义并自动追加唯一兼容的 `--dim "<时间维度> toMonth/toWeek/..."`,同时把实际维度、粒度和策略写入 state 的 `query` 证据。引用粒度不一致时返回 `FLOW_QUERY_GRANULARITY_CONFLICT`,不能靠循环尝试不同粒度掩盖定义冲突。`acceptance.mode=draft` 要求 `publish=false`,只验证草稿定义能够回读。审批中的指标返回 `pending`,不能汇报为已可用。创建结果未知时,`flow apply` 会永久保持该条目为 `blocked/reconcile`,绝不重发创建;创建前已将真正提交的 canonical 请求保存到 state 的 `submittedDefinition`,`reconcile` 只能据此核对候选,不能按实时元数据重建请求,而且同一 state 内一个非空 metricId 只能绑定一个 key。Agent 先只读核对线上候选,再执行不带 `--confirm` 的 `flow reconcile --file ... --state ... --key ... --metric-id ...` 预览,确认环境、planHash、类型、候选 ID 未被占用和关键定义完全一致后,才追加 `--confirm` 把真实 ID 写回 state。原生 Unix/Windows 中,confirmed apply 会在读取计划或访问 BI 前取得 state 锁,verify/reconcile 也在读取 state 或访问 BI 前取得锁,三者由跨进程独占锁串行化;apply preview 不读取 state,因此不持锁。遇到“正由另一个操作占用”时等待对方结束后重试,禁止改用另一个 state 绕过。WASI/非原生运行时因无法证明跨 guest 单写者,明确禁用 apply/verify/reconcile,只保留 generate/plan 等只读能力。部分指标已创建后禁止自动删除回滚,修正问题后复用同一计划和状态文件继续验证。完整契约见 `metric-flow.md`。
104
+ 用户通过对话提出一批相互依赖的指标创建需求时,优先使用 `guanmetric flow`,不要逐个调用 `create`/`fetch` 后自行判断成功。标准模板经用户确认且所有真实指标行为“可创建”后,必须优先执行 `flow generate --file <standard.xlsx> --out <metric_flow.json>`,不要由 Agent 手写计划。该命令会解析数据集字段、当前责任人/唯一用户、业务属性、已有指标和批内引用,生成稳定 key 与占位符,并立即运行 `flow plan`;无法唯一解析时输出带 Sheet/行/列的稳定诊断且不写计划。同一模板不能混合“上线”和“草稿”:全部上线生成 `usable`,全部草稿生成 `draft`,混合时必须拆分模板。提交真实创建前必须检查生成计划中的取数定义(`fdId+aggrType` 或 `formulaField`)、适用维度、时间维度、业务属性、责任人、格式、复合/衍生引用和 `publish` 均与确认后的标准模板一致;任一关键字段缺失都不得执行 `flow apply --confirm`。生成后仍可单独运行 `flow plan`;用户确认后运行带 `--confirm` 的 `flow apply`,并始终提供 `--state` 状态文件以便失败或审批后续跑。`acceptance.mode=usable` 要求请求 `publish=true`,最终状态为 `PUBLISHED`、当前用户 `canUse=true`,且 `guancli metric query --limit 1 -f json` 成功;组合衍生引用带固定高级计算粒度的指标时,Flow 会读取引用定义并自动追加唯一兼容的 `--dim "<时间维度> toMonth/toWeek/..."`,同时把实际维度、粒度和策略写入 state 的 `query` 证据。引用粒度不一致时返回 `FLOW_QUERY_GRANULARITY_CONFLICT`,不能靠循环尝试不同粒度掩盖定义冲突。`acceptance.mode=draft` 要求 `publish=false`,只验证草稿定义能够回读。审批中的指标返回 `pending`,不能汇报为已可用。创建结果未知时,`flow apply` 会永久保持该条目为 `blocked/reconcile`,绝不重发创建;创建前已将真正提交的 canonical 请求保存到 state 的 `submittedDefinition`,`reconcile` 只能据此核对候选,不能按实时元数据重建请求,而且同一 state 内一个非空 metricId 只能绑定一个 key。Agent 先只读核对线上候选,再执行不带 `--confirm` 的 `flow reconcile --file ... --state ... --key ... --metric-id ...` 预览,确认环境、planHash、类型、候选 ID 未被占用和关键定义完全一致后,才追加 `--confirm` 把真实 ID 写回 state。原生 Unix/Windows 中,confirmed apply、verify、reconcile 和 export 对同一 state 使用跨进程独占锁串行化;apply preview 不读取 state,因此不持锁。遇到“正由另一个操作占用”时等待对方结束后重试,禁止改用另一个 state 绕过。WASI/非原生运行时因无法证明跨 guest 单写者,明确禁用 apply/verify/reconcile/export,只保留 generate/plan 等只读能力。部分指标已创建后禁止自动删除回滚,修正问题后复用同一计划和状态文件继续验证。完整契约见 `metric-flow.md`。
92
105
  `flow verify` 的 `usable` 只证明指标已发布、可使用且查询成功,不证明它与另一个指标数值等价。只有用户明确要求新旧指标或两组指标数值对比时,才使用 `guancli metric batch-query` 执行独立的等价验证;必须固定相同粒度、筛选范围、排序和 raw 数值,按维度键对齐,并把可能截断的结果报告为 `inconclusive`,禁止用无排序的默认前 50 行按位置比较后宣称指标定义错误。详细 recipe 见 guancli skill 的 `references/metric-batch-query.md`。
93
106
 
107
+ 本批本地基础指标上的期末值(`LAST`)必须等基础指标实际创建并验证后,再由 confirmed Flow/DSL apply 回读其服务端 `isLastSupported`。明确不支持、字段缺失或详情不可读时阻断 LAST 创建并保留 state;不能因为 plan 通过就认为该期末值可创建,也不能绕过保护重试或删除重建已创建的基础指标。
108
+
109
+ 需要把 Flow 创建结果交给 guanvis 等下游时,使用 `flow export --state <state> --out <created-metrics.json>`,不要让下游直接读取 Flow state。只有 usable state 整体 succeeded 且每一项 verified 时才允许导出;partial/pending/blocked/failed/draft 或环境不一致都会阻断。输出只包含环境、planHash、逻辑 key、真实 metric ID、类型、验收状态和可选的服务端 canonical 定义指纹;已有文件默认拒绝覆盖,明确追加 `--force` 才替换。下游仍必须使用 `guanvis metric-init <metricId...>` 回读服务端生成 `metrics.js`,禁止从 handoff、Flow state、Flow plan 或 Metric IR 合成指标详情。完整契约见 `metric-flow.md`、`metric-flow-handoff.schema.json`、`metric-flow-handoff-example.json`、`metric-flow-export.schema.json` 和 `metric-flow-export-example.json`。
110
+
111
+ `guanmetric dsl init --project-id <id> --dir-id <id> --dataset <alias>=<datasetId> --metric <alias>=<metricId> -d <project_dir>` 只读校验主题、目录、当前用户和显式选择的数据集/远端指标,并读取当前全部启用的业务属性,生成 context、datasets、metrics、biz-attrs catalog 与环境绑定 manifest;dataset/metric 至少选一种。远端指标通过 `metricRef(METRIC.<alias>)` 引用,状态与维度只作快照,plan/apply 仍读取服务端权威状态。业务属性以 `ATTR["显示名称"]` 引用;启用配置重名时 init 拒绝,已停用配置不暴露。创建指标使用 `.businessAttributes(bizAttr(...), ...)`,字符串/字符串数组和枚举值会按快照提前校验,但必填、默认值和最终合法性仍由 plan/服务端裁决。重复 init 刷新生成快照但不覆盖已有配置和指标脚本,跨环境拒绝。
112
+
113
+ 需要评审 DSL 工程血缘时,使用纯本地 `dsl document <project_dir> --out <output_dir>`。命令在完整编译通过后固定生成 `metric-dependencies.json` 和 `metric-documentation.md`:前者是版本化机器契约,后者包含摘要、节点/边表、稳定创建顺序和 Mermaid 图。节点区分 create、edit、dataset、remoteMetric,边区分 datasetSource、localMetric、remoteMetric;不会访问 BI。已有任一固定输出文件时默认拒绝,明确追加 `--force` 才替换。完整契约见 `metric-dsl.md`、`metric-dsl-dependencies.schema.json` 和 `metric-dsl-document-output.schema.json`。
114
+
115
+ 大型工程可对 `dsl plan/apply` 做选择性执行。create 使用可重复的 `--key <flow_key>`,会自动包含全部传递本地上游但不包含下游;edit 使用可重复的 `--metric-id <metric_id>`,只处理明确选择的 checkout 指标。两类参数不能混用,不传时保持全量行为。无论选择什么,命令都先完整编译整个工程,未选脚本的语法或语义错误也会阻断;随后 state、planHash 和 edit sourceHash 只绑定规范化后的选中子集,未选脚本变更不会使该 state 失效。续跑必须使用同一个 state,并解析为同一 `resolved` 子集;省略选择或换成不同子集会拒绝复用。stdout 的可选 `selection` 明确列出 requested、resolved 和自动纳入的 autoIncluded。完整契约见 `metric-dsl.md` 和 `metric-dsl-selection.schema.json`。
116
+
117
+ 确认后的标准 Excel 可以通过 `guanmetric dsl generate --file <standard.xlsx> -d <new_project_dir>` 单向生成完整 DSL 工程。该命令复用 Flow generate 的字段、指标引用、业务属性和远端预检,目标目录必须不存在;它在临时目录生成 config、四类 catalog 和指标脚本,完整 DSL 编译通过后才原子落盘,不创建或编辑 BI 指标。生成后以 DSL 为事实源,不做 Excel/DSL 双向合并。单组输入仍直接生成一个工程;跨主题、目录或保存方式时自动按 `(projectId,parentDirId,acceptance)` 生成 `project_NNN` 子工程和 `guanmetric-dsl-bundle.json` 清单,不要再人工拆改 Excel。部分分组被真实语义错误阻断时,合法分组仍会原子生成,stdout 为 `generated=true,complete=false` 并以非零状态退出;只能继续清单中已生成的子工程,不能忽略对应 `projectKey` 的 diagnostics。不同子工程不能保留批内指标依赖;生成器发现引用名称属于同一 Excel 的其他子工程时会明确拒绝,绝不会退化成线上同名指标。逐项责任人解析后若都等于当前登录用户,可无损映射为工程级 `currentUser()`;不同用户的单指标覆盖、动态参数、复合公式字段映射或其它当前 DSL 无法无损表达的语义仍以稳定诊断拒绝。复制现有复合指标且同名时间字段在多个引用中不唯一时,优先在标准模板“时间维度”写真实字段 ID;生成器只有在能找到同名同公式的现有复合定义且其时间字段 ID 唯一一致时才回溯复用,禁止按公式顺序猜字段。单工程继续使用兼容的输出契约 1.0;bundle 使用 1.1。完整边界和输出契约见 `metric-dsl.md`、`metric-dsl-generate.schema.json`、`metric-dsl-generate-1.1.schema.json`。
118
+
119
+ 同比/环比的 `comparative({...})` 可选使用布尔字段 `replenishDimData`,用于无损表达标准模板中的“维度值补齐”;省略时不向服务端请求体写入该字段。指定日期对比使用 `fixedBase`,月末/季末/年末和按年周比较使用对应 `offsetType`;最近 N 与累计支持基于日期筛选开始或结束日期。时间衍生可显式保留源定义的 `dateFdId`(含粒度后缀),复合指标使用共用维度时仍可单独指定时间维度。原子 `expression()` 会按首版完整安全子集语法校验 `SUM/COUNT`、加减和 `CASE WHEN`,不会把缺操作数、残缺 CASE 或聚合外字段输出为有效 IR。
120
+
121
+ 多指标 edit plan 中,远端读取、目标字段漂移或单项 DTO 校验失败只把对应指标记录为 `blocked` item 和 warning diagnostic,其他独立指标仍可进入 confirmed apply;DSL、checkout manifest、环境、attach 类型与覆盖等结构错误继续阻断整批。confirmed apply 会把逐项结果持久化到 state,blocked/unknown 项不会自动重发。
122
+
123
+ 四类 catalog 仅允许在固定 catalog 加载阶段注册;catalog 项必须来自对应 DSL 构造器,进入 helper 或指标/编辑脚本前注册表与数据集字段容器会封存,禁止普通对象伪造、晚注册、替换或注入。筛选、公式和业务属性值同样必须来自对应类型化 helper,不接受手写同形对象;Builder 内部状态不向脚本暴露,注册时冻结 IR 快照,注册后修改 Builder 不影响结果。编辑已有业务限定衍生指标并切换到其它模式时,未显式设置筛选会清理旧 filter;同一 attach 显式调用 `filter/clearFilter` 时显式值优先,结果不受 setter 调用顺序影响。
124
+
125
+ 每个 catalog 注册函数只能出现在对应分域文件,执行阶段由 Go 宿主闭包提供,DSL 脚本不能自行切换;create plan/apply 在 catalog manifest 存在时必须校验当前环境和 project/directory 绑定。编辑业务属性的非空值必须使用 `bizAttr(ATTR[...], value)`,拒绝重复属性 ID;空数组表示清空。
126
+
127
+ 指标 DSL 当前处于分阶段交付。`guanmetric dsl preview <project_dir>` 是纯本地、确定性的编译入口,不访问 BI,也不创建或编辑指标;`dsl plan <project_dir> --operation create` 把同一 IR 转成 Flow 1.0 并复用 Flow 的只读远端校验,但仍不写 BI。`dsl apply <project_dir> --operation create` 默认仍是 preview;只有同时追加 `--confirm --state <path>` 才会在取得 Flow state 锁后真实创建并验证。确认执行会在 state 旁保存不可静默覆盖的派生 Flow 计划,并把路径写入 state.planFile;续跑继续用同一 DSL、state 和命令,verify 使用 `flow verify --state`,结果不确定时按 state.planFile 调用 `flow reconcile --file ... --state ...`。`dsl checkout <metricId...> -d <project_dir>` 只读回读草稿(仅在结构化“草稿不存在”时回退正式详情),按三类 Update DTO 白名单生成 `.guanmetric/manifest.json`、base 快照和默认 no-op `edit_*.js`;已有编辑脚本不会被覆盖。编辑 attach 已支持 rename、englishName、description、format、filter/clearFilter、dimensions、timeDimension/clearTimeDimension、businessAttributes 和 publish 字段级 setter,并支持原子 `fieldSource/expressionSource`、复合 `formula/useCommonDimensions`、衍生 `from + comparative/recent/cumulative/last/businessCondition` 与组合衍生 `composite`;编辑引用只允许明确远端 `metricRef()`,不提供任意 JSON path。`dsl diff` 纯本地展示相对 checkout 基线的字段差异;`dsl plan --operation edit` 重新回读当前草稿/正式详情,允许未修改字段漂移,目标字段远端变化且不同于 DSL 目标时以 `METRIC_DSL_REMOTE_DRIFT` 阻断,远端已等于目标时生成 no-op;同比/环比和期末值会只读回读新基础指标并冻结其时间维度。edit plan 只读,不执行 update-impact 或更新。`dsl apply --operation edit` 不带确认时执行 save-precheck/update-impact 并输出 checks;用户明确接受冲突与影响后才可追加 `--confirm --state` 原地更新。confirmed edit apply 会锁定并保存源码 hash、环境、冻结计划和逐项 state,写前统一复核所有 currentFingerprint,写后按三类 DTO 回读;同一命令可续跑,已达到目标不重复写,结果不确定且未达到目标时进入 blocked/reconcile 并禁止自动重发。多指标编辑没有服务端事务,部分完成以 state 为恢复和审计事实源。创建 DSL 已支持原子字段聚合与字段表达式、复合指标,以及对比、最近 N、累计、期末值、业务限定和组合衍生六类衍生指标;三类创建指标都可使用 catalog 驱动的 `businessAttributes(bizAttr(...))`、非空 JSON `format({...})` 和类型化 `filter(condition/allOf/anyOf)`。原子和复合可显式设置 `dimensions/timeDimension`;复合的显式维度与 `useCommonDimensions()` 互斥,时间维度必须属于适用维度。表达式使用 `expression()`,当前只接受 `SUM/COUNT`、加减和 `CASE WHEN` 安全子集,方括号内必须是所选数据集的真实字段 ID,最终请求只使用 `formulaField.fdFormula`。创建 DSL 暂不支持单指标责任人覆盖和动态参数;后续 Excel -> DSL 生成遇到这些输入必须拒绝,不能静默丢字段。本地/远端指标引用分别使用 `ref()`/`metricRef()`,draft 模式禁止批内本地引用。工程必须包含 `metric.config.js`,catalog 按 `catalog.context.js`、`catalog.datasets.js`、`catalog.metrics.js`、`catalog.biz-attrs.js` 固定顺序加载;存在 `helpers/` 时按文件名加载第一层 `*.js`,建议使用数字前缀明确依赖顺序,helper 只声明常量、纯函数和 Builder 组合,不得在加载时修改配置/catalog 或注册指标;最后按文件名加载指标脚本。helper 同样计入脚本数与源码大小限制,加载期副作用返回 `METRIC_DSL_HELPER_SIDE_EFFECT`。当前 DSL 不是不可信代码沙箱:原生 CLI 使用进程级内存边界,WASI 使用宿主 guest 内存边界;CLI 另外限制执行时间、调用栈、脚本数、源码大小、注册指标数和导出大小,并禁用时间、随机数、动态代码执行及外部 I/O 能力。完整的当前语法、输出契约和限制见 `metric-dsl.md`;创建完整复用 Flow,编辑复用三类专用原地更新链路,禁止把 preview/plan 成功解释为写入成功。
128
+
94
129
  指标定义是否合法由 BI 后端最终裁决。Flow 的单指标业务校验必须取“当前 Web 创建页已有规则”减去“当前后端创建链路已有规则”的差集:只补前端有而后端没有的规则,不复制后端已有规则,也不擅自新增前后端都没有的规则。当前差集包括草稿名称格式/长度、英文名格式/长度、业务口径最大长度、原子 `fdId+aggrType` 配对完整性、普通衍生 `baseMetricId+advType` 必填、自定义业务属性文本长度以及原子 save-precheck;计划结构、批内依赖、占位符、环境/状态一致性和验收编排属于 Flow 自身契约。创建接口还会执行落库、权限和上线等后置步骤,因此任何未返回可记录 `metricId` 的创建错误都必须保留结构化业务状态并进入 `reconcile`,不能自动重试。校验职责基线见 `metric-validation-ownership.md`。
95
130
  查询加速写操作已封装为 `accelerate` 专用命令;查询加速列表查询使用 `guancli metric accelerate list <metric_id>`。查询加速筛选条件使用和指标定义一致的 `WebFilterData` 结构,可放在完整请求体的 `filter` 字段,也可通过 `--filter-json` 或 `--filter-file` 传入;合法节点仅为 `condition/operator/composition`,禁止使用 `group/combineType/conditions`。查询加速无法从指标适用维度自动补齐另一数据集的字段元数据,因此条件必须显式提供 `dsId/fdId/name/fdType/metaType`;清空筛选条件可传 `--filter-json null`。完整契约和嵌套示例见 `metric-common-fields.md`。
96
131
  指标树及其目录的创建、修改和删除已封装为 `metric-tree` 专用命令,优先使用专用命令,不要再用裸 `fetch` 直接调用写接口。构造或解析指标树及目录的请求时,先读取 `metric-tree-api-contracts.md`;详情/搜索名称字段是 `metricTreeName`,父目录列表及编辑返回对象名称字段是 `name`,目录树用 `id/name`、目录详情用 `dirId/dirName`,读模型不得整体回写。指标树和目录删除默认只展示详情,明确追加 `--confirm` 才提交。指标树目录必须用 `metric-tree directory` 管理并固定 `dirType=METRIC_TREE`;不要把 `METRIC_PLATFORM` 指标目录 ID 当作指标树目录 ID。用户给出指标拆解公式时,按 `metric-tree-mutation.md` 解析成 `metricRelationTree`;遇到复合指标时读取指标详情中的 `formula`,按规则递归展开或在计划中标注不能无损展开的原因。
@@ -119,7 +154,20 @@ guanmetric fetch POST /api/metric-platform/<unwrapped_endpoint> --file request.j
119
154
  - `metric-flow.md`
120
155
  - `metric-flow-generate-example.json`
121
156
  - `metric-flow-generate.schema.json`
157
+ - `metric-flow-export-example.json`
158
+ - `metric-flow-export.schema.json`
159
+ - `metric-flow-handoff-example.json`
160
+ - `metric-flow-handoff.schema.json`
161
+ - `metric-dsl-dependencies-example.json`
162
+ - `metric-dsl-dependencies.schema.json`
163
+ - `metric-dsl-document-output-example.json`
164
+ - `metric-dsl-document-output.schema.json`
165
+ - `metric-dsl-selection-example.json`
166
+ - `metric-dsl-selection.schema.json`
167
+ - `metric-dsl-generate-example.json`
168
+ - `metric-dsl-generate.schema.json`
122
169
  - `metric-validation-ownership.md`
170
+ - `metric-dsl.md`
123
171
  - `metric-api-contracts.md`
124
172
  - `metric-api-contract-examples.json`
125
173
  - `metric-api-contract.schema.json`
@@ -86,6 +86,13 @@
86
86
  编辑接口接收完整更新写模型,不是 JSON Merge Patch。`guanmetric edit` 可以让用户提供 patch,
87
87
  但 CLI 必须先把详情读模型规范化成完整写模型,再合并 patch。
88
88
 
89
+ 业务属性配置由既有 `GET /api/metric-attr-config` 读取,代理还原后的 Spring 路由为
90
+ `GET /metric-attr-config`,`MetricAttrConfigNgController.query` 要求 `BASE / READ`。DSL init
91
+ 只把启用配置的 id、显示名称、类型、默认值和枚举选项保存为本地快照;创建请求仍只提交
92
+ `bizAttrs: [{id,values}]`。现有 plan 会读取当前配置执行前端差集校验,服务端负责最终复核。
93
+ 该读取的 PAT 有权、无权和
94
+ 资源不存在对照尚未执行,不能由本地测试替代。
95
+
89
96
  ## 原子指标
90
97
 
91
98
  ### 字段来源模式
@@ -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/`;这些运行产物不纳入源码契约,也不提交账号配置或令牌。
@@ -0,0 +1,30 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "dslVersion": "1.0",
4
+ "acceptance": "usable",
5
+ "defaults": {
6
+ "projectId": "project-1",
7
+ "directoryId": "directory-1",
8
+ "businessOwnerId": "current"
9
+ },
10
+ "summary": {
11
+ "createCount": 2,
12
+ "editCount": 1,
13
+ "datasetCount": 1,
14
+ "remoteMetricCount": 1,
15
+ "edgeCount": 3
16
+ },
17
+ "nodes": [
18
+ {"id": "create:sales", "kind": "create", "key": "sales", "name": "销售额", "subType": "ATOMIC"},
19
+ {"id": "create:sales_ratio", "kind": "create", "key": "sales_ratio", "name": "销售占比", "subType": "COMPOSITE"},
20
+ {"id": "dataset:dataset-sales", "kind": "dataset", "datasetId": "dataset-sales"},
21
+ {"id": "edit:metric-profit", "kind": "edit", "metricId": "metric-profit", "subType": "DERIVED", "operationCount": 1},
22
+ {"id": "remoteMetric:metric-cost", "kind": "remoteMetric", "metricId": "metric-cost"}
23
+ ],
24
+ "edges": [
25
+ {"from": "create:sales", "to": "create:sales_ratio", "relation": "localMetric"},
26
+ {"from": "dataset:dataset-sales", "to": "create:sales", "relation": "datasetSource"},
27
+ {"from": "remoteMetric:metric-cost", "to": "edit:metric-profit", "relation": "remoteMetric"}
28
+ ],
29
+ "createOrder": ["sales", "sales_ratio"]
30
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://guandata.dev/schemas/guanmetric/metric-dsl-dependencies-1.0.json",
4
+ "title": "guanmetric DSL dependency document v1.0",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "dslVersion", "acceptance", "defaults", "summary", "nodes", "edges", "createOrder"],
8
+ "properties": {
9
+ "schemaVersion": {"const": "1.0"},
10
+ "dslVersion": {"const": "1.0"},
11
+ "acceptance": {"enum": ["usable", "draft"]},
12
+ "defaults": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["projectId", "directoryId", "businessOwnerId"],
16
+ "properties": {
17
+ "projectId": {"type": "string"},
18
+ "directoryId": {"type": "string"},
19
+ "businessOwnerId": {"type": "string"}
20
+ }
21
+ },
22
+ "summary": {"$ref": "#/$defs/summary"},
23
+ "nodes": {"type": "array", "items": {"$ref": "#/$defs/node"}},
24
+ "edges": {"type": "array", "items": {"$ref": "#/$defs/edge"}},
25
+ "createOrder": {"type": "array", "items": {"type": "string"}}
26
+ },
27
+ "$defs": {
28
+ "summary": {
29
+ "type": "object",
30
+ "additionalProperties": false,
31
+ "required": ["createCount", "editCount", "datasetCount", "remoteMetricCount", "edgeCount"],
32
+ "properties": {
33
+ "createCount": {"type": "integer", "minimum": 0},
34
+ "editCount": {"type": "integer", "minimum": 0},
35
+ "datasetCount": {"type": "integer", "minimum": 0},
36
+ "remoteMetricCount": {"type": "integer", "minimum": 0},
37
+ "edgeCount": {"type": "integer", "minimum": 0}
38
+ }
39
+ },
40
+ "node": {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "required": ["id", "kind"],
44
+ "properties": {
45
+ "id": {"type": "string", "minLength": 1},
46
+ "kind": {"enum": ["create", "edit", "dataset", "remoteMetric"]},
47
+ "key": {"type": "string"},
48
+ "metricId": {"type": "string"},
49
+ "datasetId": {"type": "string"},
50
+ "name": {"type": "string"},
51
+ "subType": {"enum": ["ATOMIC", "COMPOSITE", "DERIVED"]},
52
+ "operationCount": {"type": "integer", "minimum": 1}
53
+ }
54
+ },
55
+ "edge": {
56
+ "type": "object",
57
+ "additionalProperties": false,
58
+ "required": ["from", "to", "relation"],
59
+ "properties": {
60
+ "from": {"type": "string", "minLength": 1},
61
+ "to": {"type": "string", "minLength": 1},
62
+ "relation": {"enum": ["datasetSource", "localMetric", "remoteMetric"]}
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "command": "dsl.document",
4
+ "valid": true,
5
+ "outputDir": ".guanmetric/docs",
6
+ "files": [
7
+ ".guanmetric/docs/metric-dependencies.json",
8
+ ".guanmetric/docs/metric-documentation.md"
9
+ ],
10
+ "summary": {
11
+ "createCount": 2,
12
+ "editCount": 1,
13
+ "datasetCount": 1,
14
+ "remoteMetricCount": 1,
15
+ "edgeCount": 3
16
+ },
17
+ "diagnostics": []
18
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://guandata.dev/schemas/guanmetric/metric-dsl-document-output-1.0.json",
4
+ "title": "guanmetric dsl document output v1.0",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "command", "valid", "files", "summary", "diagnostics"],
8
+ "properties": {
9
+ "schemaVersion": {"const": "1.0"},
10
+ "command": {"const": "dsl.document"},
11
+ "valid": {"type": "boolean"},
12
+ "outputDir": {"type": "string"},
13
+ "files": {"type": "array", "items": {"type": "string"}},
14
+ "summary": {"$ref": "metric-dsl-dependencies.schema.json#/$defs/summary"},
15
+ "diagnostics": {
16
+ "type": "array",
17
+ "items": {
18
+ "type": "object",
19
+ "additionalProperties": false,
20
+ "required": ["code", "severity", "message"],
21
+ "properties": {
22
+ "code": {"type": "string"},
23
+ "severity": {"enum": ["error", "warning"]},
24
+ "file": {"type": "string"},
25
+ "line": {"type": "integer", "minimum": 1},
26
+ "column": {"type": "integer", "minimum": 1},
27
+ "metricKey": {"type": "string"},
28
+ "field": {"type": "string"},
29
+ "message": {"type": "string"}
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://guandata.dev/schemas/guanmetric/metric-dsl-generate-1.1.json",
4
+ "title": "guanmetric dsl generate bundle output 1.1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "command", "generated", "complete", "metricCount", "files", "diagnostics"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "1.1" },
10
+ "command": { "const": "dsl.generate" },
11
+ "generated": { "type": "boolean" },
12
+ "complete": { "type": "boolean" },
13
+ "projectDir": { "type": "string", "minLength": 1 },
14
+ "metricCount": { "type": "integer", "minimum": 0 },
15
+ "files": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true },
16
+ "projects": {
17
+ "type": "array",
18
+ "items": {
19
+ "type": "object",
20
+ "additionalProperties": false,
21
+ "required": ["key", "projectDir", "projectId", "directoryId", "acceptance", "metricCount", "files"],
22
+ "properties": {
23
+ "key": { "type": "string", "pattern": "^project_[0-9]{3}$" },
24
+ "projectDir": { "type": "string", "minLength": 1 },
25
+ "projectId": { "type": "string", "minLength": 1 },
26
+ "directoryId": { "type": "string", "minLength": 1 },
27
+ "acceptance": { "enum": ["usable", "draft"] },
28
+ "metricCount": { "type": "integer", "minimum": 1 },
29
+ "files": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true }
30
+ }
31
+ }
32
+ },
33
+ "diagnostics": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "additionalProperties": false,
38
+ "required": ["code", "severity", "message"],
39
+ "properties": {
40
+ "code": { "type": "string", "minLength": 1 },
41
+ "severity": { "enum": ["error", "warning"] },
42
+ "projectKey": { "type": "string", "pattern": "^project_[0-9]{3}$" },
43
+ "sheet": { "type": "string" },
44
+ "row": { "type": "integer", "minimum": 1 },
45
+ "field": { "type": "string" },
46
+ "message": { "type": "string" }
47
+ }
48
+ }
49
+ }
50
+ },
51
+ "allOf": [
52
+ {
53
+ "if": { "properties": { "generated": { "const": true } }, "required": ["generated"] },
54
+ "then": { "required": ["projectDir", "projects"], "properties": { "projects": { "minItems": 1 } } }
55
+ }
56
+ ]
57
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "schemaVersion": "1.1",
3
+ "command": "dsl.generate",
4
+ "generated": true,
5
+ "complete": false,
6
+ "projectDir": "metric-bundle",
7
+ "metricCount": 2,
8
+ "files": [
9
+ "guanmetric-dsl-bundle.json",
10
+ "project_001/atomic_metric_001.js",
11
+ "project_001/metric.config.js"
12
+ ],
13
+ "projects": [
14
+ {
15
+ "key": "project_001",
16
+ "projectDir": "metric-bundle/project_001",
17
+ "projectId": "project-1",
18
+ "directoryId": "dir-1",
19
+ "acceptance": "usable",
20
+ "metricCount": 1,
21
+ "files": ["atomic_metric_001.js", "metric.config.js"]
22
+ }
23
+ ],
24
+ "diagnostics": [
25
+ {
26
+ "code": "FLOW_FILTER_INVALID",
27
+ "severity": "error",
28
+ "projectKey": "project_002",
29
+ "sheet": "原子指标",
30
+ "row": 3,
31
+ "field": "业务限定",
32
+ "message": "筛选字段与指标数据集不一致"
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "command": "dsl.generate",
4
+ "generated": true,
5
+ "projectDir": "metric-project",
6
+ "metricCount": 3,
7
+ "files": [
8
+ ".guanmetric/catalog-manifest.json",
9
+ "atomic_metric_001.js",
10
+ "catalog.biz-attrs.js",
11
+ "catalog.context.js",
12
+ "catalog.datasets.js",
13
+ "catalog.metrics.js",
14
+ "composite_metric_002.js",
15
+ "derived_metric_003.js",
16
+ "metric.config.js"
17
+ ],
18
+ "diagnostics": []
19
+ }