@qingflow-tech/qingflow-cli 1.1.43-beta.1 → 1.1.43-beta.2
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 +4 -3
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-form/SKILL.md +53 -0
- package/skills/qingflow-app-form/agents/openai.yaml +4 -0
- package/skills/qingflow-cli/SKILL.md +6 -6
- package/skills/qingflow-cli/manifest.yaml +1 -1
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_BUILDER_APP_DELIVERY_WORKFLOW.md +4 -4
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_EXPLORATION_REPORT.md +1 -1
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_FIELD_DATA_TYPES.md +1 -1
- package/skills/qingflow-cli/reference/QINGFLOW_CLI_SCHEMA_APPLY_FIELD_TYPES_AND_SCENARIOS.md +4 -4
- package/skills/qingflow-cli/reference/builder/10-build-single-app.md +5 -5
- package/skills/qingflow-cli/reference/builder/20-build-complete-system.md +14 -14
- package/skills/qingflow-cli/reference/builder/30-schema-fields.md +98 -101
- package/skills/qingflow-cli/reference/builder/40-layout.md +39 -31
- package/skills/qingflow-cli/reference/builder/README.md +9 -9
- package/skills/qingflow-cli/reference/builder/code-integrations/README.md +4 -2
- package/skills/qingflow-cli/reference/builder/code-integrations/code-block.md +2 -0
- package/skills/qingflow-cli/reference/builder/code-integrations/q-linker.md +2 -0
- package/skills/qingflow-cli/reference/builder/reference/app-delivery-sop.md +45 -38
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_EXPLORATION_REPORT.md +1 -1
- package/skills/qingflow-cli/reference/core/QINGFLOW_CLI_FIELD_DATA_TYPES.md +1 -1
- package/skills/qingflow-cli/reference/examples/README.md +3 -3
- package/skills/qingflow-mcp-setup/SKILL.md +1 -1
- package/src/qingflow_mcp/app_form_compat.py +6 -1
- package/src/qingflow_mcp/builder_facade/app_form.py +547 -18
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/complete.json +1321 -178
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/address.json +268 -7
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/amount.json +115 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/attachment.json +304 -7
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/code_block.json +23 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/data_relation.json +23 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/date.json +23 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/datetime.json +23 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/department.json +145 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/email.json +69 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/link.json +69 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/long_text.json +69 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/member.json +360 -7
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/multi_select.json +71 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/number.json +115 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/phone.json +78 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/q_linker.json +23 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/relation.json +249 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/single_choice.json +71 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/single_select.json +71 -4
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/subtable.json +1041 -20
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/text.json +69 -10
- package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/summary.json +23 -0
- package/src/qingflow_mcp/response_trim.py +41 -1
|
@@ -1,53 +1,63 @@
|
|
|
1
|
-
# Builder
|
|
1
|
+
# Builder Field Modeling And AppForm Pointer
|
|
2
2
|
|
|
3
3
|
Read this when the task is about app creation fields, schema updates, field types, data title, data cover, relation fields, or system fields.
|
|
4
4
|
|
|
5
5
|
## Scope
|
|
6
6
|
|
|
7
|
-
Responsible for:
|
|
7
|
+
Responsible for: field modeling notes, AppForm field types, data title/cover, relation field shape, and routing form writes to the sibling `qingflow-app-form` Skill.
|
|
8
8
|
|
|
9
|
-
Not responsible for:
|
|
9
|
+
Not responsible for: record data operations. Form layout is part of the AppForm `spec.body`; do not use a separate schema/layout write path.
|
|
10
10
|
|
|
11
11
|
## Main chain
|
|
12
12
|
|
|
13
13
|
```text
|
|
14
|
-
app/package resolve ->
|
|
14
|
+
app/package resolve -> app_form_schema/get/validate/apply -> app get fields/layout readback -> publish/readback verify
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
For
|
|
17
|
+
For every app, use the sibling `qingflow-app-form` Skill with a pinned schema version and a complete declaration. The old `builder schema apply`, `--apps-file`, `--form-file`, and `add_fields/update_fields/remove_fields` routes are retired compatibility adapters, not current public commands.
|
|
18
18
|
|
|
19
19
|
## Demo files
|
|
20
20
|
|
|
21
21
|
| Scenario | Example |
|
|
22
22
|
|----------|---------|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
23
|
+
| AppForm declaration shape | [qingflow-app-form Skill](../../../qingflow-app-form/SKILL.md) |
|
|
24
|
+
| Historical schema capability probe (not the current 21-type manifest) | [schema_apply_add_fields_all_types.json](../examples/schema/schema_apply_add_fields_all_types.json) |
|
|
25
|
+
| Historical existing-app field capability probe | [schema_apply_add_fields_all_types.json](../examples/schema/schema_apply_add_fields_all_types.json) |
|
|
26
26
|
|
|
27
|
-
## Create app with
|
|
27
|
+
## Create app with AppForm
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
The current creation shape is a complete AppForm declaration: `spec.body` contains fields, sections, rows, and settings. Pin `app_form_schema`, preserve IDs from `app_form_get(being_draft=true)`, validate, and apply through the sibling Skill. Do not call the retired schema/layout CLI adapters.
|
|
30
30
|
|
|
31
31
|
```json
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
{
|
|
33
|
+
"apiVersion": "builder.qingflow.com/v1alpha1",
|
|
34
|
+
"packageId": 123456,
|
|
35
|
+
"spec": {
|
|
36
|
+
"appName": "生产工单",
|
|
37
|
+
"icon": "clipboard-check",
|
|
38
|
+
"color": "green",
|
|
39
|
+
"body": [
|
|
40
|
+
{
|
|
41
|
+
"kind": "section",
|
|
42
|
+
"title": "基础信息",
|
|
43
|
+
"rows": [
|
|
44
|
+
{"fields": [
|
|
45
|
+
{"name": "工单编号", "type": "text", "dataTitle": true},
|
|
46
|
+
{"name": "产品", "type": "text"},
|
|
47
|
+
{"name": "状态", "type": "single_select", "config": {"options": ["待排产", "生产中", "已完工"]}}
|
|
48
|
+
]},
|
|
49
|
+
{"fields": [
|
|
50
|
+
{"name": "计划数量", "type": "number"},
|
|
51
|
+
{"name": "计划完成日期", "type": "date"}
|
|
52
|
+
]}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
45
55
|
]
|
|
46
56
|
}
|
|
47
|
-
|
|
57
|
+
}
|
|
48
58
|
```
|
|
49
59
|
|
|
50
|
-
|
|
60
|
+
Historical CLI shape (retired; do not run):
|
|
51
61
|
|
|
52
62
|
```bash
|
|
53
63
|
qingflow --json builder schema apply \
|
|
@@ -59,7 +69,7 @@ qingflow --json builder schema apply \
|
|
|
59
69
|
> tmp/schema_apply_production_order.json
|
|
60
70
|
```
|
|
61
71
|
|
|
62
|
-
|
|
72
|
+
Historical complete-system item shape (retired; do not run):
|
|
63
73
|
|
|
64
74
|
```json
|
|
65
75
|
{
|
|
@@ -76,7 +86,7 @@ Complete-system `apps-file` item:
|
|
|
76
86
|
}
|
|
77
87
|
```
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
Historical complete-system CLI (retired; do not run):
|
|
80
90
|
|
|
81
91
|
```bash
|
|
82
92
|
qingflow --json builder schema apply \
|
|
@@ -84,7 +94,7 @@ qingflow --json builder schema apply \
|
|
|
84
94
|
> tmp/schema_apply_system.json
|
|
85
95
|
```
|
|
86
96
|
|
|
87
|
-
|
|
97
|
+
The following is retained only to recognize a historical `apps-file` payload. It is not a current template: create each app with its own AppForm declaration, save the returned `appKey`, then bind relations with `targetAppKey`.
|
|
88
98
|
|
|
89
99
|
```json
|
|
90
100
|
{
|
|
@@ -141,63 +151,50 @@ For the complete-system apps-file, use the object shape below. The same file car
|
|
|
141
151
|
}
|
|
142
152
|
```
|
|
143
153
|
|
|
144
|
-
## Existing-app
|
|
154
|
+
## Existing-app field maintenance notes
|
|
145
155
|
|
|
146
|
-
- Re-read
|
|
147
|
-
-
|
|
148
|
-
- Use `
|
|
149
|
-
- If apply returns uncertain write state, re-read fields before retrying.
|
|
150
|
-
- Do not use this section for new complete-system creation. New apps should stay on the `apps[].form` path above.
|
|
156
|
+
- Re-read the published and draft AppForm before updating; preserve every field and ID that should remain.
|
|
157
|
+
- Use complete AppForm target state for additions, edits, layout changes, and removals; never replay a partial field patch.
|
|
158
|
+
- Use `app_form_validate` before every apply and follow AppForm recovery rules for uncertain write state.
|
|
151
159
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
"publish": true,
|
|
158
|
-
"add_fields": [{"name": "跟进日期", "type": "date"}],
|
|
159
|
-
"update_fields": [
|
|
160
|
-
{
|
|
161
|
-
"selector": {"name": "金额"},
|
|
162
|
-
"set": {"name": "订单金额", "required": true}
|
|
163
|
-
}
|
|
164
|
-
],
|
|
165
|
-
"remove_fields": [{"name": "旧字段"}]
|
|
166
|
-
}
|
|
167
|
-
```
|
|
160
|
+
Current updates must be complete AppForm declarations. Start from
|
|
161
|
+
`app_form_get(being_draft=true)`, keep the existing `appKey`/IDs, change the
|
|
162
|
+
desired `spec.body`, validate the complete declaration, and apply it. The old
|
|
163
|
+
`add_fields`/`update_fields`/`remove_fields` patch shape is retired and is not a
|
|
164
|
+
current CLI payload.
|
|
168
165
|
|
|
169
166
|
## Field type reference
|
|
170
167
|
|
|
171
|
-
> **口径**:`field.type`
|
|
172
|
-
> **CLI
|
|
173
|
-
> **新建应用主规则**:`
|
|
168
|
+
> **口径**:`field.type` 枚举和字段形状以固定版本的 **`qingflow --json builder app-form schema`** / `app_form_schema()` 返回结果为准;每个 canonical 类型还可用 `--field-type TYPE` 获取细节。不要从已退休的 `app_schema_apply` contract 推断当前 AppForm payload。
|
|
169
|
+
> **CLI**:表单写入使用 `qingflow [--profile NAME] --json builder app-form schema/get/validate/apply`;`validate/apply` 接受 `--file`,`get` 接受 `--app-key`。旧 `builder schema apply` 及 `builder layout apply` 不在当前 parser 的公开命令集合中。
|
|
170
|
+
> **新建应用主规则**:`spec.body` 里必须有且仅有一个顶层字段标记 `dataTitle: true`;数据封面可选,只能在顶层 `attachment` 字段标记 `dataCover: true`。
|
|
174
171
|
> **权限**:包内新建应用按后端 `CreateAppBean` 链路只预检目标包 **AddAppAuth**;已有应用的字段/基础信息变更才走应用自身 **EditAppAuth**。
|
|
175
172
|
|
|
176
173
|
## 0. 字段建模一眼决策表
|
|
177
174
|
|
|
178
|
-
|
|
175
|
+
先按业务语义选字段类型。当前主路径使用 pinned AppForm Schema 返回的 canonical 类型;历史别名只在迁移旧草稿时识别,不能作为新声明模板。
|
|
179
176
|
|
|
180
177
|
| 业务语义 | 推荐写法 | 注意 |
|
|
181
178
|
| --- | --- | --- |
|
|
182
|
-
| 名称、标题、编号、短文本 | `text` | 新建应用必须且只能有一个顶层可读字段标记 `
|
|
183
|
-
| 说明、备注、描述、长文本 | `
|
|
184
|
-
| 状态、类型、等级、阶段、是否枚举 | `
|
|
185
|
-
| 标签、多选项、多个类别 | `multi_select` |
|
|
179
|
+
| 名称、标题、编号、短文本 | `text` | 新建应用必须且只能有一个顶层可读字段标记 `dataTitle: true` |
|
|
180
|
+
| 说明、备注、描述、长文本 | `long_text` | 多行文本 |
|
|
181
|
+
| 状态、类型、等级、阶段、是否枚举 | `single_select` | 必须在 `config.options` 定义非空字符串数组 |
|
|
182
|
+
| 标签、多选项、多个类别 | `multi_select` | 必须在 `config.options` 定义非空字符串数组 |
|
|
186
183
|
| 数量、比例、分数、工时、百分比、时长 | `number` | 需要小数或计算时优先 `number` |
|
|
187
184
|
| 金额、费用、单价、预算 | `amount` | 只用于货币/金额语义,不要拿它存比例或普通数量 |
|
|
188
185
|
| 日期、计划日、截止日 | `date` | 同时需要时分秒才用 `datetime` |
|
|
189
186
|
| 负责人、审批人、参与人 | `member` | 不要创建“申请人/提交人”等平台系统字段 |
|
|
190
|
-
| 部门、组织 | `department` | 可按需要补 `
|
|
191
|
-
| 图片、文件、附件 | `attachment` | 只有顶层 `attachment` 可标记 `
|
|
192
|
-
| 跨应用业务对象关系 | `relation` |
|
|
187
|
+
| 部门、组织 | `department` | 可按需要补 `config.departmentScope` |
|
|
188
|
+
| 图片、文件、附件 | `attachment` | 只有顶层 `attachment` 可标记 `dataCover: true` |
|
|
189
|
+
| 跨应用业务对象关系 | `relation` | 使用已确认的 `targetAppKey`;`displayField` / `visibleFields` 必须写对象选择器 |
|
|
193
190
|
|
|
194
191
|
禁止创建平台系统字段:`数据ID`、`编号`、`申请人`、`申请时间`、`创建人`、`创建时间`、`提交人`、`提交时间`、`更新时间`、`更新人`、`当前流程状态`、`当前处理人`、`当前处理节点`、`流程标题`。需要引用系统字段时,只在工具明确支持的位置引用,例如按钮 `source_field: "数据ID"`。
|
|
195
192
|
|
|
196
193
|
---
|
|
197
194
|
|
|
198
|
-
## 1. 全部 `field.type`(
|
|
195
|
+
## 1. 全部 `field.type`(21 种)
|
|
199
196
|
|
|
200
|
-
|
|
197
|
+
固定 AppForm Schema 中可用的字段类型为:
|
|
201
198
|
|
|
202
199
|
| `type` | 说明(搭建语义) |
|
|
203
200
|
|--------|------------------|
|
|
@@ -205,35 +202,37 @@ Example patch:
|
|
|
205
202
|
| `long_text` | 多行文本 |
|
|
206
203
|
| `number` | 数字 |
|
|
207
204
|
| `amount` | 金额 |
|
|
205
|
+
| `link` | 链接 |
|
|
208
206
|
| `date` | 日期 |
|
|
209
207
|
| `datetime` | 日期时间 |
|
|
210
208
|
| `member` | 成员 |
|
|
211
|
-
| `department` | 部门(可带 `
|
|
209
|
+
| `department` | 部门(可带 `config.departmentScope`) |
|
|
212
210
|
| `single_select` | 单选 |
|
|
213
211
|
| `multi_select` | 多选 |
|
|
214
212
|
| `phone` | 电话 |
|
|
215
213
|
| `email` | 邮箱 |
|
|
216
214
|
| `address` | 地址 |
|
|
217
215
|
| `attachment` | 附件 |
|
|
218
|
-
| `
|
|
219
|
-
| `q_linker` | 远程查询 / 数据获取(**`
|
|
220
|
-
| `code_block` | 代码块(**`
|
|
221
|
-
| `relation` | 关联记录(**`
|
|
216
|
+
| `single_choice` | 兼容的单选类型;新声明优先使用 `single_select` |
|
|
217
|
+
| `q_linker` | 远程查询 / 数据获取(**`config.qLinkerBinding`**) |
|
|
218
|
+
| `code_block` | 代码块(**`config.codeBlockBinding`**) |
|
|
219
|
+
| `relation` | 关联记录(**`config.relationMode`**:`single` \| `multiple`) |
|
|
220
|
+
| `data_relation` | 数据关联/引用填充 |
|
|
222
221
|
| `subtable` | 子表(**`subfields[]`**) |
|
|
223
222
|
|
|
224
|
-
**`
|
|
223
|
+
**`config.relationMode`**:仅 **`relation`** 使用,取值为 **`single`** 或 **`multiple`**。一个应用可以有多个 `relation` 字段;不要因为 relation 数量超过 1 就改成文本字段。
|
|
225
224
|
|
|
226
|
-
### 1.1
|
|
225
|
+
### 1.1 历史字段类型别名
|
|
227
226
|
|
|
228
|
-
|
|
227
|
+
主路径使用 pinned AppForm Schema 返回的 canonical 类型;下列别名只用于识别历史载荷,不作为当前声明模板:
|
|
229
228
|
|
|
230
|
-
|
|
|
229
|
+
| 历史写法 | 当前 canonical 类型 |
|
|
231
230
|
|------------|----------------|
|
|
232
231
|
| `multiline` / `multiline_text` / `textarea` | `long_text` |
|
|
233
232
|
| `select` / `single_choice` / `dropdown` | `single_select` |
|
|
234
233
|
| `multi_select` / `multi_choice` / `multiple_choice` / `checkbox` | `multi_select` |
|
|
235
234
|
|
|
236
|
-
|
|
235
|
+
`boolean`、`multiline`、`select`、`checkbox` 等仅是兼容输入,归一化结果以 pinned `app_form_schema` 的类型详情为准;新声明不要使用这些别名。
|
|
237
236
|
|
|
238
237
|
---
|
|
239
238
|
|
|
@@ -241,31 +240,33 @@ Example patch:
|
|
|
241
240
|
|
|
242
241
|
| `type` | 通常必填 | 常见可选 / 约束 |
|
|
243
242
|
|--------|----------|-----------------|
|
|
244
|
-
| 标量与选择器 | `name` + `type`(+ 业务 `required` 等) | `description`、`required`;新建应用时其中一个顶层可读字段须 `
|
|
245
|
-
| `department` | 同左 | **`
|
|
246
|
-
| `relation` |
|
|
247
|
-
| `subtable` | **`subfields[]` 非空** |
|
|
248
|
-
| `q_linker` | **`
|
|
249
|
-
| `code_block` | **`
|
|
243
|
+
| 标量与选择器 | `name` + `type`(+ 业务 `required` 等) | `description`、`required`;新建应用时其中一个顶层可读字段须 `dataTitle: true`;**`single_select` / `multi_select` 的 `config.options` 是非空字符串数组**,如 `["A", "B"]` |
|
|
244
|
+
| `department` | 同左 | **`config.departmentScope`**:`mode: all \| custom`;`custom` 时 **`departments[]`**(含 `deptId` 等) |
|
|
245
|
+
| `relation` | **`targetAppKey`**;另需 **`displayField`**、**`visibleFields[]`** | **`relationMode`**;目标应用元数据不可读时先读已发布表单,不要猜目标 key |
|
|
246
|
+
| `subtable` | **`subfields[]` 非空** | 子列递归同父级规则;使用 Schema 返回的 camelCase 子字段配置 |
|
|
247
|
+
| `q_linker` | **`config.qLinkerBinding`**:`inputs`、`request`、**`outputs[]` 每项须含 `targetField`**(能解析到本表单字段) | `request.url` 等须符合**租户/后端远程查询策略**;以字段类型 Schema 返回的配置为准 |
|
|
248
|
+
| `code_block` | **`config.codeBlockBinding`**:`inputs`、`code`、**`outputs[]` + `targetField`**;代码体须能被规范识别 **`qf_output` 赋值** | 以字段类型 Schema 返回的 camelCase 配置为准 |
|
|
250
249
|
|
|
251
250
|
别名:契约会把 `title`/`label` 映射到 **`name`** 等;字段类型自然别名见 §1.1。
|
|
252
251
|
|
|
253
252
|
### 2.1 `relation` 选择器形态
|
|
254
253
|
|
|
255
|
-
`relation`
|
|
254
|
+
`relation` 的配置必须使用已确认的目标应用 key;展示字段选择器必须写对象,不要写裸字符串:
|
|
256
255
|
|
|
257
256
|
```json
|
|
258
257
|
{
|
|
259
258
|
"name": "关联产品",
|
|
260
259
|
"type": "relation",
|
|
261
|
-
"
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
"config": {
|
|
261
|
+
"targetAppKey": "PRODUCT_APP_KEY",
|
|
262
|
+
"relationMode": "single",
|
|
263
|
+
"displayField": {"name": "产品编码"},
|
|
264
|
+
"visibleFields": [{"name": "产品名称"}, {"name": "产品线"}]
|
|
265
|
+
}
|
|
265
266
|
}
|
|
266
267
|
```
|
|
267
268
|
|
|
268
|
-
|
|
269
|
+
只在目标应用已经创建并通过 readback 确认后填写 `targetAppKey`。如果返回选择器校验错误,修复 `config.displayField` / `config.visibleFields`,不要重建应用或改 `appKey`。
|
|
269
270
|
|
|
270
271
|
### 2.2 工作流状态字段
|
|
271
272
|
|
|
@@ -273,18 +274,14 @@ Example patch:
|
|
|
273
274
|
|
|
274
275
|
---
|
|
275
276
|
|
|
276
|
-
## 3.
|
|
277
|
+
## 3. AppForm 场景矩阵
|
|
277
278
|
|
|
278
|
-
| 场景 |
|
|
279
|
+
| 场景 | 当前入口 | 说明 |
|
|
279
280
|
|------|----------------|------|
|
|
280
|
-
| 编辑已有应用 |
|
|
281
|
-
| 包内新建应用 |
|
|
282
|
-
|
|
|
283
|
-
|
|
|
284
|
-
| 改字段 | `--update-fields-file` | 每项 **`selector`**(`name`/`que_id`/`field_id`)+ **`set`** |
|
|
285
|
-
| 删字段 | `--remove-fields-file` | 每项至少 **`name`/`que_id`/`field_id`** 之一 |
|
|
286
|
-
| 可见性(新建/部分元数据) | `--visibility-file` | `mode` / `external_mode` / `selectors` 见交付文 §3.2 |
|
|
287
|
-
| 发布 | 默认或 `--publish`;探针常用 **`--no-publish`** | 与 **`app_publish_verify`** 配合 |
|
|
281
|
+
| 编辑已有应用 | `app_form_get(being_draft=true)` -> `app_form_validate` -> `app_form_apply` | 保留完整 `body` 和现有 IDs;不要提交部分字段 patch |
|
|
282
|
+
| 包内新建应用 | `app_form_schema` -> declaration without `appKey` -> `app_form_validate` -> `app_form_apply` | 须含 `packageId`、`spec.appName`、显式 icon/color 和完整 `body` |
|
|
283
|
+
| 多应用系统 | 每个 app 独立走 AppForm;先创建无关系 app,再用已确认 `appKey` 更新关系 | 不使用旧 `apps-file` 批量 schema 路径 |
|
|
284
|
+
| 删除应用 | 显式用户意图 -> `app_delete` | 不通过字段删除 |
|
|
288
285
|
|
|
289
286
|
---
|
|
290
287
|
|
|
@@ -292,9 +289,9 @@ Example patch:
|
|
|
292
289
|
|
|
293
290
|
| 内容 | 位置 |
|
|
294
291
|
|------|------|
|
|
295
|
-
|
|
|
296
|
-
|
|
|
297
|
-
| **`
|
|
292
|
+
| **当前完整系统主示例** | [qingflow-app-form Skill](../../../qingflow-app-form/SKILL.md) |
|
|
293
|
+
| **历史字段类型能力探针(不是新建主模板)** | [schema_apply_add_fields_all_types.json](../examples/schema/schema_apply_add_fields_all_types.json)(仅用于旧字段能力覆盖测试;当前新建和更新统一使用上文 AppForm) |
|
|
294
|
+
| **`q_linker` / `code_block`**(契约内置形状) | `app_form_schema(field_type=...)` 返回的当前 AppForm 类型详情 |
|
|
298
295
|
| 最小新建字段(1 个 text 标题字段) | [schema_add_fields_minimal.example.json](../examples/schema/schema_add_fields_minimal.example.json) |
|
|
299
296
|
| 历史 scalar / complex 批测(可选) | [_batch_schema_scalar.json](../examples/schema/_batch_schema_scalar.json)、[_batch_schema_complex.json](../examples/schema/_batch_schema_complex.json) |
|
|
300
297
|
|
|
@@ -302,11 +299,11 @@ Example patch:
|
|
|
302
299
|
|
|
303
300
|
## 5. 实跑结论
|
|
304
301
|
|
|
305
|
-
|
|
302
|
+
**新建应用**:固定 AppForm schema 版本,使用无 `appKey` 的完整声明创建;字段、分组、行布局和设置统一在 `spec.body` 内表达。字段类型覆盖测试文件只用于能力探针,不作为正式业务应用模板。
|
|
306
303
|
|
|
307
|
-
|
|
304
|
+
**多应用系统**:先创建 relation-independent AppForms,立即记录每个返回的 `appKey`,再用完整 AppForm 更新依赖关系。若写入结果不确定,先读 draft/published form,禁止重放创建、猜名称或使用后缀应用。
|
|
308
305
|
|
|
309
|
-
|
|
306
|
+
**限制(平台硬性)**:relation 字段数量不做“每应用只能一个”的智能体侧限制,按 pinned AppForm Schema、后端校验和写后读回为准。`q_linker` / `code_block` 的配置必须使用当前字段 Schema 返回的 camelCase 形状。
|
|
310
307
|
|
|
311
308
|
**排障**:`--json`;**`DUPLICATE_FIELD`**;真实写入失败看 `SCHEMA_APPLY_FAILED` 的 `backend_code`、`details.relation_field_count` 和读回矩阵。
|
|
312
309
|
|
|
@@ -1,43 +1,52 @@
|
|
|
1
|
-
# Builder Layout
|
|
1
|
+
# Builder Form Layout (AppForm)
|
|
2
2
|
|
|
3
3
|
Read this only when the task is about repairing or changing the form layout of an existing app.
|
|
4
4
|
|
|
5
5
|
## Scope
|
|
6
6
|
|
|
7
|
-
Responsible for:
|
|
7
|
+
Responsible for: AppForm section titles, `rows` matrix, and existing-app layout repair.
|
|
8
8
|
|
|
9
|
-
Not responsible for: creating new apps, adding fields, or complete-system app creation. New apps must put layout directly in `
|
|
9
|
+
Not responsible for: creating new apps, adding fields, or complete-system app creation. New apps must put layout directly in `spec.body` through [30-schema-fields.md](./30-schema-fields.md).
|
|
10
10
|
|
|
11
|
-
Do not read this as
|
|
11
|
+
Do not read this as a standalone CLI write path. For new or existing apps, edit the complete canonical AppForm `body` through the sibling `qingflow-app-form` Skill.
|
|
12
12
|
|
|
13
13
|
## Main chain
|
|
14
14
|
|
|
15
15
|
```text
|
|
16
|
-
|
|
16
|
+
app_form_get(being_draft=true) -> edit spec.body sections/rows -> app_form_validate -> app_form_apply -> readback on recovery
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Demo file
|
|
20
20
|
|
|
21
|
-
Use [layout_sections_full.example.json](../examples/layout/layout_sections_full.example.json) as
|
|
21
|
+
Use [layout_sections_full.example.json](../examples/layout/layout_sections_full.example.json) only as a historical layout probe. For current work, start from `app_form_get(being_draft=true)` and preserve the complete canonical declaration.
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Canonical shape
|
|
24
24
|
|
|
25
|
-
For
|
|
25
|
+
For AppForm layout maintenance, use canonical sections and rows from the pinned AppForm Schema. Each row contains the allowed field objects/IDs for that version. Do not invent top-level `columns`, and do not use portal `x/y/cols/rows` here.
|
|
26
26
|
|
|
27
27
|
```json
|
|
28
28
|
{
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
"apiVersion": "builder.qingflow.com/v1alpha1",
|
|
30
|
+
"appKey": "APP_KEY",
|
|
31
|
+
"spec": {
|
|
32
|
+
"body": [
|
|
33
|
+
{
|
|
34
|
+
"kind": "section",
|
|
35
|
+
"sectionId": "30001",
|
|
36
|
+
"title": "基础信息",
|
|
37
|
+
"rows": [
|
|
38
|
+
{"fields": [
|
|
39
|
+
{"queId": 101, "name": "客户名称", "type": "text", "dataTitle": true},
|
|
40
|
+
{"queId": 102, "name": "订单金额", "type": "amount"}
|
|
41
|
+
]},
|
|
42
|
+
{"fields": [
|
|
43
|
+
{"queId": 103, "name": "状态", "type": "single_select", "config": {"options": ["待处理", "已完成"]}},
|
|
44
|
+
{"queId": 104, "name": "负责人", "type": "member"}
|
|
45
|
+
]}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
41
50
|
}
|
|
42
51
|
```
|
|
43
52
|
|
|
@@ -45,26 +54,25 @@ For existing-app layout maintenance, use section `title + rows`. This is form la
|
|
|
45
54
|
|
|
46
55
|
| Intent | Correct shape | Avoid |
|
|
47
56
|
| --- | --- | --- |
|
|
48
|
-
| Group fields on a form | `
|
|
57
|
+
| Group fields on a form | `spec.body[].title + spec.body[].rows` | Portal `position.pc` / `x` / `y` / `cols` |
|
|
49
58
|
| Put fields on one horizontal form row | `["客户名称", "订单金额"]` inside `rows` | Top-level `columns` |
|
|
50
|
-
| Keep existing layout and add/update groups |
|
|
59
|
+
| Keep existing layout and add/update groups | complete AppForm body preserving existing blocks | partial `mode`/`sections` payloads |
|
|
51
60
|
| Repair missing/unknown field errors | Re-read `app get fields` and remove/correct names | Guessing field ids from old payload |
|
|
52
61
|
|
|
53
62
|
Short rule: **form layout rows arrange fields; portal rows arrange components. Do not mix the two.**
|
|
54
63
|
|
|
55
64
|
## Update existing layout
|
|
56
65
|
|
|
57
|
-
-
|
|
58
|
-
- Re-read `
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- If you are creating apps, stop and use `builder schema apply --apps-file` with `apps[].form` instead.
|
|
66
|
+
- Preserve the complete current AppForm body unless intentionally removing fields or sections.
|
|
67
|
+
- Re-read `app_form_get(being_draft=true)` before writing; every field in rows must be retained with its canonical ID.
|
|
68
|
+
- If apply returns `partial_success` or layout validation details, read the draft and published forms before retrying.
|
|
69
|
+
- There is no current batch layout CLI; update each app's complete AppForm independently.
|
|
62
70
|
|
|
63
71
|
## Common failures
|
|
64
72
|
|
|
65
73
|
| Failure | Action |
|
|
66
74
|
|---------|--------|
|
|
67
|
-
| `UNKNOWN_LAYOUT_FIELD` | Re-read
|
|
68
|
-
| `DUPLICATE_LAYOUT_FIELD` | Keep each field in only one row. |
|
|
69
|
-
| `INCOMPLETE_LAYOUT` |
|
|
70
|
-
| repeated shape errors |
|
|
75
|
+
| `UNKNOWN_LAYOUT_FIELD` | Re-read the pinned AppForm Schema and draft; correct the field pointer. |
|
|
76
|
+
| `DUPLICATE_LAYOUT_FIELD` | Keep each field in only one row in the complete AppForm body. |
|
|
77
|
+
| `INCOMPLETE_LAYOUT` | Rebuild the complete body from the latest draft; do not submit a partial patch. |
|
|
78
|
+
| repeated shape errors | Re-read `app_form_schema` for the pinned version and validate before apply. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Builder Index
|
|
2
2
|
|
|
3
|
-
This directory is for Qingflow system-building work through `qingflow builder ...`.
|
|
3
|
+
This directory is for Qingflow system-building work through `qingflow builder ...`. Form fields, form layout, form settings, and application deletion are owned by the sibling `qingflow-app-form` Skill.
|
|
4
4
|
|
|
5
5
|
## Choose the main path
|
|
6
6
|
|
|
@@ -23,16 +23,16 @@ This directory is for Qingflow system-building work through `qingflow builder ..
|
|
|
23
23
|
## Default build order
|
|
24
24
|
|
|
25
25
|
```text
|
|
26
|
-
package ->
|
|
26
|
+
package -> AppForm per app -> workflow if requested/needed -> views -> portal with chart -> publish/readback verify
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Rules:
|
|
30
30
|
|
|
31
|
-
- Complete systems create
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
31
|
+
- Complete systems create apps through the sibling `qingflow-app-form` Skill, one complete declaration per app, and retain each returned `appKey`.
|
|
32
|
+
- Pin the AppForm schema version and preserve every existing field, section, row, and ID on updates.
|
|
33
|
+
- Create relation-independent apps first; use confirmed target `appKey`s in later complete AppForm declarations.
|
|
34
|
+
- The CLI commands for form work are `builder app-form schema`, `builder app-form get`, `builder app-form validate`, and `builder app-form apply --file`.
|
|
35
|
+
- The old `builder schema apply` and `builder layout apply` routes are retired compatibility adapters, not public commands.
|
|
36
36
|
- Single-app builds use one app path; do not add relation fields unless the user asks for cross-app modeling.
|
|
37
37
|
- Workflow is conditional: build it only when the user asks for approval, fill/copy, reminders, process routing, task handling, or the business process clearly cannot work without it.
|
|
38
38
|
- Portal chart sections use one `chart` field: `{"chart_id":"..."}` to reuse an existing QingBI chart, or `{"app_key":"...","name":"...","chart_type":"...",...}` to create/update the needed chart inline.
|
|
@@ -46,8 +46,8 @@ Rules:
|
|
|
46
46
|
|------|----------------|
|
|
47
47
|
| [10-build-single-app.md](./10-build-single-app.md) | One-app delivery order and completion standard |
|
|
48
48
|
| [20-build-complete-system.md](./20-build-complete-system.md) | Multi-app package delivery order and relation strategy |
|
|
49
|
-
| [30-schema-fields.md](./30-schema-fields.md) | Field
|
|
50
|
-
| [40-layout.md](./40-layout.md) |
|
|
49
|
+
| [30-schema-fields.md](./30-schema-fields.md) | Field modeling notes and AppForm pointer |
|
|
50
|
+
| [40-layout.md](./40-layout.md) | Retired layout-patch pointer; use the AppForm Skill for form layout |
|
|
51
51
|
| [50-views.md](./50-views.md) | Table/card/board/gantt views, filters, query panel, view patches, ordinary view action buttons |
|
|
52
52
|
| [60-charts.md](./60-charts.md) | Standalone QingBI chart maintenance; portal dashboards normally use section `chart` for missing reports |
|
|
53
53
|
| [70-portal.md](./70-portal.md) | Portal apply/delete, standard workbench layout, component config, section `chart` |
|
|
@@ -45,6 +45,8 @@ Current builder support:
|
|
|
45
45
|
- one-step high-level config through `q_linker_binding`
|
|
46
46
|
- internal compilation into existing backend payloads
|
|
47
47
|
|
|
48
|
+
`q_linker_binding` is the compatibility/high-level builder shorthand. In a current AppForm declaration, write the canonical `config.qLinkerBinding` shape returned by the pinned field Schema.
|
|
49
|
+
|
|
48
50
|
## Operating Order
|
|
49
51
|
|
|
50
52
|
For code block or Q-Linker work, use this order:
|
|
@@ -53,8 +55,8 @@ For code block or Q-Linker work, use this order:
|
|
|
53
55
|
- `qingflow builder app resolve`
|
|
54
56
|
- `qingflow builder app get fields`
|
|
55
57
|
2. Confirm the target field set already exists.
|
|
56
|
-
3.
|
|
57
|
-
4. Read
|
|
58
|
+
3. Switch to the sibling `qingflow-app-form` Skill, preserve the complete declaration, validate it, and call `builder app-form apply --file`.
|
|
59
|
+
4. Read the published AppForm again and verify:
|
|
58
60
|
- field type
|
|
59
61
|
- alias config
|
|
60
62
|
- target field binding shape
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
- auto trigger
|
|
10
10
|
- custom button text
|
|
11
11
|
|
|
12
|
+
For current AppForm declarations, use `config.codeBlockBinding` from the pinned field Schema. The snake_case `code_block_binding` name is a compatibility shorthand used by the high-level builder layer.
|
|
13
|
+
|
|
12
14
|
## Stable Writing Rules
|
|
13
15
|
|
|
14
16
|
- Always emit `qf_output = {...}`
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
- auto trigger
|
|
9
9
|
- custom button text
|
|
10
10
|
|
|
11
|
+
For current AppForm declarations, use `config.qLinkerBinding` from the pinned field Schema. The snake_case `q_linker_binding` name is a compatibility shorthand used by the high-level builder layer.
|
|
12
|
+
|
|
11
13
|
## Current Supported Scope
|
|
12
14
|
|
|
13
15
|
- custom mode only
|