@guandata/guancli 1.0.59 → 1.0.61

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## @guandata/guancli 1.0.61 - 2026-09-18
4
+
5
+ - 指标取数不再静默忽略无效筛选与排序字段:`--dim`、`--filter`、`--sort-asc`/`--sort-desc` 都按指标详情中的字段校验,未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;结构化 `--filter-json`/`--filter-file` 在解析阶段返回 `FILTER_UNKNOWN_FIELD`,不会透传未知字段。
6
+ - 排序目标除了适用维度和时间维度,还接受保存卡片中真实存在的高级计算列,以及泛化查询结果列名 `<指标名>_<后缀>`(如 `_yoy`、`_recent_7d`、`_percentage`、`_rank`)。
7
+ - 指标详情 `publicDimensionMap` 中唯一映射到一个适用维度的公共维度名,可直接用于 `--dim`、日期粒度表达式、排序和筛选;同名映射到多个物理字段时明确报歧义,不猜测字段。
8
+
9
+ ## @guandata/guancli 1.0.60 - 2026-09-17
10
+
11
+ - 新增内部 OAuth2 应用认证:整体注入 `GUANCLI_OAUTH2_BASE_URL`、`GUANCLI_OAUTH2_ACCESS_TOKEN` 与用户身份(`GUANCLI_OAUTH2_UID` 或 `GUANCLI_OAUTH2_LOGIN_ID`);CLI 不保存、不交换也不刷新该 Token,且 OAuth2 与 OIDC 变量同时出现时明确报错,不回退本地 profile。
12
+ - Personal Access Token 登录会保存登录 Domain,多 profile 场景可按 Domain 筛选。
13
+ - 新增 `ds get <ds_id> --validate-downstream`:逐个校验血缘中的下游资源是否仍存在,只有结构化业务状态 `1002` 或 HTTP 404 才判定为不存在,认证/HTTP/解析错误直接失败;单次最多校验 100 个下游资源、总超时 30 秒。
14
+
3
15
  ## @guandata/guancli 1.0.59 - 2026-09-15
4
16
 
5
17
  - `--filter` 支持符号比较操作符 `=`、`!=`、`<>`、`<`、`<=`、`>`、`>=`,统一归一化为枚举操作符;`--filter-json`、`--filter-file` 和 `metric batch-query` 的 `operator` 同样支持。`BT` 也接受两个不含空格的边界用空格分隔。
package/README.md CHANGED
@@ -43,6 +43,16 @@ guancli chatbi query --theme-name "经营主题" --message "最近30天营业收
43
43
 
44
44
  ## 版本更新
45
45
 
46
+ ### @guandata/guancli 1.0.61
47
+
48
+ - 指标取数会校验 `--dim`、`--filter` 和排序字段:未命中指标详情字段时返回明确错误,不再静默忽略条件。
49
+ - 排序支持保存卡片的高级计算列与泛化结果列名;唯一映射的公共维度名可用于维度、排序和筛选。
50
+
51
+ ### @guandata/guancli 1.0.60
52
+
53
+ - 新增内部 OAuth2 应用认证,按 `GUANCLI_OAUTH2_*` 整体注入环境与用户身份,CLI 不保存、不刷新该 Token。
54
+ - PAT 登录会保存登录 Domain;新增 `ds get --validate-downstream` 校验血缘下游资源是否仍存在。
55
+
46
56
  ### @guandata/guancli 1.0.59
47
57
 
48
58
  - 指标筛选支持 `=`、`!=`、`<>`、`<`、`<=`、`>`、`>=` 符号写法,统一归一化为枚举操作符;`BT` 也支持两个不含空格的边界用空格分隔。
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guandata/guancli",
3
- "version": "1.0.59",
3
+ "version": "1.0.61",
4
4
  "description": "观远 BI 命令行工具 - 通过 API 操作 ETL、数据集、页面、表单等资源,并提供 ChatBI 问数/洞察能力",
5
5
  "bin": {
6
6
  "guancli": "bin/run.js"
@@ -47,9 +47,9 @@ guancli 是 BI 资源的**查询分析入口**,并支持 Form 表单填报 CRU
47
47
  ## 先做判断
48
48
 
49
49
  1. 认证检查和 BI 查询都会联网,密码 profile 或服务端轮换 token 时可能更新本地 token;只在当前任务允许认证刷新时执行。
50
- 2. 当前进程同时提供 `GUANCLI_OIDC_BASE_URL` 和 `GUANCLI_OIDC_ACCESS_TOKEN` 时,外部 OIDC 环境是本次进程的唯一有效目标,会覆盖本地 profile;直接用 `auth status` 验证,不要求先创建、选择或切换本地 profile。CLI 不接收外部 RefreshToken,也不刷新这组上游托管 Token。
51
- 3. 未启用外部 OIDC 时,多 profile 且已知登录 Domain 或 BI/页面 URL,先用 `auth list --domain <domain>` 或 `auth list --url <url>` 找候选;0 个候选时报告无匹配,并让用户明确现有 profile 或授权新建/更新哪个 profile,不能自动登录。多个候选时让用户按 profile 名称明确选择。选定 profile 后,用 `guancli --profile <name> auth status` 验证,并在后续查询中保留同一 `--profile <name>`;只有用户明确要求切换机器级默认环境时才用 `auth use`。
52
- 4. 未指定 profile 线索且未启用外部 OIDC 时,用 `auth status` 确认当前默认环境的认证是否有效;首次配置、PAT、profile 和配置文件细节见 `references/auth-and-config.md`。
50
+ 2. 当前进程提供完整外部 OIDC 认证环境时,它是本次进程的唯一有效目标并覆盖本地 profile:使用 `GUANCLI_OIDC_BASE_URL` + `GUANCLI_OIDC_ACCESS_TOKEN`。直接用 `auth status` 验证,不要求先创建、选择或切换本地 profile。
51
+ 3. 未启用外部认证时,多 profile 且已知登录 Domain 或 BI/页面 URL,先用 `auth list --domain <domain>` 或 `auth list --url <url>` 找候选;0 个候选时报告无匹配,并让用户明确现有 profile 或授权新建/更新哪个 profile,不能自动登录。多个候选时让用户按 profile 名称明确选择。选定 profile 后,用 `guancli --profile <name> auth status` 验证,并在后续查询中保留同一 `--profile <name>`;只有用户明确要求切换机器级默认环境时才用 `auth use`。
52
+ 4. 未指定 profile 线索且未启用外部认证时,用 `auth status` 确认当前默认环境的认证是否有效;首次配置、PAT、profile 和配置文件细节见 `references/auth-and-config.md`。
53
53
  5. 如果 Token 过期,密码登录方式会自动刷新;Token 方式需重新登录。
54
54
  6. 先判断资源类型:ETL 用 `etl`,数据集用 `ds`,页面/仪表板用 `page`,卡片用 `card`,表单填报用 `form`。
55
55
  7. 信息不全时先 `tree` 或 `search`,拿到 ID 后再 `get`;目录名能出现在 `ds tree`,不代表同词一定能命中 `ds search`。三棵 `tree` 都支持 `--max-depth N` / `--keyword 词`(客户环境目录树可达数千节点,全量输出会被截断,默认先 `--max-depth 2` 再按需加深)。
@@ -86,6 +86,7 @@ guancli etl get <resource_id>
86
86
  guancli ds get <resource_id>
87
87
  guancli ds get <resource_id> --brief
88
88
  guancli ds get <resource_id> --assoc
89
+ guancli ds get <resource_id> --validate-downstream
89
90
  guancli page get <resource_id>
90
91
  guancli url page <page_id>
91
92
  guancli url card <cd_id> --page-id <page_id>
@@ -115,6 +116,8 @@ guancli insight card <cd_id> --page-id <page_id>
115
116
  > 优先用 `guands dataset fields <ds_id>`(轻量、秒回);详情确需查看时先加
116
117
  > `--brief` 跳过血缘。命令超时时不要原样重试——换轻量命令或转后台执行。
117
118
 
119
+ 删除数据集前不要依据 `cardCount` 单独判断引用关系。需要核验血缘中的下游 ID 是否仍存在时,使用 `ds get <ds_id> --validate-downstream`;该选项逐个调用资源详情接口,只有结构化业务状态 `1002` 或 HTTP 404 才标记为“不存在”,认证、HTTP 和 JSON 解析错误会直接失败,避免把查询失败误报成幽灵引用。单次最多验证 100 个下游资源,总超时 30 秒;不支持与 `--brief` 同时使用。
120
+
118
121
  详细筛选、输出、动态参数和复杂报表 Pro 行为见 `references/preview-and-output.md`。
119
122
 
120
123
  ## 页面写操作不在 guancli
@@ -153,7 +156,7 @@ guancli 在这条链路上只出只读的那一环:`guancli page search` / `pa
153
156
  - query 的业务列可以是中文,每个中文层级都用 `["字段名"]`:例如 `.data[] | .["组织"]["名称"]`,每一个中文层级都要引用,不能只改顶层。search/get 的 canonical 英文字段与 query 的业务列名要分开理解。文件模式的 `path` 指向行数组,行数组没有 `rowCount`;先按 `resultMode` 分支再消费,示例见 `references/metric-commands.md`。
154
157
  - 必须解析的命令不得用 `2>/dev/null` 隐藏 stderr,也不得用 `2>&1` 将错误文本送入 JSON 解码器。不要用会让末端命令成功掩盖上游失败的管道;允许组合执行时用 `&&` 衔接“输出到文件 → 解析摘要”,不为读取文件另起一轮推理,必须使用管道时先启用 `set -o pipefail`。
155
158
  - 同类语法错误只允许出现一次;第一次失败后先执行对应命令的 `--help` 或读取本 Skill 的参考文档,再按真实契约纠正,不连续尝试相近写法。
156
- - 普通 `--filter`、可重复 `--filter-json`、单个 `--filter-file` 三选一,禁止混用。复杂筛选优先使用 `--filter-json`(可重复)或 `--filter-file` 条件树。参数和口径明确时直接查询;需要检查计划或排查复杂参数时才用 `--dry-run -f json`。dry-run 只读取指标详情做查询维度、筛选字段和类型校验,不执行指标取数,也不支持普通文件或 stderr 输出目标。不支持的 `--dim` 返回 `METRIC_UNSUPPORTED_DIMENSION`。条件组使用 `combineType: AND|OR` 和 `conditions` 数组,叶子使用 `field/operator/value|values`;`IN` 至少一个值,`BT` 恰好两个值。当前指标取数接口不能无损表达多分支 OR,真实执行会在取数前返回 `FILTER_OR_EXECUTION_UNSUPPORTED`,不得拆成多次聚合查询后拼接。失败时按稳定错误码修正,不猜错误文本。
159
+ - 普通 `--filter`、可重复 `--filter-json`、单个 `--filter-file` 三选一,禁止混用。复杂筛选优先使用 `--filter-json`(可重复)或 `--filter-file` 条件树。参数和口径明确时直接查询;需要检查计划或排查复杂参数时才用 `--dry-run -f json`。dry-run 只读取指标详情做查询维度、筛选字段和类型校验,不执行指标取数,也不支持普通文件或 stderr 输出目标;保存卡片高级计算列不在指标详情中,因此这类排序候选在 dry-run 中不会被猜测为有效,真实执行时才读取既有卡片编辑配置校验。不支持的 `--dim`、普通 `--filter` 的字段、`--sort-asc`/`--sort-desc` 的字段都按指标详情中的字段(适用维度 / 时间维度 / 指标字段名)校验,未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;结构化 `--filter-json`/`--filter-file` 在解析阶段按同一份字段集合校验,未命中返回 `FILTER_UNKNOWN_FIELD`。两类错误都不会静默忽略条件或透传未知字段。普通展示别名只对 `--dim` 与排序生效;若指标详情的 `publicDimensionMap` 把唯一公共维度名映射到一个适用维度,则 `--dim`、排序和筛选也可使用该公共维度名,CLI 会保留物理 `fdId` 并把公共维度名作为 alias;同名映射到多个物理字段时拒绝猜测。仅由 CLI 为排序注入、以指标 ID 充当 `fdId` 的“指标名伪字段”不能用于筛选,若指标详情的 `fdInfos` 本身含同名原始字段和真实 `fdId`,仍可正常筛选。`--sort-asc`/`--sort-desc` 额外接受保存卡片中真实存在的高级计算列,以及泛化查询的结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`)。遇到这些错误时先用 `guancli metric get` 读取适用维度再改字段。条件组使用 `combineType: AND|OR` 和 `conditions` 数组,叶子使用 `field/operator/value|values`;`IN` 至少一个值,`BT` 恰好两个值。当前指标取数接口不能无损表达多分支 OR,真实执行会在取数前返回 `FILTER_OR_EXECUTION_UNSUPPORTED`,不得拆成多次聚合查询后拼接。失败时按稳定错误码修正,不猜错误文本。
157
160
  - 搜索并同时查看业务口径、数据集和适用维度等详情时,优先使用 `guancli metric search --fuzzy <keyword> --limit <N> --with-detail --brief -f json`,不要先 search 再逐个 get,也不要为终端阅读额外拼 jq。只查单个指标详情时优先使用 `guancli metric get <metric_id> --brief`;只裁剪指标查询结果列时使用 `metric query --columns`。可复制模板见 `references/metric-commands.md`。
158
161
  - 业务词不能直接命中指标时,候选发现必须遵守单批预算:一次性生成“原词 + 最多 4 个必要同义词/等价表达”,按 trim、空白归一化和大小写不敏感语义去重,保留原词在首位,然后只执行一次 `metric search --fuzzy`。不得把同义词拆成多次查询,不得通过调换顺序、改写等价词或查询子集重复搜索;如果单批无候选,立即结束本轮候选发现并说明已尝试关键词、搜索范围、无结果原因和 `stop_reason=no_candidate_within_budget`。后端最多接受 10 个模糊关键词,但 Agent 候选发现预算默认最多 5 个;不要缓存或跨请求复用“未找到指标”的结论。完整协议见 `references/metric-commands.md`。
159
162
  - 指标结果加工前,先读取成功 query envelope 的实际 `columns` 和行对象 keys,按业务含义选择列;禁止硬编码或猜测指标展示列名(包括高级计算后缀),也不能按列位置取值。使用 `python3 references/examples/metric-query-rows.py <envelope.json> --list-columns` 发现列,再用 `--column "<已确认的实际列名>"` 精确选择;候选缺失或多义时停止并返回实际列集合,不猜近似名称。该参数属于消费 recipe,不是 `guancli metric query` 的参数。
@@ -240,13 +240,13 @@ guancli metric query <metric_id> [flags]
240
240
  | --- | --- | --- |
241
241
  | `--limit int` | `50` | 数据行数限制 |
242
242
  | `--dim strings` | 无 | 维度名称,可多次指定,也支持逗号、中文逗号、顿号分隔;日期子类型写作 `"订单日期 toMonth"` |
243
- | `--filter stringArray` | 无 | 筛选条件,格式:`"列名 操作符 值"`,可多次指定 |
244
- | `--filter-json stringArray` | 无 | 结构化筛选 JSON,可重复;与 --filter/--filter-file 互斥;支持嵌套 AND/OR 条件树 |
243
+ | `--filter stringArray` | 无 | 筛选条件,格式:`"列名 操作符 值"`,可多次指定;列名必须是该指标详情中的字段(适用维度 / 时间维度 / 指标字段名),未命中返回 `METRIC_UNSUPPORTED_DIMENSION`,不会静默忽略 |
244
+ | `--filter-json stringArray` | 无 | 结构化筛选 JSON,可重复;与 --filter/--filter-file 互斥;支持嵌套 AND/OR 条件树;字段未命中该指标字段时在解析阶段返回 `FILTER_UNKNOWN_FIELD` |
245
245
  | `--filter-file string` | 无 | 从 JSON 文件读取一棵结构化条件树;与 `--filter`、`--filter-json` 互斥 |
246
246
  | `--combine-type string` | `AND` | 多条件组合方式:`AND` 或 `OR` |
247
247
  | `--dry-run` | `false` | 只返回规范化查询计划、字段类型和稳定错误码,不执行指标取数;必须同时使用 `-f json`,且不支持普通文件或 stderr 输出目标 |
248
- | `--sort-asc string` | 无 | 按列升序排序;日期子类型使用与 `--dim` 相同的粒度表达式;与 `--sort-desc` 互斥 |
249
- | `--sort-desc string` | 无 | 按列降序排序;日期子类型使用与 `--dim` 相同的粒度表达式;与 `--sort-asc` 互斥 |
248
+ | `--sort-asc string` | 无 | 按列升序排序;排序目标可以是适用维度 / 时间维度、指标名本身、保存卡片中真实存在的高级计算列,或泛化结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`);日期子类型使用与 `--dim` 相同的粒度表达式;未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;与 `--sort-desc` 互斥 |
249
+ | `--sort-desc string` | 无 | 按列降序排序;合法排序目标与 `--sort-asc` 相同(适用维度 / 时间维度、指标名、泛化结果列名);日期子类型使用与 `--dim` 相同的粒度表达式;未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;与 `--sort-asc` 互斥 |
250
250
  | `--columns strings` | 无 | 只显示指定列,逗号分隔,在 CLI 端执行 |
251
251
  | `--precision int` | `6` | 没有有效指标格式时的数值最大小数位数;传 `-1` 保留原始精度 |
252
252
  | `--value-format string` | `formatted` | `formatted` 按指标格式输出;`raw` 保留原始数值 |
@@ -258,6 +258,8 @@ search/get 的 `data` 使用直接由后端字段构造的 canonical 模型:`i
258
258
 
259
259
  query dry-run 的 `dimensions` 保留用户输入的字符串数组,并额外返回 `resolvedDimensions`。后者是 CLI 最终发送给查询接口的维度对象,可用于确认日期子类型是否解析到了预期的 `fdId`、`fdType=SUB_DATE`、`parentFdName` 和 `granularity`。
260
260
 
261
+ 筛选字段通常必须使用指标详情中的原始字段名。例外是指标详情 `publicDimensionMap` 中能唯一映射到一个适用维度的公共维度名:维度、日期粒度、排序和筛选均可使用该名称,CLI 仍发送物理字段 `fdId`,并在维度 alias 中保留公共维度名;同名映射到多个物理字段时会拒绝猜测。指标名仅作为排序伪字段、没有对应真实字段 `fdId` 时不能筛选;若 `fdInfos` 本身存在同名原始字段和真实 `fdId`,该字段仍可筛选。排序目标只在来自指标详情、当前泛化参数,或保存卡片编辑配置中真实带 `advCalc` 的字段时通过;仅与指标名具有相同前缀不能证明字段有效。dry-run 只读取指标详情,因此不会猜测保存卡片高级计算列有效;真实执行会在修改隔离编辑会话前读取既有卡片编辑配置并校验。
262
+
261
263
  ### 日期子类型维度
262
264
 
263
265
  日期维度可在字段名后增加粒度修饰符:
@@ -202,7 +202,11 @@ guancli metric query <metric_id> --profile default --dim 城市 --rank-top 5 --r
202
202
 
203
203
  ### 泛化结果列的发现与选择
204
204
 
205
- `--recent/--xtd/--compare` 的窗口和展示列名不能互相推导。消费前先读实际 `columns` 和行对象 keys,禁止硬编码展示列名或拼接 `_recent_7d` 等后缀;仅按业务意图确认实际列,不按列顺序或近似名称猜测。列缺失或多个候选同时存在时停止,返回实际列集合。
205
+ `--recent/--xtd/--compare` 的窗口和展示列名不能互相推导。**解析结果**前先读实际 `columns` 和行对象 keys,禁止凭猜测硬编码展示列名;仅按业务意图确认实际列,不按列顺序或近似名称猜测。列缺失或多个候选同时存在时停止,返回实际列集合。
206
+
207
+ **排序是例外**:`--sort-asc`/`--sort-desc` 可以直接用推导出的结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`)作为排序目标,CLI 的排序白名单接受它(实测 `_yoy`、`_percentage` 与实际响应列名一致)。这类列只存在于响应中、不在指标详情里,因此不要拿它去 `--filter` 或 `--dim`;两者仍只接受指标详情中的字段,未命中会返回 `METRIC_UNSUPPORTED_DIMENSION`(结构化筛选为 `FILTER_UNKNOWN_FIELD`)。
208
+
209
+ 若指标详情返回 `publicDimensionMap`,并且某个公共维度名只对应一个适用物理字段,则 `--dim`、日期粒度表达式、排序和筛选都可直接使用公共维度名。请求仍使用物理 `fdId`,维度 alias 保留公共维度名;同名公共维度对应多个物理字段时 CLI 会报歧义,不会任选一个字段。
206
210
 
207
211
  复用 [查询结果消费 recipe](metric-commands.md#查询结果消费):成功取得 `-f json` envelope 后,用 `python3 references/examples/metric-query-rows.py query-envelope.json --list-columns` 发现列,再用 `--column "<已确认的实际列名>"` 精确选择。这些是 Python recipe 参数,不是 query 参数。inline/file 分支、失败时保留 stderr 和停止解析沿用同一 recipe。
208
212
 
@@ -34,6 +34,8 @@ guancli etl get <resource_id> # ETL 详情(含节点、SQL、血缘
34
34
  guancli ds get <resource_id> # 数据集详情(含字段结构、血缘)
35
35
  guancli ds get <resource_id> --brief # 数据集轻量输出(省略 Malloy、血缘、公式详情,节省 token)
36
36
  guancli ds get <resource_id> --assoc # 附加显示关联关系摘要(ETL、融合等)
37
+ guancli ds get <resource_id> --validate-downstream # 验证血缘中的下游资源是否仍存在
38
+ guancli ds get <resource_id> --raw --validate-downstream # 在 lineage.downstreamValidation 返回结构化报告
37
39
  guancli page get <resource_id> # 页面详情(含卡片列表、血缘)
38
40
  ```
39
41
 
@@ -41,6 +43,12 @@ guancli page get <resource_id> # 页面详情(含卡片列表、血缘
41
43
 
42
44
  **`--assoc` 模式**(仅 `ds get`):在详情末尾追加数据集关联关系摘要,显示关联的 ETL、数据融合等资源。
43
45
 
46
+ **`--validate-downstream` 模式**(仅 `ds get`):按血缘返回顺序串行调用数据集、ETL、页面或卡片详情接口,确认每个下游 ID 当前是否仍存在。只有业务状态 `1002` 或 HTTP 404 会记为 `not_found`;认证失败、其他 HTTP 错误、JSON 解析失败和响应 ID 不一致都会让命令失败,不会误报为“不存在”。未知资源类型记为 `unsupported`,并令报告的 `complete=false`。原始 `lineage.downstream` 不会被删除或改写;`--raw` 下新增的 `lineage.downstreamValidation` 包含 `complete`、`allValid`、`checked`、`valid`、`notFound`、`unsupported` 和逐项 `items`。默认不启用,因此现有 `ds get` / `ds get --raw` 输出保持不变。
47
+
48
+ 该验证单次最多处理 100 个下游资源,按服务端血缘顺序执行,单请求超时 10 秒、总超时 30 秒。它验证的是“血缘 ID 对应资源详情当前可读取”,不替代服务端删除接口对真实依赖、权限和并发变化的最终校验;不能与跳过血缘的 `--brief` 同时使用。
49
+
50
+ 使用 Personal Access Token 时,血缘、页面和卡片详情使用 `BASE/read`;数据集详情使用 `DATASET/read`;ETL 详情使用 `ETL/read`。PAT 创建时权限列表默认为空,`BASE` 基础读取仍按账号角色校验,但数据集和 ETL 读取权限必须显式选入 PAT scope;缺少权限时验证会返回真实鉴权错误并终止。
51
+
44
52
  ## 4. 获取资源具体 URL
45
53
 
46
54
  ```bash