@qingflow-tech/qingflow-cli 1.1.55 → 1.1.57

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/README.md CHANGED
@@ -7,7 +7,7 @@ Qingflow CLI 是轻流面向开发者和 AI Agent 的命令行工具。它把轻
7
7
  ## 安装
8
8
 
9
9
  ```bash
10
- npm install @qingflow-tech/qingflow-cli@1.1.55
10
+ npm install @qingflow-tech/qingflow-cli@1.1.57
11
11
  ```
12
12
 
13
13
  推荐从官网复制这一条一键安装 Qingflow CLI:
@@ -21,7 +21,7 @@ npx qingflow-cli@latest install
21
21
  ## 运行
22
22
 
23
23
  ```bash
24
- npx -y -p @qingflow-tech/qingflow-cli@1.1.55 qingflow
24
+ npx -y -p @qingflow-tech/qingflow-cli@1.1.57 qingflow
25
25
  ```
26
26
 
27
27
  全局安装后可以直接运行:
@@ -62,7 +62,7 @@ qingflow-skills install --agent codex --scope user
62
62
  如果你通过一次性 `npx -p` 执行 skills 安装,建议加 `--copy`,避免 symlink 指向 npm 临时执行缓存:
63
63
 
64
64
  ```bash
65
- npx -y -p @qingflow-tech/qingflow-cli@1.1.55 qingflow-skills install --agent codex --scope user --copy
65
+ npx -y -p @qingflow-tech/qingflow-cli@1.1.57 qingflow-skills install --agent codex --scope user --copy
66
66
  ```
67
67
 
68
68
  `qingflow-skills install` 默认使用 symlink,且遇到同名 skill 不会覆盖;只有显式传入 `--force` 才会替换。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingflow-tech/qingflow-cli",
3
- "version": "1.1.55",
3
+ "version": "1.1.57",
4
4
  "description": "Human-friendly Qingflow command line interface for auth, record operations, import, tasks, and stable builder flows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "1.1.55"
7
+ version = "1.1.57"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -31,7 +31,7 @@ description: |
31
31
  | [reference/builder/20-build-complete-system.md](./reference/builder/20-build-complete-system.md) | **完整系统/应用包主入口**:多应用、跨应用 relation、门户闭环 |
32
32
  | [reference/builder/30-schema-fields.md](./reference/builder/30-schema-fields.md) | **字段 / schema**:字段类型、直觉别名、数据标题/封面、schema 创建与更新 |
33
33
  | [reference/builder/40-layout.md](./reference/builder/40-layout.md) | **布局维护**:仅用于已有应用的分组、`rows` 矩阵、布局修复;新建应用布局写在 `form` 内 |
34
- | [reference/builder/50-views.md](./reference/builder/50-views.md) | **视图**:表格/卡片/看板/甘特、固定筛选、查询面板、视图 patch |
34
+ | [reference/builder/50-views.md](./reference/builder/50-views.md) | **视图**:先读 schema,一次写一个视图对象;查询面板和按钮约束见该文 |
35
35
  | [reference/builder/60-charts.md](./reference/builder/60-charts.md) | **报表 / QingBI**:指标卡、图表、语义聚合、筛选、排序、更新 |
36
36
  | [reference/builder/70-portal.md](./reference/builder/70-portal.md) | **门户**:标准工作台、业务入口、指标、图表、视图组件、发布 |
37
37
  | [reference/builder/80-buttons-associated-resources.md](./reference/builder/80-buttons-associated-resources.md) | **关联资源 / 非主链路按钮维护**:关联视图/报表、`match_mappings`、上下文传参;按钮配置看视图文档 `action_buttons`;创建自定义按钮前先 `button get --button-text` 查重复用 |
@@ -9,7 +9,7 @@
9
9
 
10
10
  统一语义:
11
11
 
12
- - 固定筛选用 `field_name + operator + value/values`,例如视图 `filters`、报表 `filters`。
12
+ - 报表固定筛选用 `field_name + operator + value/values`。普通视图的 `filters`、`visible_when`、`query_conditions` 不在本文,字段写 `que_id`,见 [50-views.md](./builder/50-views.md)。
13
13
  - 当前记录上下文匹配用 `target_field + operator + source_field/value`,例如关联资源 `match_mappings`、新增数据按钮传参。
14
14
  - 不要直接写 `judgeType`、`judgeValues`、`matchRules`;CLI 会按目标协议自动编译。
15
15
  - 单选 / 多选 / 布尔这类选项值,入参可写选项文本或 option id;视图 / 按钮 / 工作流路径会编译成 Qingflow 需要的 id + details,QingBI 报表路径会编译成 BI 前端需要的文本 `judgeValue`。
@@ -1,52 +1,7 @@
1
- # Builder Views Workflow (Legacy Redirect)
1
+ # Builder Views Workflow
2
2
 
3
- This file is kept only for old cross-links. Use the current canonical document instead:
4
-
5
- - [builder/50-views.md](./builder/50-views.md)
6
-
7
- Current main path:
3
+ 旧文已并入 [builder/50-views.md](./builder/50-views.md)。字段形状读 `builder views schema --schema-kind complete`。一次只提交一个视图对象:
8
4
 
9
5
  ```bash
10
- qingflow builder views apply --app-key APP_KEY --view-file /abs/path/view.json
6
+ qingflow builder views apply --app-key APP_KEY --schema-version v1alpha1 --view-file /abs/path/view.json
11
7
  ```
12
-
13
- Use `--app-key APP_KEY --view-file /abs/path/view.json`. The file contains one direct view object.
14
-
15
- Minimum current shape:
16
-
17
- ```json
18
- {
19
- "name": "订单跟进视图",
20
- "type": "table",
21
- "columns": ["订单编号", "客户名称", "状态", "负责人"],
22
- "filters": [
23
- {"field_name": "状态", "operator": "neq", "value": "已关闭"}
24
- ],
25
- "query_conditions": {
26
- "enabled": true,
27
- "rows": [["订单编号", "客户名称"], ["状态", "负责人"]]
28
- },
29
- "action_buttons": [
30
- {
31
- "text": "行内新建跟进",
32
- "action": "add_data",
33
- "target_app_key": "TARGET_APP_KEY",
34
- "placement": "list",
35
- "field_mappings": [
36
- {"source_field": "数据ID", "target_field": "关联订单"}
37
- ]
38
- },
39
- {
40
- "text": "详情新建跟进",
41
- "action": "add_data",
42
- "target_app_key": "TARGET_APP_KEY",
43
- "placement": "detail",
44
- "field_mappings": [
45
- {"source_field": "数据ID", "target_field": "关联订单"}
46
- ]
47
- }
48
- ]
49
- }
50
- ```
51
-
52
- Each `builder views apply` call handles one operation on one view: pass one `--view-file`, one-item `patch_views`, or one-item `remove_views`; do not combine these operation modes.
@@ -55,7 +55,7 @@
55
55
  | --- | --- |
56
56
  | `builder app get` | 应用地图;轻量返回字段摘要、视图、图表、自定义按钮、关联资源池 |
57
57
  | `builder app-form schema/get/validate/apply` | 当前表单/字段/布局/应用设置入口;固定 AppForm schema 版本,完整声明写入并保留现有 IDs;旧 `builder schema apply` / `builder layout apply` 仅为已移除的内部兼容适配器 |
58
- | `builder views apply` | 业务视图;固定筛选写 `filters`,前端查询栏写 `query_conditions` |
58
+ | `builder views apply` | 业务视图。字段形状读 `views schema`;一次一个视图对象。数据权限默认 `custom + all`,自定义范围才写 `filters`;查询栏写 `query_conditions` 的 queId |
59
59
  | `builder button apply` | 自定义按钮默认路径;新增数据按钮用 `field_mappings/default_values`,绑定位置用 `header/detail/list` |
60
60
  | `builder associated-resource apply` | 应用级关联视图/报表池 + 视图展示配置;报表来源用 `report_source`,不让智能体填写后端 raw source |
61
61
  | `builder charts apply` | QingBI 报表配置;报表变更 immediate-live,不等同于应用发布 |
@@ -1,541 +1,56 @@
1
1
  # Builder Views
2
2
 
3
- Read this when the task is about table/card/board/gantt/hierarchy/calendar views, fixed filters, query panels, view sorting, view data permissions, associated report/view display on a view, or repairing existing views.
3
+ 视图字段形状以 `builder views schema` 为准。本文只保留调用顺序和 schema 没有替你做的交付约束。不要再找 `view_create`、`--views-file` 或批量 `views[]`。
4
4
 
5
- ## Scope
6
-
7
- Responsible for: `builder views apply --app-key APP_KEY --view-file PATH` (the **only** creation entry), one view declaration, `columns`, `filters`, `query_conditions`, `action_buttons`, and view readback.
8
-
9
- Not responsible for: creating associated report resources or maintaining custom button bodies outside the view design. New business views must include `query_conditions`; ordinary business shortcut buttons are required and are declared only through `action_buttons` on the target view.
10
-
11
- ## Main chain
5
+ ## 调用顺序
12
6
 
13
7
  ```text
14
- app get -> app get fields/views -> views schema -> prepare one view -> views validate -> views apply -> app get/views readback
8
+ app get fields/views -> views schema --schema-kind complete -> 写一个视图对象 -> views validate -> views apply -> 按 verification 回读
15
9
  ```
16
10
 
17
- ## 版本与 schema(views v1alpha1)
18
-
19
- 视图声明是**版本化契约**(`apiVersion: builder.qingflow.com/v1alpha1`)。`builder views apply` 是视图创建的**唯一入口**(旧命令式 `view_create` 已删除;不要再寻找或使用任何“直接创建视图”的命令/工具)。
20
-
21
- - **两级 schema**:**summary**(最简版:类型/名称/数据展示内容 + `data_permission` 数据权限形状)与 **complete**(完整版:visibility 可见性授权、`filters`、`sort`、`query_conditions`、`action_buttons`/`buttons`、`associated_resources`、`card`/`gantt`/`hierarchy`/`calendar` 类型专属配置、`display`/`record`/`share`)。字段级定义逐字段带 `x-backend` 后端映射。
22
- - **读 schema**:`qingflow --json builder views schema` 默认返回 `v1alpha1/summary.json`;需要完整可写配置时显式传 `--schema-kind complete`。MCP 对应 `app_views_schema`。
23
- - **Schema-first 写入**:先用 `builder views schema --schema-version VERSION --schema-kind complete` 读取完整 schema;将相同版本显式传给 `validate --schema-version VERSION` 和 `apply --schema-version VERSION`。`validate` 也可从声明信封读取 `schema_version`,但推荐显式传版本;apply 的版本校验必须用 `--schema-version`。`validate` 接受一个直接视图声明对象,不接受 `upsert_view` 包装或批量 envelope。
24
- - **说明字段**:视图 Schema 使用语义化的 `*Description` 自定义 key(如 `dataPermissionDescription`)承载说明,加载和引用展开时原样保留;读取说明的工具应识别这些 key。标准校验器忽略这些自定义字段,仍按 `type`、`enum`、`required` 等关键字校验;`default` 是标准注解,不会自动填值。`*Description` 不是提交视图声明时的业务字段。
25
- - **离线校验**:`qingflow --json builder views validate --file PATH`(`-` 支持 stdin),不访问后端;返回 `ok`/`issues[]`(带 JSON pointer path)。
26
- - **读 canonical 声明**:`qingflow --json builder views get --app-key APP --schema-version VERSION --schema-kind summary`,返回指定版本的 summary 声明数组(字段名反解);完整可写配置用 `--schema-kind complete` 并检查 `config_read_errors[].gaps`。
27
- - **完整声明的提取边界**:`views get --schema-kind complete` 优先读取 `buttonConfigVO` 中的完整按钮绑定。公式过滤、无法解析的过滤规则或按钮 ID 会使该视图返回 `VIEW_NOT_EXTRACTABLE`(见 `details.config_read_errors[].gaps`),不会生成删减后的可写声明。修改这类视图的其他属性应使用局部 patch。更新现有视图时,已配置的系统字段原样保留,不补默认值、不重算序号;读接口生成的未配置占位对象不会写回,不会因此新增系统字段配置。
28
- - **版本协商**:apply 显式传 `--schema-version v1alpha1` 时启用版本化校验:非法声明返回 `INVALID_SPEC` 且**不写**;响应信封回显 `schemaVersion`。apply 不传时行为与旧版一致(别名宽容,零破坏)。
29
- - **公开视图类型**:summary 与 complete 均支持 `table`、`card`、`board`、`gantt`、`hierarchy`、`calendar`。层级视图须提供 `hierarchy: {title_que_id, children_que_id}`;日历视图须提供 `calendar: {title_que_id, date_que_id}`,可选 `color_que_id`。日历 `date_que_id` 可引用表单日期字段,也可用系统字段 `2`(申请时间)或 `3`(更新时间)。
30
- - **complete 档配置速览**:`data_permission` 默认 `{type: custom, scope: all}`。`type=config` 跟随应用成员授权,忽略 `scope` 与 `filters`;`type=custom` 才使用 `scope`,其中 `scope=custom` 的规则写 `filters`。`sort`(`[{que_id, ascending}]`,空数组=恢复默认排序);`hierarchy`(可选 `root_filter`);`card`/`gantt`/`calendar`/`display`/`record`/`share` 配置组。
31
-
32
- ## Update existing views
33
-
34
- - Prefer `--patch-views-file` for small changes to an existing view.
35
- - Use raw `view_key` from `app_get.views[].view_key`; do not use record-data `custom:<view_key>` prefixes.
36
- - Do not send a partial `--view-file` object to update a complex existing view; use `--patch-views-file` with `set`.
37
- - Verify filters, query conditions, and associated resources separately before reporting success.
38
-
39
- ## Detailed contract notes
40
-
41
- 稳定命令:**`qingflow builder views apply --app-key APP_KEY --view-file PATH`**(别名 **`qingflow build views apply`**)。`--view-file` 是一个直接的 JSON 对象,只声明一个新建或完整更新的视图。
42
-
43
- > **权限**:视图**新建**走后端 `createViewgraphConfig`,需要同时满足 **视图管理 / ViewManagementAuth**(`beingViewManageStatus`)和 **数据管理 / DataManageAuth**;视图**更新/删除**只走 **ViewManagementAuth**。未开启高级应用权限时 `beingViewManageStatus` 等价回落到 **DataManageAuth**。失败时常见 **40002 / 40161 / 编辑锁**,参见主技能与 **ADMIN** 速查。
44
-
45
- > **默认系统视图**:`全部数据`、`我的数据`、`我发起的`、`待办`、`已办`、`抄送` 等由轻流自带,**不要新建同名业务视图**。新建视图必须用业务名,例如 `项目台账视图`、`客户跟进视图`、`逾期任务看板`。如果确实要调整默认系统视图,只能从 `app get views` 取已存在的 raw **`view_key`** 后通过 `--patch-views-file` 更新。
46
-
47
- > **契约**(权威键名、枚举、`execution_notes`、示例):
48
- > `qingflow --json builder contract --tool-name app_views_apply`
49
- > (`--tool-name` 为契约索引,用于拉取 **`allowed_keys` / 别名 / 示例**。)
50
- > 契约示例若带 `"profile"` 或 `"app_key"`,不要复制到 `--view-file`;CLI 分别用根级 `qingflow --profile …` 和 `--app-key` 指定。
51
-
52
- ---
53
-
54
- ## 1. 推荐操作顺序(读 → 写 → 校验)
55
-
56
- | 步骤 | 动作 | CLI |
57
- |------|------|-----|
58
- | ① 读应用地图 | 先看 compact views/charts/buttons/associated resources | `qingflow --json builder app get --app-key <APP_KEY>` |
59
- | ② 读字段/视图 | 确认 **`columns`** / `query_conditions.rows` 可用字段、核对 **`view_key`** | `qingflow --json builder app get --app-key <APP_KEY> fields` / `qingflow --json builder app get --app-key <APP_KEY> views` |
60
- | ③ 读取 schema | 固定版本;按需求读取 summary 或 complete | `qingflow --json builder views schema --schema-version v1alpha1 --schema-kind complete` |
61
- | ④ 准备并校验声明 | 新建或完整更新写一个视图对象;先离线校验;局部修改写单项 patch | `qingflow --json builder views validate --file PATH --schema-version v1alpha1` |
62
- | ⑤ 应用视图操作 | 将同一版本传给 apply;一次只提交一个视图操作 | `qingflow builder views apply --app-key … --view-file PATH --schema-version v1alpha1` |
63
- | ⑥ 配置查询面板和快捷按钮 | 新建业务视图必须写 `query_conditions` 和 `action_buttons`,按钮同时覆盖 `list` 和 `detail` 位置 | `builder views apply` |
64
- | ⑦ 需要上线时 | 发布侧校验 | `qingflow builder publish verify --app-key …` |
65
-
66
- **说明**:`views apply` 的 **`--publish`** 对应契约里的 **`publish`**;新建业务视图必须包含 `query_conditions` 和 `action_buttons` 并使用 `publish=true`,因为底层按钮写入会自动发布。只有删除、纯维护补丁、或用户明确要求的只读/归档视图,才允许不带按钮;只读/归档视图仍应配置 `query_conditions`。
67
-
68
- ---
69
-
70
- ## 2. CLI 形态
71
-
72
11
  ```bash
73
- qingflow builder views apply \
74
- --app-key APP_KEY \
75
- --view-file PATH \
76
- [--publish | --no-publish]
77
- ```
78
-
79
- - **`--view-file`**:单个 JSON 对象,用于新建或完整更新一个视图;命令每次只接受一个。
80
- - **`--patch-views-file`**:JSON 数组,用于已有视图的局部更新;每次最多传一项,包含 `view_key` 或唯一 `name`,以及 `set`/`unset`。
81
- - **`--remove-views-file`**:JSON 数组,用于删除一个视图;每次最多传一个 raw `view_key` 或唯一名称。
82
- - 每次调用只能选择一种写入模式:`--view-file`、`--patch-views-file`、`--remove-views-file` 三者不能混用;每次只处理一个应用中的一个视图操作。
83
- - **不支持批量创建**:不要传 `upsert_views`、`views`、`apps` 等批量声明,也不要在 patch/remove 文件中放多项;多个视图须逐个调用 `builder views apply`,每次单独读回确认。
84
- - **`--app-key`**:每次视图写入必须指定一个应用;CLI 不提供跨应用或同次多视图写入。
85
- - 输出默认直接给 stdout,前端可直接读取;需要留档时用 `qingflow builder views apply … | tee tmp/builder_views_apply.json`。
86
-
87
- ---
88
-
89
- ## 2.1 参考示例文件(与门户 / 报表同风格)
90
-
91
- | 文件 | 用途 |
92
- |------|------|
93
- | [views_upsert_table_minimal.example.json](../examples/views/views_upsert_table_minimal.example.json) | 单视图表格示例,可直接作为 `--view-file` |
94
- | [views_apply_v1alpha1.example.json](../examples/views/views_apply_v1alpha1.example.json) | 版本化单视图字段示例;作为 `--view-file` 使用时加 `--schema-version v1alpha1` |
95
-
96
- 复制到具体应用前替换 **`columns`**;应用由命令的 **`--app-key`** 指定。**`name`** 重名时会更新已有同名视图而非新建(见 **§4**)。
97
-
98
- ---
99
-
100
- ## 3. 请求体形状(与契约对齐)
101
-
102
- CLI 将参数与文件内容拼装为服务层载荷,**顶层键**如下:
103
-
104
- | 键 | 说明 |
105
- |----|------|
106
- | **`app_key`** | 命令的必填参数,定位单个应用 |
107
- | **`upsert_view`** | 来自 `--view-file` 的一个对象;创建用 `name`,完整更新优先带 raw `view_key` |
108
- | **`upsert_view.query_conditions`** | 新建业务视图必填;配置前端查询面板字段布局 |
109
- | **`patch_views`** | 来自 `--patch-views-file` 的数组;每次最多一项,使用 `view_key`/`name` 和 `set`/`unset` |
110
- | **`remove_views`** | 来自 `--remove-views-file` 的数组;每次最多一项,使用 raw `view_key` 或唯一名称 |
111
-
112
- **别名**(契约 `aliases` 节选):**`fields` / `column_names` → `columns`**;**`view_key` / `viewKey`**;**`tableView`→`table`**、**`kanban`→`board`** 等;**`filter_rules`→`filters`**;**`startField`→`start_field`** 等。
113
-
114
- ---
115
-
116
- ## 4. 创建 vs 更新(`view_key` 与 `name`)
117
-
118
- 服务逻辑概要:
119
-
120
- - **`remove_views`**:优先传 raw **`view_key`**;也可传唯一视图显示名 `name`,显示名重名则 **`AMBIGUOUS_VIEW`**。
121
- - **`upsert_view`**:
122
- - 若提供 **`view_key`**:对该视图做 **更新**(含类型变更等,仍受后端约束)。
123
- - 未提供 **`view_key`**:若 **`name` 唯一** 匹配已有视图 → **更新**;否则 → **创建**。
124
- - **`patch_views`**:对已有视图做局部参数替换;必须有 `view_key` 或唯一 `name`,并写 `set` / `unset`。
125
-
126
- 响应中的 **`verification.view.status`** 会出现 **`created` / `updated`** 等;**`view_result`** 给出本次唯一视图操作结果,**`views_diff`** 仅保留兼容摘要。
127
-
128
- **`partial_success`**:单个视图写入已执行,但读回或附属配置校验未完全通过;务必读 **`view_result`**、**`warnings`** 与 **`verification`**。
129
-
130
- **系统默认名禁止新建**:未提供 `view_key` 的 `upsert` 不要使用 `全部数据`、`我的数据`、`我发起的`、`待办`、`已办`、`抄送` 这类默认系统视图名。它们不是业务视图模板,而是平台默认对象;新业务视图用具体业务名。
131
-
132
- ---
133
-
134
- ## 5. `type` 与各类型必填
135
-
136
- 契约 **`view.type`**:**`table`** | **`card`** | **`board`** | **`gantt`** | **`hierarchy`** | **`calendar`**。
137
-
138
- | `type` | 列/字段要点 | 类型专属键 |
139
- |--------|----------------|------------|
140
- | **`table`** | **`columns`**(业务字段 **queId**,或已有系统字段 **queId**) | — |
141
- | **`card`** | 同 table | — |
142
- | **`board`**(看板) | 列;且须 **`group_by`**(分组字段名) | **`group_by`** |
143
- | **`gantt`** | 列;须 **`start_field`**、**`end_field`**(通常为日期类字段名) | 可选 **`title_field`** |
144
- | **`hierarchy`** | 层级标题字段和父子关系字段 | `hierarchy.title_que_id`、`hierarchy.children_que_id`;可选 `hierarchy.root_filter` |
145
- | **`calendar`** | 标题字段和日期字段 | `calendar.title_que_id`、`calendar.date_que_id`;可选 `calendar.color_que_id` |
146
-
147
- 实现侧校验:对 **table/card**,`columns` 至少包含一列;已知系统字段在读取已有视图时原样透传,不要求出现在表单业务字段索引中。未知系统字段仍会报告覆盖缺口。
148
-
149
- ---
150
-
151
- ## 6. `filters` / `query_conditions` / `visibility` / `action_buttons`
152
-
153
- ### 6.0 条件/匹配一眼决策表
154
-
155
- 先按目标场景选入口。所有入口都接受智能体友好的字段名/操作符语义,但底层编译路径不同。
156
-
157
- | 目标场景 | 写到哪里 | 推荐写法 | 不要这样做 |
158
- | --- | --- | --- | --- |
159
- | 视图自定义数据范围 | `data_permission` + `filters` | `{"type":"custom","scope":"custom"}`,规则写 `filters` | 不要只写 `filters`;`type=config` 或 `scope` 为 all/oneself/dept/subordinate 时 `filters` 不生效 |
160
- | 前端查询面板显示哪些字段 | `query_conditions.rows` | `[["客户名称", "负责人"], ["创建时间"]]` | 不要写筛选值;不要把它当 OR 条件 |
161
- | 按钮显示条件 | `action_buttons[].visible_when` | `{"que_id":101,"operator":"eq","value":"已完工"}` | 不要手写后端判断符 |
162
- | 当前记录创建下游记录时传值 | `field_mappings` | `{"source_field":"数据ID","target_field":"关联工单"}` | 不要放在 `header` 按钮;`header` 没有当前记录上下文 |
163
- | 关联视图/关联报表按当前记录过滤 | `associated-resource apply.match_mappings` | `{"target_field":"关联客户","operator":"eq","source_field":"数据ID"}` | 不要用 `filters` 或 `query_conditions` 代替 |
164
- | 关联视图/关联报表静态筛选 | `match_mappings` | `{"target_field":"状态","operator":"eq","value":"有效"}` | 不要混用 raw `match_rules` |
165
-
166
- 短规则:**数据权限默认 `custom + all`;自定义范围才写 `filters`(且 `type=custom`、`scope=custom`);查询栏用 `query_conditions`;当前记录匹配用 `match_mappings`;当前记录传参用 `field_mappings`。**
167
-
168
- ### 6.1 `filters`
169
-
170
- - 项形状:**`que_id`**、**`operator`**、**`values`**(或契约允许的 **`value`** 别名)。
171
- - **`operator`**:统一公共语义,推荐 `eq` / `neq` / `in` / `contains` / `gte` / `lte` / `is_empty` / `not_empty`;兼容 `equal` / `equals` / `=` / `!=` / `any_of` / `one_of` / `empty` 等别名(以契约为准)。
172
- - **`in` 等多值**:传 **列表**;**`value`** 为列表时可作别名。
173
- - **`value` 按字段类型写**:文本/数字/日期直接写业务值;单选/多选/是否优先写选项文本,也支持 option id;成员/部门/关联记录固定筛选优先写唯一 id 或 `{id,value}`。完整规则见 **[reference/match-rules.md](./reference/match-rules.md)**。
174
- - **语义**:`filters` 是 `data_permission.type=custom` 且 `scope=custom` 时的数据范围,不是叠在 `config` 或预设范围上的第二层筛选。不要把前端查询栏字段写进 `filters`。
175
- - **写入 / 读回语义**:智能体始终写 `que_id + operator + value/values`;CLI 内部自动转换目标协议,读回也会还原成 `operator/value` 语义。不要手写或解释后端判断符。
176
-
177
- 示例:
178
-
179
- ```json
180
- {"que_id": 101, "operator": "eq", "value": "进行中"}
181
- ```
182
-
183
- ### 6.2 `query_conditions`
184
-
185
- `query_conditions` 是前端“查询条件/查询栏”配置,和 `filters` 是两套语义。新建业务视图必须配置 `query_conditions`,不要交付没有查询面板的业务视图。
186
-
187
- - `filters`:仅 `type=custom` 且 `scope=custom` 时作为视图数据范围。默认权限是 `custom + all`,此时不要写 `filters`。
188
- - `query_conditions`:只配置前端查询面板可输入哪些字段;用户输入查询值后才生效。
189
- - `rows` 是字段布局矩阵,不表示 OR 条件。
190
- - `rows` 只放前端查询面板支持的字段:文本、长文本、数字、金额、日期/时间、单选/多选、成员、部门、手机号、邮箱、布尔。
191
- - 不要把 relation、attachment、subtable/subfield、address、Q-Linker 或 code-block 字段放进 `query_conditions`。
192
- - 需要自定义数据范围时,写 `data_permission.type=custom`、`scope=custom` 和 `filters`;需要关联报表/关联视图按当前记录匹配时用 `builder associated-resource apply` 的 `match_mappings`。
193
- - 每个新建业务视图至少配置 2-4 个查询字段;优先选择标题/编号、状态、负责人、日期等高频检索字段。
194
-
195
- 示例:
196
-
197
- ```json
198
- {
199
- "name": "客户查询视图",
200
- "type": "table",
201
- "columns": [101, 102, 103, 104],
202
- "filters": [
203
- {"que_id": 103, "operator": "eq", "value": "有效"}
204
- ],
205
- "query_conditions": {
206
- "enabled": true,
207
- "exact": false,
208
- "hide_before_query": false,
209
- "rows": [["客户名称", "负责人"], ["创建时间"]]
210
- },
211
- "action_buttons": [
212
- {
213
- "text": "行内创建跟进",
214
- "action": "add_data",
215
- "target_app_key": "FOLLOWUP_APP_KEY",
216
- "field_mappings": [
217
- {"source_field": "数据ID", "target_field": "关联客户"}
218
- ],
219
- "default_values": {"跟进状态": "待跟进"},
220
- "placement": "list"
221
- },
222
- {
223
- "text": "详情创建跟进",
224
- "action": "add_data",
225
- "target_app_key": "FOLLOWUP_APP_KEY",
226
- "field_mappings": [
227
- {"source_field": "数据ID", "target_field": "关联客户"}
228
- ],
229
- "default_values": {"跟进状态": "待跟进"},
230
- "placement": "detail"
231
- }
232
- ]
233
- }
234
- ```
235
-
236
- 读回验证时,不要只看视图是否存在;要看 `verification.view_query_conditions_verified=true`。若返回 query condition mismatch,只能说视图已创建/更新,但查询条件未完全验证。
237
-
238
- ### 6.3 `visibility`
239
-
240
- 与包/应用/视图等 **授权形态一致**(契约 **`visibility.mode`**:`workspace` | `everyone` | `specific`;**`external_mode`**:`not` | `workspace` | `specific`;**`selectors` / `external_selectors`** 键集合见契约)。
241
-
242
- - **更新已存在视图**:省略 **`visibility`** 可 **保留**当前后端权限。
243
- - **名称类 selector**:须 **唯一解析**,否则失败(不猜测)。
244
-
245
- ### 6.4 `action_buttons`(主路径)
246
-
247
- 设计业务视图时,必须同时声明这个视图上的快捷按钮。常规按钮写在视图对象的 `action_buttons` 里,不要先建视图再单独找按钮工具补。新建核心业务视图必须至少包含一个 `placement: "list"` 按钮和一个 `placement: "detail"` 按钮;`header` 按钮可按需增加,但不能替代列表和详情按钮。
248
-
249
- 创建视图时:
250
-
251
- ```json
252
- {
253
- "name": "生产工单执行视图",
254
- "type": "table",
255
- "columns": ["工单编号", "产品", "状态", "负责人"],
256
- "filters": [
257
- {"que_id": 101, "operator": "in", "values": ["生产中", "已完工"]}
258
- ],
259
- "query_conditions": {
260
- "enabled": true,
261
- "exact": false,
262
- "hide_before_query": false,
263
- "rows": [["工单编号", "状态"], ["负责人"]]
264
- },
265
- "action_buttons": [
266
- {
267
- "text": "行内创建质检单",
268
- "action": "add_data",
269
- "target_app_key": "QUALITY_APP",
270
- "field_mappings": [
271
- {"source_field": "数据ID", "target_field": "关联工单"}
272
- ],
273
- "default_values": {"处理状态": "待处理"},
274
- "placement": "list",
275
- "visible_when": [
276
- {"que_id": 101, "operator": "eq", "value": "已完工"}
277
- ]
278
- },
279
- {
280
- "text": "详情创建返工单",
281
- "action": "add_data",
282
- "target_app_key": "REWORK_APP",
283
- "field_mappings": [
284
- {"source_field": "数据ID", "target_field": "关联工单"}
285
- ],
286
- "default_values": {"返工状态": "待处理"},
287
- "placement": "detail"
288
- }
289
- ]
290
- }
291
- ```
292
-
293
- 局部补按钮时:
294
-
295
- ```json
296
- {
297
- "view_key": "RAW_VIEW_KEY",
298
- "set": {
299
- "action_buttons": [
300
- {
301
- "text": "行内创建验收单",
302
- "action": "add_data",
303
- "target_app_key": "ARRIVAL_APP",
304
- "field_mappings": [
305
- {"source_field": "数据ID", "target_field": "关联工单"}
306
- ],
307
- "default_values": {"状态": "待验收"},
308
- "placement": "list"
309
- },
310
- {
311
- "text": "详情创建验收单",
312
- "action": "add_data",
313
- "target_app_key": "ARRIVAL_APP",
314
- "field_mappings": [
315
- {"source_field": "数据ID", "target_field": "关联工单"}
316
- ],
317
- "default_values": {"状态": "待验收"},
318
- "placement": "detail"
319
- }
320
- ],
321
- "action_buttons_mode": "merge"
322
- }
323
- }
324
- ```
325
-
326
- 规则:
327
-
328
- - `action_buttons_mode` 默认 `merge`:新增/更新声明按钮并绑定到该视图,不清空已有按钮。
329
- - `replace`:替换该视图上的自定义按钮绑定;`action_buttons: []` + `action_buttons_mode: "replace"` 可清空视图按钮绑定,但不删除按钮本体。
330
- - 新建核心业务视图时 `query_conditions` 和 `action_buttons` 都不能为空,并且按钮必须同时配置 `placement: "list"` 和 `placement: "detail"`。不要交付缺少查询面板或缺少列表/详情按钮的核心操作视图。
331
- - `publish=false` + `action_buttons` 会被阻断为 `VIEW_ACTION_BUTTONS_REQUIRE_PUBLISH`。
332
- - 视图内按钮写智能体语义:`action: "add_data"` 或 `action: "link"`。不要手写底层触发名。
333
- - 响应里同时看 `verification.views_verified`、`verification.action_buttons_verified`、`verification.view_button_bindings_verified`。
334
- - 按钮失败但视图成功时是 `partial_success`;先按 `suggested_next_call` 用 `patch_views` 重试失败视图。 如果回读里目标视图已有 `CUSTOM` 按钮、文本/位置/触发类型正确,不要重建视图或重复创建按钮。
335
-
336
- `default_values` 是写入**目标应用新增表单**的静态默认值,必须按目标应用 schema 写:
337
-
338
- - 写按钮前先确认 **`target_app_key` 对应应用**的字段与选项;优先用 `builder app get --app-key TARGET_APP fields` 看字段名/选项,必要时用 `record schema insert --app-key TARGET_APP` 看 insert-ready 写入格式。
339
- - 单选/多选字段的默认值必须来自目标字段 `options` 的**原始文本或 option id**;不要用业务近义词。例如 schema 选项是 `每月`、`中`,就不要写 `月检`、`普通`。
340
- - 成员/部门/关联字段默认值按 record insert 的写法处理;不确定候选或目标记录时,先只写 `field_mappings`,不要编造 `default_values`。
341
- - `field_mappings[].target_field` 和 `default_values` 的 key 都是**目标应用字段名**,不是当前视图字段名。
342
- - CLI 会在按钮写入前校验默认值;非法值会返回 `CUSTOM_BUTTON_DEFAULT_VALUE_UNSUPPORTED`。这时视图可能已经创建成功,只需要用 `patch_views` + raw `view_key` 修正 `action_buttons.default_values`,不要重建视图或应用。
343
-
344
- 正确示例:
345
-
346
- ```json
347
- "default_values": {
348
- "巡检周期": "每月",
349
- "优先级": "中",
350
- "隐患等级": "中"
351
- }
352
- ```
353
-
354
- 按钮一眼决策表:先按**用户真实意图**选,不要先从按钮枚举反推业务。
355
-
356
- | 用户真实意图 | 视图内 `action` | 推荐位置 | 必需配置 | 禁止误用 |
357
- | --- | --- | --- | --- | --- |
358
- | 从当前记录生成下游/关联记录,例如工单生成质检、订单生成到货、客户生成跟进 | `add_data` | `detail` 和 `list` 都要配置 | `target_app_key` + `field_mappings`,通常 `source_field: "数据ID"` 指向目标应用的关联/引用字段;`default_values` 必须按目标应用 schema/options 写 | 目标应用或关联字段不清楚时不要猜;不要放在 `header` 后又引用当前记录字段;不要编造选项近义词 |
359
- | 创建不依赖当前行的独立记录或全局入口 | `add_data` | `header` | `target_app_key`;不要写当前记录 `source_field` | 不要假装有当前记录上下文 |
360
- | 打开 SOP、外部系统、帮助文档、固定页面 | `link` | `header` 或 `detail` | `url` | 不要用它代替新增数据、审批、状态流转或数据写回 |
361
- | 审批、通过、驳回、状态流转、关闭任务 | 默认不配普通按钮 | 先判断工作流/任务动作/已有自动化 | 用户明确要求普通按钮且能落到 `add_data` / `link` 时才配置 | 不要用 `link`、空按钮或伪 URL 假装完成 |
362
-
363
- 核心判断:**要把当前记录的数据带到另一个应用,就用 `add_data`;只打开页面就用 `link`;审批/状态流转不是普通按钮。**
364
-
365
- 按钮位置选择:
366
-
367
- | `placement` | 前端位置 | 适合场景 | 注意事项 |
368
- | --- | --- | --- | --- |
369
- | `header` | 视图顶部 | 全局入口,不依赖当前行:打开说明、创建独立记录、批量入口 | 不能依赖当前记录的 `source_field` |
370
- | `list` | 列表/行内 | 对当前行记录操作:从工单创建质检、从客户创建跟进 | 必须确认当前记录上下文可用于 `field_mappings` |
371
- | `detail` | 记录详情页 | 当前记录上下文操作:创建子记录、查看外部详情、补充材料 | 最稳妥的上下文按钮位置 |
372
-
373
- 不同视图类型:
374
-
375
- - `table`:必须配置 `list` 和 `detail` 快捷按钮,是最适合放业务按钮的视图。
376
- - `board`:必须配置状态相关的 `list` 和 `detail` 快捷按钮,并配 `visible_when`,例如只在“待验收”显示“创建验收单”。
377
- - `card`:必须配置 `detail`,并在卡片行操作明确时配置 `list`;核心操作视图不要只给 `header`。
378
- - `gantt`:不适合作为唯一核心操作视图;需要快捷按钮时同时提供配套 table/board 视图,在该操作视图中配置 `list` 和 `detail`。
379
-
380
- ### 6.4.1 绑定已有自定义按钮(`buttons`,查重优先)
381
-
382
- 视图声明里的 `buttons[]` 只做绑定(引用应用级自定义按钮的 `button_id`),不会创建按钮本体。绑定前必须查重,不要重复创建同名按钮:
383
-
384
- 1. **查询**:`qingflow --json builder button get --app-key APP --button-text 按钮文案`(MCP `app_get_buttons` 传 `button_text`),按文案精确匹配。
385
- 2. **有则复用**:唯一命中 → 取返回的 `button_id` 直接写进 `buttons[]`;同名多个 → 用 `button_id` 精确指定(避免歧义)。
386
- 3. **没有再创建**:`builder button apply` 创建(其自身也按文案去重),拿到 `button_id` 后回到视图声明绑定。
387
-
388
- 按钮本体维护(样式/跨视图复用/删除本体)见 [80-buttons-associated-resources.md](./80-buttons-associated-resources.md)。
389
-
390
- ### 6.5 关联视图/报表
391
-
392
- 新版默认不要通过 `app_views_apply.associated_resources` 配置关联资源。应用级关联资源池和视图展示开关统一走 **`app_associated_resources_apply`** / CLI **`builder associated-resource apply`**。
393
-
394
- - `builder views apply` **新建视图时默认开启详情页关联查看**:等价于 `asosChartVisible=true`、`limit_type=all`,会展示当前应用级关联资源池里的全部关联视图/报表。
395
- - **更新已有视图**:未显式传 `associated_resources` 时保留原关联查看状态;需要关闭或改成指定资源时,用 **`builder associated-resource apply --view-configs-file`**,或维护旧配置时显式 patch `associated_resources`。
396
- - 已有资源的最终口径是 `app_get.associated_resources[].associated_item_id`;它不是 `chart_id`、`chart_key` 或 `view_key`。
397
- - 新版 CLI 在关联报表时可先传 `chart_id` / `chart_key`,内部会解析为轻流后端需要的 id;创建前先检查是否已有相同 `target_app_key + view_key/chart_key`,已存在时用 `patch_resources`;`client_key` 只在同一次 apply 中可被 `associated_item_refs` 引用,不会持久化。
398
- - 数据集 BI 报表只能关联已有报表,使用 `report_source: "dataset"`;应用源报表可先用 `builder charts apply` 创建/更新。
399
- - 关联筛选优先用 `match_mappings`;字段类型、`operator`、`value/values` 和跨应用当前记录匹配规则见 **[reference/match-rules.md](./reference/match-rules.md)**。
400
-
401
- ---
402
-
403
- ## 7. 删除视图
404
-
405
- - 主路径使用 `--remove-views-file`;元素是 raw **`view_key`** 或唯一视图显示名,应用通过 `--app-key` 指定。
406
- - 优先用 **`view_key`** 删除;显示名重名会导致 **`AMBIGUOUS_VIEW`**,需先在 **`app get views`** 里确认。
407
- - DELETE 发出后,工具会用单个 **`view_key`** 回读验证,而不是再读全量视图列表判断删除结果。
408
- - 删除结果看 **`verification.view.delete_executed`**、**`readback_status`**、**`safe_to_retry_delete`**:
409
- - **`readback_status=deleted`**:删除已验证。
410
- - **`readback_status=unavailable`** 或 **`still_exists`**:删除请求已发出但回读未完全确认,**不要盲目重复删除**;稍后用 `builder app get views` 或对应视图详情确认。
411
-
412
- ---
413
-
414
- ## 8. 契约示例(可复制为文件基底)
415
-
416
- **Table + `visibility`(`minimal_example` 节选)**:
417
-
418
- ```json
419
- {
420
- "name": "项目台账视图",
421
- "type": "table",
422
- "columns": [101],
423
- "visibility": {
424
- "mode": "workspace",
425
- "selectors": {},
426
- "external_mode": "not",
427
- "external_selectors": {}
428
- }
429
- }
430
- ```
431
-
432
- **Gantt(`gantt_example` 节选)**:
433
-
434
- ```json
435
- {
436
- "name": "项目甘特图",
437
- "type": "gantt",
438
- "columns": [101, 102, 103],
439
- "start_que_id": 102,
440
- "end_que_id": 103,
441
- "title_que_id": 101,
442
- "filters": [
443
- {
444
- "que_id": 101,
445
- "operator": "eq",
446
- "value": "进行中"
447
- }
448
- ]
449
- }
450
- ```
451
-
452
- **Table + 筛选 + 查询条件 + 快捷按钮(单条 `--view-file`)**:
453
-
454
- ```json
455
- {
456
- "name": "客户查询视图",
457
- "type": "table",
458
- "columns": [101, 102, 103, 104],
459
- "filters": [
460
- {"que_id": 103, "operator": "eq", "value": "有效"}
461
- ],
462
- "query_conditions": {
463
- "enabled": true,
464
- "exact": false,
465
- "hide_before_query": false,
466
- "rows": [["客户名称", "负责人"], ["创建时间"]]
467
- },
468
- "action_buttons": [
469
- {
470
- "text": "行内创建跟进",
471
- "action": "add_data",
472
- "target_app_key": "FOLLOWUP_APP_KEY",
473
- "field_mappings": [
474
- {"source_field": "数据ID", "target_field": "关联客户"}
475
- ],
476
- "default_values": {"跟进状态": "待跟进"},
477
- "placement": "list"
478
- },
479
- {
480
- "text": "详情创建跟进",
481
- "action": "add_data",
482
- "target_app_key": "FOLLOWUP_APP_KEY",
483
- "field_mappings": [
484
- {"source_field": "数据ID", "target_field": "关联客户"}
485
- ],
486
- "default_values": {"跟进状态": "待跟进"},
487
- "placement": "detail"
488
- }
489
- ]
490
- }
12
+ qingflow --json builder views schema --schema-version v1alpha1 --schema-kind complete
13
+ qingflow --json builder views validate --schema-version v1alpha1 --file view.json
14
+ qingflow builder views apply --app-key APP_KEY --schema-version v1alpha1 --view-file view.json --publish
491
15
  ```
492
16
 
493
- ---
17
+ - `--view-file`:一个视图对象,新建或完整更新。一次一个应用、一个操作。
18
+ - `--patch-views-file`:已有视图的局部更新。JSON 数组最多一项,含 raw `view_key` 或唯一 `name`,以及 `set` / `unset`。
19
+ - `--remove-views-file`:删除。数组最多一项,优先 raw `view_key`。
20
+ - 三种文件不能混用。不要传 `views`、`upsert_views`、`upsert_view` 包装或多项数组。多个视图逐次调用。
21
+ - `app_key`、`profile` 写在命令上,不要写进视图对象。
22
+ - 读已有声明:`builder views get --app-key APP --schema-version v1alpha1 --schema-kind complete`。出现 `VIEW_NOT_EXTRACTABLE` 时改用 patch,不要拿残缺声明覆盖。
23
+ - MCP:`app_views_schema`,然后 `app_views_apply` 的 `upsert_view`(一个对象)、`patch_views`(最多一项)或 `remove_views`(最多一项)。
494
24
 
495
- ## 9. 实测记录(`ead8ims5i401`,`--publish`)
25
+ 字段、枚举、`data_permission`、各视图类型必填项都在 schema 的 `*Description` 里。`columns`、`filters`、`query_conditions.rows`、标题和时间字段写整数 queId。业务字段中文名不会解析。已知系统字段可以用 queId 或公开名,例如 `2` / `提交时间`、`0` / `编号`、`-17` / `数据ID`。
496
26
 
497
- 内容与仓库 **[views_upsert_table_minimal.example.json](../examples/views/views_upsert_table_minimal.example.json)** 一致(或历史探针名 **`CLI探针视图_可删`**)。
27
+ ## 交付约束
498
28
 
499
- **读视图**:
500
-
501
- ```bash
502
- qingflow --json builder app get --app-key ead8ims5i401 views
503
- ```
504
-
505
- **应用**:
506
-
507
- ```bash
508
- qingflow builder views apply \
509
- --app-key ead8ims5i401 \
510
- --publish \
511
- --view-file ./view.json
512
- ```
29
+ - 新建业务视图写 `query_conditions`(至少 2–4 个查询字段)和 `action_buttons`,并且 `publish=true`。`publish=false` 带按钮会返回 `VIEW_ACTION_BUTTONS_REQUIRE_PUBLISH`。只读或归档视图可以没有按钮,仍应有查询面板。
30
+ - `action_buttons` 至少各有一个 `placement: "list"` 和 `"detail"`。`header` 没有当前行上下文,不能写当前记录的 `field_mappings`。
31
+ - 当前记录带到另一个应用用 `action: "add_data"`(`target_app_key` + `field_mappings`,通常 `source_field: "数据ID"`)。只打开页面用 `action: "link"` 加 `url`。审批、状态流转、关闭任务走流程,不要用普通按钮假装。
32
+ - `default_values` 的 key 和 `field_mappings[].target_field` 是目标应用字段。选项必须是目标字段的原文或 option id。不确定就不要编造;`CUSTOM_BUTTON_DEFAULT_VALUE_UNSUPPORTED` 时用 patch 改默认值,不要重建视图。
33
+ - `action_buttons_mode` 默认 `merge`。`replace` 加空数组只清绑定,不删按钮本体。已有按钮先 `builder button get --button-text`,唯一命中后用 `buttons[]` 的 `button_id` 绑定。
34
+ - 写出 `data_permission` 时 `type` 和 `scope` 都必填,优先 `{"type":"custom","scope":"all"}`。整段省略时创建路径才用这个默认。`filters` 只在 `type=custom` 且 `scope=custom` 时是数据范围。不要把 `filters` 叠在 `config` 或预设范围上,也不要把它当查询栏。
35
+ - 写出 `visibility` 时 `mode` 必填。`mode=specific` 必须带 `selectors`(各列表不单独必填,空对象表示尚未配置成员)。`mode=everyone` 时 `external_mode` 必须是 `workspace`。`external_mode=specific` 必须带 `external_selectors`。整段省略时创建路径按工作区可见。
36
+ - 查询栏不要放 relation、attachment、subtable、address、Q-Linker、code-block。
37
+ - 不要新建名为 `全部数据`、`我的数据`、`我发起的`、`待办`、`已办`、`抄送` 的视图。要改它们,先读 raw `view_key` 再 patch。`view_key` 不要加 `custom:` 前缀。
38
+ - 未带 `view_key` 时,唯一同名视图会被更新,重名返回 `AMBIGUOUS_VIEW`。局部修改用 patch,不要用只含少数字段的完整对象去覆盖。
39
+ - 新建视图默认打开详情页关联查看(全部应用级关联资源)。改展示范围、匹配规则用 `builder associated-resource apply`,不要把关联筛选写进 `filters` 或 `query_conditions`。
40
+ - 新建要同时满足视图管理和数据管理权限。更新和删除只要视图管理。常见失败 `40002` / `40161` / 编辑锁。
513
41
 
514
- **结果摘要**(示例视图名 **`示例业务操作视图_CLI模板`**):`status: success`,`verification.view.status: created`,返回 **`view_key`**(如 **`ecdk22v65c02`**),并验证 `query_conditions` 与 `action_buttons`。
42
+ ## 回读
515
43
 
516
- ---
44
+ 成功看 `verification.view.status`(`created` / `updated`)。不要只凭视图存在就说筛选、查询或按钮已生效:
517
45
 
518
- ## 10. 排障要点
46
+ - 筛选:`view_filters_verified`
47
+ - 查询:`view_query_conditions_verified`
48
+ - 按钮:`action_buttons_verified` 与 `view_button_bindings_verified`
519
49
 
520
- | 现象 | 处理 |
521
- |------|------|
522
- | 列校验失败 / 无有效业务列 | **`app get fields`** 核对 **`name`**;避免 `columns` 仅含 **§7.1 系统列** |
523
- | 响应含 **`STALE_FIELD_REFERENCE`** / **`STALE_OPTION_REFERENCE`** 警告 | 声明引用了表单中已删除的字段/选项(后端保存视图本就原样透传);apply 已照写并在 `warnings` 留痕,重放/迁移场景属预期,人工整理时再清理死引用 |
524
- | 系统字段作标题/时间轴 | `title_que_id`/甘特 `start_que_id` 等可直接用系统字段 id(如 2=提交时间),与 `columns` 系统列同规则 |
525
- | 重名视图 / 删错 | **`app get views`**;更新时带 **`view_key`** |
526
- | 过滤器未生效疑虑 | 看响应 **`verification.view_filters_verified`**;必要时再 **`app get views`** |
527
- | 查询条件未生效疑虑 | 看响应 **`verification.view_query_conditions_verified`**;不要把 `query_conditions` 当 `filters` |
528
- | 后端 **40038 / Object not exist** | 先读失败项 **`details.view_result.details.field_level_diagnostics`** 与 **`recommended_minimal_retry`**。不要删除字段、不要重建应用;先按最小列重试,再逐步加非关键列/筛选。 |
529
- | 按钮/关联资源配置 | 常规业务按钮随视图写 **`action_buttons`**;关联视图/报表走 **`builder associated-resource apply`** |
530
- | 部分失败 | 读 **`views_diff.failed`** 与契约 **execution_notes** 中 **partial_success** |
531
- | 权限/锁 | 同 [publish verify](./99-publish-verify.md) 与 [app delivery reference](./reference/app-delivery-sop.md) |
50
+ `partial_success` 表示视图可能已写入,附属校验未过。按 `suggested_next_call` 对同一 `view_key` 做 patch。回读里按钮文案、位置、触发类型已经正确时,不要再建一次。
532
51
 
533
- ---
52
+ 删除看 `verification.view.delete_executed` 和 `readback_status`。`unavailable` 或 `still_exists` 时不要立刻重删,改用 `app get views` 确认。
534
53
 
535
- ## 11. 交叉引用
54
+ `STALE_FIELD_REFERENCE` 表示声明引用了已删除字段,保存会原样透传。`40038` 时读 `field_level_diagnostics`,按最小列重试,不要删字段或重建应用。
536
55
 
537
- - [views_upsert_table_minimal.example.json](../examples/views/views_upsert_table_minimal.example.json)(单视图示例,可直接作为 `--view-file` 使用)
538
- - [SKILL.md](../../SKILL.md):builder 直接输出、鉴权顺序。
539
- - [99-publish-verify.md](./99-publish-verify.md):发布与回读。
540
- - [reference/app-delivery-sop.md](./reference/app-delivery-sop.md):系统列与历史交付细节。
541
- - [QINGFLOW_CLI_EXPLORATION_REPORT.md](../core/QINGFLOW_CLI_EXPLORATION_REPORT.md):CLI 覆盖与 **`view_id` vs `view_key`** 备忘。
56
+ 示例对象见 [views_upsert_table_minimal.example.json](../examples/views/views_upsert_table_minimal.example.json)。操作符和跨应用匹配见 [reference/match-rules.md](./reference/match-rules.md)。按钮本体维护见 [80-buttons-associated-resources.md](./80-buttons-associated-resources.md)。
@@ -28,7 +28,7 @@ app get -> app get views/charts/buttons/associated resources -> apply button or
28
28
  - Use this standalone button tool for advanced cases: deleting button bodies, reusing the same button across many views, bulk reordering bindings, changing style independently, or configuring qRobot/wings when the user provides exact config.
29
29
  - Use `upsert_buttons` for create/update and `patch_buttons` for small changes.
30
30
  - Use `view_configs` only after reading target raw `view_key`.
31
- - Use semantic conditions from [reference/match-rules.md](./reference/match-rules.md). Fixed filters use `field_name + operator + value/values`; associated-resource context matching uses `target_field + operator + source_field/value`.
31
+ - Use semantic conditions from [reference/match-rules.md](./reference/match-rules.md). View `filters` and `visible_when` use `que_id`; chart filters use `field_name`; associated-resource context matching uses `target_field + operator + source_field/value`.
32
32
  - For add-data button field mappings, use target/source semantics, not raw backend ids, unless a contract explicitly requires ids.
33
33
  - If `button apply` returns `CUSTOM_BUTTON_APPLY_PARTIAL` / `VIEW_CUSTOM_BUTTON_READBACK_PENDING` while `custom_buttons_verified=true`, do not recreate the button. Run `builder app get --app-key APP views` and inspect the target view `buttons[]` for `button_type=CUSTOM` plus the expected `button_text` or `button_id`. Only reapply `view_configs` if the view binding is actually absent.
34
34
 
@@ -396,7 +396,7 @@ qingflow builder flow apply \
396
396
  **`数据ID`**、**`编号`**、**`申请人`**、**`申请时间`**、**`创建人`**、**`创建时间`**、**`提交人`**、**`提交时间`**、**`更新时间`**、**`更新人`**、**`当前流程状态`**、**`当前处理人`**、**`当前处理节点`**、**`流程标题`**。
397
397
 
398
398
  - **含义**:这些是平台维护的系统信息,**不要**在 **`add_fields`** 里手工造同名控件来「模拟」,也不要写进 `record insert` 的 `fields` / `items[].fields`。
399
- - **视图列例外**:`builder views apply` 对部分系统列名会过滤并警告(`ignored_system_columns`);新建/更新业务视图至少要包含一个真实业务字段。
399
+ - **视图列例外**:已知系统字段可以按 queId 或公开名出现在 `columns`、标题、甘特/日历日期和 `query_conditions` 里,例如 `2` / `提交时间`。不要在 `add_fields` 里再造同名控件。未知系统 id 仍会报告缺口。
400
400
  - **与 `app_get_fields` 的关系**:读回 **`fields[]`** 侧重 **表单搭建字段**;**编号 / 申请人** 等可能不会作为普通 `type` 出现在列表中(视应用模板与工作流是否开启),**以读回 JSON 为准**。交付时 **业务字段** 用 **`app_get_fields`**;**系统列** 由平台在 **数据列表 / 视图** 侧展示。
401
401
 
402
402
  ### 7.2 布局 / 流程中的「系统行为」
@@ -2,7 +2,7 @@
2
2
 
3
3
  本文适用于 Builder 侧所有给智能体公开的筛选和条件入口:
4
4
 
5
- - 视图固定筛选:`builder views apply` 的 `filters`
5
+ - 视图数据范围:`builder views apply` 的 `filters`。只在 `data_permission.type=custom` 且 `scope=custom` 时生效,字段写 `que_id`
6
6
  - 视图动作按钮显示条件:`action_buttons[].visible_when`
7
7
  - QingBI 图表筛选:`builder charts apply` 或 `portal apply sections[].chart.filters`
8
8
  - 关联视图 / 关联报表匹配:`builder associated-resource apply` 的 `match_mappings`
@@ -13,7 +13,8 @@
13
13
 
14
14
  公开写法按场景选择,智能体不要混用。**operator 语义完全一致,区别只在字段名键**:
15
15
 
16
- - **固定筛选**:`field_name + operator + value/values`
16
+ - **视图数据范围、查询条件和按钮可见条件**:`que_id + operator + value/values`
17
+ - **图表固定筛选**:`field_name + operator + value/values`
17
18
  - **关联资源上下文匹配**:`target_field + operator + source_field/value`
18
19
  - **新增数据传参**:`source_field + target_field`;静态默认值写 `default_values`
19
20
 
@@ -23,7 +24,8 @@
23
24
 
24
25
  | 你想表达 | 写法 | 示例 |
25
26
  | --- | --- | --- |
26
- | 当前视图/图表只显示某类数据 | `filters` | `{"field_name":"状态","operator":"eq","value":"进行中"}` |
27
+ | 当前视图只显示某类数据 | `filters` | `{"que_id":101,"operator":"eq","value":"进行中"}`,且 `data_permission` 为 `custom` + `custom` |
28
+ | 图表只显示某类数据 | `filters` | `{"field_name":"状态","operator":"eq","value":"进行中"}` |
27
29
  | 关联报表/关联视图只显示“当前记录相关”的数据 | `match_mappings` + `source_field` | `{"target_field":"关联客户","operator":"eq","source_field":"数据ID"}` |
28
30
  | 关联报表/关联视图再加一个固定条件 | `match_mappings` + `value/values` | `{"target_field":"状态","operator":"eq","value":"有效"}` |
29
31
  | 从当前记录创建下游记录并带值 | `field_mappings` | `{"source_field":"数据ID","target_field":"关联工单"}` |
@@ -90,9 +92,10 @@
90
92
 
91
93
  优先使用语义化映射,不手写后端 raw `que_relation` / `match_rules`。
92
94
 
93
- 心智模型:**同一个 operator,同一套 value 规则;只是当前记录匹配要把 `field_name` 改成 `target_field`,并用 `source_field` 表示当前记录字段。**
95
+ 心智模型:**同一个 operator,同一套 value 规则;只是当前记录匹配要把字段键改成 `target_field`,并用 `source_field` 表示当前记录字段。**
94
96
 
95
- - 固定筛选当前资源自己的数据:`field_name + operator + value/values`
97
+ - 视图数据范围:`que_id + operator + value/values`,且 `data_permission` 为 `custom` + `custom`
98
+ - 图表固定筛选:`field_name + operator + value/values`
96
99
  - 用当前记录过滤另一个资源:`target_field + operator + source_field`
97
100
  - 给另一个资源加静态筛选:`target_field + operator + value/values`
98
101
  - 从当前记录创建下游记录时传值:`source_field + target_field`,不写 `operator`
@@ -55,7 +55,7 @@
55
55
  | --- | --- |
56
56
  | `builder app get` | 应用地图;轻量返回字段摘要、视图、图表、自定义按钮、关联资源池 |
57
57
  | `builder app-form schema/get/validate/apply` | 当前表单/字段/布局/应用设置入口;固定 AppForm schema 版本,完整声明写入并保留现有 IDs;旧 `builder schema apply` / `builder layout apply` 仅为已移除的内部兼容适配器 |
58
- | `builder views apply` | 业务视图;固定筛选写 `filters`,前端查询栏写 `query_conditions` |
58
+ | `builder views apply` | 业务视图。字段形状读 `views schema`;一次一个视图对象。数据权限默认 `custom + all`,自定义范围才写 `filters`;查询栏写 `query_conditions` 的 queId |
59
59
  | `builder button apply` | 自定义按钮默认路径;新增数据按钮用 `field_mappings/default_values`,绑定位置用 `header/detail/list` |
60
60
  | `builder associated-resource apply` | 应用级关联视图/报表池 + 视图展示配置;报表来源用 `report_source`,不让智能体填写后端 raw source |
61
61
  | `builder charts apply` | QingBI 报表配置;报表变更 immediate-live,不等同于应用发布 |
@@ -2,13 +2,13 @@
2
2
  "name": "项目台账视图",
3
3
  "type": "table",
4
4
  "columns": [100, 101, 102, 103],
5
- "data_permission": {"type": "custom", "scope": "dept"},
5
+ "data_permission": {"type": "custom", "scope": "all"},
6
6
  "sort": [{"que_id": 100, "ascending": false}],
7
7
  "display": {"row_height": "compact", "pin_navigate": true},
8
8
  "query_conditions": {
9
9
  "enabled": true,
10
10
  "exact": false,
11
11
  "hide_before_query": false,
12
- "rows": [["项目名称", "负责人"], ["创建时间"]]
12
+ "rows": [[100, 101], [2]]
13
13
  }
14
14
  }
@@ -9,7 +9,7 @@
9
9
  "enabled": true,
10
10
  "exact": false,
11
11
  "hide_before_query": false,
12
- "rows": [["主记录编号", "主记录名称"], ["状态", "负责人"]]
12
+ "rows": [[100, 101], [102, 2]]
13
13
  },
14
14
  "action_buttons": [
15
15
  {
@@ -311,7 +311,8 @@
311
311
  "DataPermission": {
312
312
  "type": "object",
313
313
  "additionalProperties": false,
314
- "dataPermissionDescription": "先选来源 type,再在 type=custom 时选 scope。默认且优先写 custom + all。filters 只在 type=custom 且 scope=custom 时作为数据范围,不会叠在 config 或预设范围上。",
314
+ "required": ["type", "scope"],
315
+ "dataPermissionDescription": "写出本对象时 type 与 scope 都必填。优先写 custom + all。整段 data_permission 省略时,创建路径才按 custom + all。filters 只在 type=custom 且 scope=custom 时作为数据范围,不会叠在 config 或预设范围上。",
315
316
  "properties": {
316
317
  "type": {
317
318
  "type": "string",
@@ -320,7 +321,7 @@
320
321
  "custom"
321
322
  ],
322
323
  "default": "custom",
323
- "dataPermissionDescription": "数据权限来源,默认 custom。未声明时按 custom + all 创建。config=跟随应用成员授权的数据权限,本视图的 scope 与 filters 不参与查询。custom=使用本视图自己的数据范围(scope)。别名 dataPermissionType(CONFIG/CUSTOM)。",
324
+ "dataPermissionDescription": "数据权限来源。写出 data_permission 时必填。config=跟随应用成员授权的数据权限,本视图的 scope 与 filters 不参与查询。custom=使用本视图自己的数据范围(scope)。别名 dataPermissionType(CONFIG/CUSTOM)。",
324
325
  "x-backend": "dataPermissionType(CONFIG|CUSTOM)"
325
326
  },
326
327
  "scope": {
@@ -333,7 +334,7 @@
333
334
  "custom"
334
335
  ],
335
336
  "default": "all",
336
- "dataScopeDescription": "仅 type=custom 时生效,默认 all。all=不追加数据范围;oneself=仅自己发起;dept=所在部门发起;subordinate=下属发起;custom=用 filters 作为数据范围。type=config 时不要用 scope 选择应用权限,应用授权组的范围写在成员授权上。",
337
+ "dataScopeDescription": "写出 data_permission 时必填,且只在 type=custom 时生效。all=不追加数据范围;oneself=仅自己发起;dept=所在部门发起;subordinate=下属发起;custom=用 filters 作为数据范围。type=config 时不要用 scope 选择应用权限,应用授权组的范围写在成员授权上。",
337
338
  "x-backend": "dataScope(ALL|ONESELF|DEPT|SUBORDINATE|CUSTOM)"
338
339
  }
339
340
  }
@@ -341,6 +342,34 @@
341
342
  "Visibility": {
342
343
  "type": "object",
343
344
  "additionalProperties": false,
345
+ "required": ["mode"],
346
+ "visibilityDescription": "写出 visibility 时 mode 必填。mode=specific 时必须带 selectors;selectors 各列表都不是单独必填,空对象表示指定范围但尚未配置成员。mode=everyone 时 external_mode 必须为 workspace。external_mode=specific 时必须带 external_selectors。整段省略时创建路径按 workspace + external_mode=not。",
347
+ "allOf": [
348
+ {
349
+ "if": {
350
+ "properties": { "mode": { "const": "specific" } },
351
+ "required": ["mode"]
352
+ },
353
+ "then": { "required": ["selectors"] }
354
+ },
355
+ {
356
+ "if": {
357
+ "properties": { "mode": { "const": "everyone" } },
358
+ "required": ["mode"]
359
+ },
360
+ "then": {
361
+ "required": ["external_mode"],
362
+ "properties": { "external_mode": { "const": "workspace" } }
363
+ }
364
+ },
365
+ {
366
+ "if": {
367
+ "properties": { "external_mode": { "const": "specific" } },
368
+ "required": ["external_mode"]
369
+ },
370
+ "then": { "required": ["external_selectors"] }
371
+ }
372
+ ],
344
373
  "properties": {
345
374
  "mode": {
346
375
  "type": "string",
@@ -373,6 +402,7 @@
373
402
  "VisibilitySelectors": {
374
403
  "type": "object",
375
404
  "additionalProperties": false,
405
+ "visibilitySelectorsDescription": "成员、部门、角色用不同列表表达,没有任何一个列表单独必填。mode=specific 时本对象本身必填;空对象是合法回读,表示指定范围但尚未配置成员。要真正授权时,至少填一个非空列表。",
376
406
  "properties": {
377
407
  "member_uids": {
378
408
  "type": "array",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://qingflow.com/schemas/builder/views/v1alpha1/details/data-permission.json",
4
4
  "title": "Qingflow Views data permission configuration",
5
- "dataPermissionDescription": "视图数据权限片段(schema_kind=data-permission)。默认且优先写 data_permission {type: custom, scope: all}。type 选来源,scope 只在 type=custom 时生效;filters 只在 type=custom 且 scope=custom 时作为数据范围。字段直接并入完整视图声明。",
5
+ "dataPermissionDescription": "视图数据权限片段(schema_kind=data-permission)。写出 data_permission 时 type 与 scope 都必填,优先 {type: custom, scope: all}。整段省略时创建路径才按 custom + all。type 选来源,scope 只在 type=custom 时生效;filters 只在 type=custom 且 scope=custom 时作为数据范围。字段直接并入完整视图声明。",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "properties": {
@@ -36,7 +36,7 @@
36
36
  "fieldSchema": "字段类型、默认值等表单侧细节用 app_form_schema 传 schema_kind=field 和 field_type 获取(CLI: builder app-form schema --schema-kind field --field-type TYPE)。"
37
37
  }
38
38
  },
39
- "x-qingflow-apply-semantics": "新建视图默认且应优先写 data_permission type=custom、scope=all。只有要跟随应用成员授权时才用 type=config,此时不要用 scope 表达范围。filters 仅在 type=custom 且 scope=custom 时作为数据范围;省略 filters 表示保留现有规则,空数组表示清空。",
39
+ "x-qingflow-apply-semantics": "写出 data_permission 时 type 与 scope 都必填,优先 type=custom、scope=all。整段省略时创建路径才按 custom + all。只有要跟随应用成员授权时才用 type=config,此时不要用 scope 表达范围。filters 仅在 type=custom 且 scope=custom 时作为数据范围;省略 filters 表示保留现有规则,空数组表示清空。",
40
40
  "x-qingflow-mode-requirements": {
41
41
  "default": "未声明 data_permission 时按 custom + all 创建。需要限制行时再改 scope,不要默认改成 config。",
42
42
  "config": "跟随应用成员授权的数据权限。视图上的 scope、filters 不参与查询。应用授权组自己可以是全部、自己、部门、下属或自定义公式,那些规则写在成员授权上,不写在视图声明里。",
@@ -199,7 +199,8 @@
199
199
  "DataPermission": {
200
200
  "type": "object",
201
201
  "additionalProperties": false,
202
- "dataPermissionDescription": "先选来源 type,再在 type=custom 时选 scope。默认且优先写 custom + all。filters 只在 type=custom 且 scope=custom 时作为数据范围,不会叠在 config 或预设范围上。",
202
+ "required": ["type", "scope"],
203
+ "dataPermissionDescription": "写出本对象时 type 与 scope 都必填。优先写 custom + all。整段 data_permission 省略时,创建路径才按 custom + all。filters 只在 type=custom 且 scope=custom 时作为数据范围,不会叠在 config 或预设范围上。",
203
204
  "properties": {
204
205
  "type": {
205
206
  "type": "string",
@@ -208,7 +209,7 @@
208
209
  "custom"
209
210
  ],
210
211
  "default": "custom",
211
- "dataPermissionDescription": "数据权限来源,默认 custom。未声明时按 custom + all 创建。config=跟随应用成员授权的数据权限,本视图的 scope 与 filters 不参与查询。custom=使用本视图自己的数据范围(scope)。别名 dataPermissionType(CONFIG/CUSTOM)。",
212
+ "dataPermissionDescription": "数据权限来源。写出 data_permission 时必填。config=跟随应用成员授权的数据权限,本视图的 scope 与 filters 不参与查询。custom=使用本视图自己的数据范围(scope)。别名 dataPermissionType(CONFIG/CUSTOM)。",
212
213
  "x-backend": "viewgraph.dataPermissionType(CONFIG|CUSTOM)"
213
214
  },
214
215
  "scope": {
@@ -221,7 +222,7 @@
221
222
  "custom"
222
223
  ],
223
224
  "default": "all",
224
- "dataScopeDescription": "仅 type=custom 时生效,默认 all。all=不追加数据范围;oneself=仅自己发起;dept=所在部门发起;subordinate=下属发起;custom=用 filters 作为数据范围(规则在 complete 或 schema_kind=data-permission)。type=config 时不要用 scope 选择应用权限,应用授权组的范围写在成员授权上。dataset-v0 实测分布:all×560 / custom×74 / oneself×71。",
225
+ "dataScopeDescription": "写出 data_permission 时必填,且只在 type=custom 时生效。all=不追加数据范围;oneself=仅自己发起;dept=所在部门发起;subordinate=下属发起;custom=用 filters 作为数据范围(规则在 complete 或 schema_kind=data-permission)。type=config 时不要用 scope 选择应用权限,应用授权组的范围写在成员授权上。dataset-v0 实测分布:all×560 / custom×74 / oneself×71。",
225
226
  "x-backend": "viewgraph.dataScope(ALL|ONESELF|DEPT|SUBORDINATE|CUSTOM)"
226
227
  }
227
228
  }