@josephyan/qingflow-app-builder-mcp 1.1.25 → 1.1.27
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 +6 -6
- package/docs/local-agent-install.md +6 -57
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-app-builder-mcp.mjs +33 -2
- package/npm/lib/runtime.mjs +101 -21
- package/npm/scripts/postinstall.mjs +10 -1
- package/package.json +2 -3
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +51 -164
- package/skills/qingflow-app-builder/references/build-complete-system.md +234 -0
- package/skills/qingflow-app-builder/references/build-single-app.md +138 -0
- package/skills/qingflow-app-builder/references/create-app.md +24 -31
- package/skills/qingflow-app-builder/references/environments.md +1 -1
- package/skills/qingflow-app-builder/references/gotchas.md +13 -39
- package/skills/qingflow-app-builder/references/match-rules.md +18 -29
- package/skills/qingflow-app-builder/references/public-surface-sync.md +2 -2
- package/skills/qingflow-app-builder/references/solution-playbooks.md +0 -10
- package/skills/qingflow-app-builder/references/tool-selection.md +25 -42
- package/skills/qingflow-app-builder/references/update-flow.md +38 -22
- package/skills/qingflow-app-builder/references/update-schema.md +0 -14
- package/skills/qingflow-app-builder/references/update-views.md +14 -83
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +3 -5
- package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
- package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
- package/skills/qingflow-mcp-setup/SKILL.md +111 -0
- package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
- package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
- package/skills/qingflow-mcp-setup/references/environments.md +61 -0
- package/skills/qingflow-mcp-setup/references/generic-stdio.md +31 -0
- package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
- package/skills/qingflow-workflow-builder/SKILL.md +96 -0
- package/skills/qingflow-workflow-builder/manifest.yaml +8 -0
- package/skills/qingflow-workflow-builder/references/01-overview.md +45 -0
- package/skills/qingflow-workflow-builder/references/02-update-mode.md +53 -0
- package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +57 -0
- package/skills/qingflow-workflow-builder/references/04-stage1-business-modeling.md +131 -0
- package/skills/qingflow-workflow-builder/references/05-stage2-members-roles.md +29 -0
- package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +165 -0
- package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +33 -0
- package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +51 -0
- package/skills/qingflow-workflow-builder/references/09-stage6-summary.md +88 -0
- package/skills/qingflow-workflow-builder/references/10-node-config-reference.md +93 -0
- package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +15 -0
- package/skills/qingflow-workflow-builder/scripts/diff_flow_spec.py +275 -0
- package/skills/qingflow-workflow-builder/scripts/validate_flow_spec.py +605 -0
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/__main__.py +2 -6
- package/src/qingflow_mcp/builder_facade/models.py +49 -330
- package/src/qingflow_mcp/builder_facade/service.py +1621 -6149
- package/src/qingflow_mcp/cli/commands/builder.py +366 -322
- package/src/qingflow_mcp/cli/commands/chart.py +1 -1
- package/src/qingflow_mcp/cli/commands/common.py +3 -12
- package/src/qingflow_mcp/cli/commands/exports.py +2 -2
- package/src/qingflow_mcp/cli/commands/imports.py +3 -3
- package/src/qingflow_mcp/cli/commands/portal.py +2 -2
- package/src/qingflow_mcp/cli/commands/record.py +27 -101
- package/src/qingflow_mcp/cli/commands/task.py +47 -28
- package/src/qingflow_mcp/cli/commands/view.py +1 -1
- package/src/qingflow_mcp/cli/context.py +3 -0
- package/src/qingflow_mcp/cli/formatters.py +16 -784
- package/src/qingflow_mcp/cli/main.py +41 -120
- package/src/qingflow_mcp/errors.py +2 -43
- package/src/qingflow_mcp/public_surface.py +17 -26
- package/src/qingflow_mcp/response_trim.py +17 -81
- package/src/qingflow_mcp/server.py +12 -14
- package/src/qingflow_mcp/server_app_builder.py +39 -81
- package/src/qingflow_mcp/server_app_user.py +16 -22
- package/src/qingflow_mcp/session_store.py +7 -11
- package/src/qingflow_mcp/solution/compiler/__init__.py +1 -3
- package/src/qingflow_mcp/solution/executor.py +18 -245
- package/src/qingflow_mcp/tools/ai_builder_tools.py +1483 -3139
- package/src/qingflow_mcp/tools/app_tools.py +43 -184
- package/src/qingflow_mcp/tools/approval_tools.py +35 -197
- package/src/qingflow_mcp/tools/auth_tools.py +16 -92
- package/src/qingflow_mcp/tools/code_block_tools.py +40 -298
- package/src/qingflow_mcp/tools/custom_button_tools.py +10 -64
- package/src/qingflow_mcp/tools/directory_tools.py +72 -236
- package/src/qingflow_mcp/tools/export_tools.py +34 -244
- package/src/qingflow_mcp/tools/feedback_tools.py +0 -9
- package/src/qingflow_mcp/tools/file_tools.py +3 -9
- package/src/qingflow_mcp/tools/import_tools.py +49 -336
- package/src/qingflow_mcp/tools/navigation_tools.py +12 -91
- package/src/qingflow_mcp/tools/package_tools.py +6 -118
- package/src/qingflow_mcp/tools/portal_tools.py +3 -39
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +7 -116
- package/src/qingflow_mcp/tools/record_tools.py +360 -1145
- package/src/qingflow_mcp/tools/resource_read_tools.py +39 -188
- package/src/qingflow_mcp/tools/role_tools.py +9 -80
- package/src/qingflow_mcp/tools/solution_tools.py +45 -59
- package/src/qingflow_mcp/tools/task_context_tools.py +158 -662
- package/src/qingflow_mcp/tools/task_tools.py +29 -113
- package/src/qingflow_mcp/tools/view_tools.py +3 -106
- package/src/qingflow_mcp/tools/workflow_tools.py +4 -48
- package/src/qingflow_mcp/tools/workspace_tools.py +3 -71
- package/src/qingflow_mcp/version.py +2 -0
- package/npm/bin/qingflow-skills.mjs +0 -5
- package/skills/qingflow-app-builder/references/complete-system-development-guide.md +0 -172
- package/skills/qingflow-app-builder/references/single-app-development-guide.md +0 -87
- package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +0 -124
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +0 -173
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Build Single App
|
|
2
|
+
|
|
3
|
+
Use this when the user asks for one app/form, or gives one `app_key`.
|
|
4
|
+
If the request contains several related business objects, use [build-complete-system.md](./build-complete-system.md).
|
|
5
|
+
|
|
6
|
+
## Main Chain
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
app_resolve / app_get
|
|
10
|
+
-> app_schema_apply(fields + form.sections)
|
|
11
|
+
-> app_views_apply(views[])
|
|
12
|
+
-> workflow only when requested or required
|
|
13
|
+
-> readback/verify
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This is the only recommended chain for a new single app. Do not split layout into a routine second step.
|
|
17
|
+
|
|
18
|
+
## Required Shape
|
|
19
|
+
|
|
20
|
+
- Resolve the target package/app with `app_resolve`, `app_get`, or `package_get`.
|
|
21
|
+
- Create or update business fields with `app_schema_apply`.
|
|
22
|
+
- Put form layout directly in `form.sections` in the schema payload.
|
|
23
|
+
- Exactly one readable top-level field must have `as_data_title: true`.
|
|
24
|
+
- Do not create platform fields: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`.
|
|
25
|
+
- Create at least one business view when the user-facing list/table/card experience matters.
|
|
26
|
+
- If a view needs business actions, put the action configuration directly inside the view item with `action_buttons`.
|
|
27
|
+
|
|
28
|
+
## Schema Payload Pattern
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"package_id": 123,
|
|
33
|
+
"create_if_missing": true,
|
|
34
|
+
"apps": [
|
|
35
|
+
{
|
|
36
|
+
"client_key": "contract",
|
|
37
|
+
"app_name": "合同",
|
|
38
|
+
"icon": "document-text",
|
|
39
|
+
"color": "blue",
|
|
40
|
+
"add_fields": [
|
|
41
|
+
{"name": "合同名称", "type": "text", "required": true, "as_data_title": true},
|
|
42
|
+
{"name": "合同编号", "type": "text"},
|
|
43
|
+
{"name": "合同状态", "type": "select", "options": ["草稿", "审批中", "已生效", "已终止"]},
|
|
44
|
+
{"name": "合同金额", "type": "amount"},
|
|
45
|
+
{"name": "负责人", "type": "member"},
|
|
46
|
+
{"name": "签署日期", "type": "date"},
|
|
47
|
+
{"name": "合同说明", "type": "multiline"},
|
|
48
|
+
{"name": "合同附件", "type": "attachment"}
|
|
49
|
+
],
|
|
50
|
+
"form": {
|
|
51
|
+
"sections": [
|
|
52
|
+
{"title": "基础信息", "rows": [["合同名称", "合同编号"], ["合同状态", "负责人"]]},
|
|
53
|
+
{"title": "金额与时间", "rows": [["合同金额", "签署日期"]]},
|
|
54
|
+
{"title": "补充信息", "rows": [["合同说明"], ["合同附件"]]}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Agent-friendly field type aliases are allowed: `multiline -> long_text`, `select -> single_select`, `amount -> amount`. Readback may show canonical types; do not treat that as a mismatch.
|
|
63
|
+
|
|
64
|
+
## View Payload Pattern
|
|
65
|
+
|
|
66
|
+
- Use `app_views_apply(views=[...])`.
|
|
67
|
+
- Do not create platform default views named `全部数据`, `我的数据`, `我发起的`, `待办`, `已办`, or `抄送`.
|
|
68
|
+
- Use business-specific view names.
|
|
69
|
+
- `filters` are fixed saved filters.
|
|
70
|
+
- `query_conditions` are frontend query panel fields.
|
|
71
|
+
- Put button configuration in `action_buttons`.
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"views": [
|
|
76
|
+
{
|
|
77
|
+
"operation": "upsert",
|
|
78
|
+
"app_key": "APP_KEY",
|
|
79
|
+
"name": "合同执行视图",
|
|
80
|
+
"type": "table",
|
|
81
|
+
"columns": ["合同名称", "合同状态", "合同金额", "负责人", "签署日期"],
|
|
82
|
+
"filters": [
|
|
83
|
+
{"field_name": "合同状态", "operator": "neq", "value": "已终止"}
|
|
84
|
+
],
|
|
85
|
+
"query_conditions": {
|
|
86
|
+
"enabled": true,
|
|
87
|
+
"rows": [["合同名称", "合同状态"], ["负责人", "签署日期"]]
|
|
88
|
+
},
|
|
89
|
+
"action_buttons": [
|
|
90
|
+
{
|
|
91
|
+
"text": "查看合同模板",
|
|
92
|
+
"action": "link",
|
|
93
|
+
"url": "https://example.com/contract-template",
|
|
94
|
+
"placement": "detail"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"operation": "upsert",
|
|
100
|
+
"app_key": "APP_KEY",
|
|
101
|
+
"name": "合同状态看板",
|
|
102
|
+
"type": "board",
|
|
103
|
+
"group_by": "合同状态",
|
|
104
|
+
"columns": ["合同名称", "合同金额", "负责人", "签署日期"],
|
|
105
|
+
"query_conditions": {
|
|
106
|
+
"enabled": true,
|
|
107
|
+
"rows": [["合同名称", "负责人"]]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Workflow
|
|
115
|
+
|
|
116
|
+
Only add workflow when the user asks for approval, fill, copy, reminders, process routing, or task handling.
|
|
117
|
+
|
|
118
|
+
- Create an explicit business status `select` field first, such as `状态`, `处理状态`, `审批状态`, or `流程阶段`.
|
|
119
|
+
- Do not create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
|
|
120
|
+
- If no workflow is requested, report it as not requested/not configured.
|
|
121
|
+
|
|
122
|
+
## Readback And Verification
|
|
123
|
+
|
|
124
|
+
After writing:
|
|
125
|
+
|
|
126
|
+
- read fields and confirm `as_data_title`
|
|
127
|
+
- read layout and confirm important fields are placed
|
|
128
|
+
- read views and confirm business view keys exist
|
|
129
|
+
- verify publish/live status only when required by the user or task
|
|
130
|
+
|
|
131
|
+
If a write returns `partial_success`, `write_executed=true`, or `safe_to_retry=false`, read back before retrying. Retry only verified missing or incorrect slices.
|
|
132
|
+
|
|
133
|
+
## Stop Conditions
|
|
134
|
+
|
|
135
|
+
- If the task actually needs multiple business objects, switch to the complete-system guide.
|
|
136
|
+
- If a same/similar app already exists and the user did not explicitly say update, extend, or create new, stop and ask which target to use.
|
|
137
|
+
- Do not create `V2`, `测试`, timestamp, or random-suffix apps to bypass duplicate names in a real business package.
|
|
138
|
+
- If the same validation error repeats twice, re-read `builder_tool_contract` instead of guessing.
|
|
@@ -6,17 +6,16 @@ This playbook follows the current public builder surface, not legacy package hel
|
|
|
6
6
|
Do not use this playbook when the user is really asking for a system/package with multiple forms or modules. In that case:
|
|
7
7
|
|
|
8
8
|
1. read or create the package through `package_get` / `package_apply`
|
|
9
|
-
2. create
|
|
9
|
+
2. create related apps together with one `app_schema_apply(apps=[...])`
|
|
10
10
|
3. keep package ownership on the public `package_id` path instead of a separate attach step
|
|
11
|
-
4. add
|
|
12
|
-
5. choose explicit non-template `icon + color` for each new package/app
|
|
11
|
+
4. add relation fields between apps
|
|
13
12
|
|
|
14
13
|
Hierarchy reminder:
|
|
15
14
|
|
|
16
15
|
- package -> app -> field -> relation
|
|
17
16
|
- another business object is another app, not a text field
|
|
18
17
|
|
|
19
|
-
If creating a brand new package would help, ask the user to confirm package creation first. After confirmation, create it through `package_apply(package_name
|
|
18
|
+
If creating a brand new package would help, ask the user to confirm package creation first. After confirmation, create it through `package_apply(create_if_missing=true, package_name=...)`.
|
|
20
19
|
|
|
21
20
|
## Minimal sequence
|
|
22
21
|
|
|
@@ -37,25 +36,12 @@ then do not treat that as one app.
|
|
|
37
36
|
|
|
38
37
|
Use this pattern instead:
|
|
39
38
|
|
|
40
|
-
1. `package_get` or `package_apply(package_name
|
|
41
|
-
2. for a multi-app system, run one `app_schema_apply` with `
|
|
39
|
+
1. `package_get` or `package_apply(create_if_missing=true, package_name=...)`
|
|
40
|
+
2. for a multi-app system, run one `app_schema_apply` with `apps[]`
|
|
42
41
|
3. use `apps[].client_key` plus relation field `target_app_ref` when one new app references another new app
|
|
43
42
|
|
|
44
|
-
If that multi-app call times out, returns `partial_success`, returns `write_executed=true`, has `safe_to_retry=false`, or has incomplete readback, do not decide that the create failed. Run `readback_before_retry`: read the package, resolve each intended app by package/name or returned app key, read fields, and retry only verified missing apps or fields. Do not rebuild the same complete system as separate single-app creates, and do not create `V2`, `测试`, timestamp, or random-suffix apps to bypass duplicate names.
|
|
45
|
-
|
|
46
43
|
## Example
|
|
47
44
|
|
|
48
|
-
When designing fields, do not add platform system fields such as `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`. Qingflow provides them automatically; create only business fields.
|
|
49
|
-
|
|
50
|
-
Field authoring rules:
|
|
51
|
-
|
|
52
|
-
- Use intuitive field types in drafts: `text`, `multiline`, `select`, `multi_select`, `number`, `amount`, `date`, `datetime`, `member`, `department`, `attachment`, `relation`.
|
|
53
|
-
- The tool normalizes aliases before writing: `multiline -> long_text`, `select -> single_select`, `checkbox -> multi_select`, `currency -> amount`, `mobile -> phone`. Readback may show canonical types; that is not a failed write.
|
|
54
|
-
- Every new app must have exactly one top-level `as_data_title: true` field. `as_data_cover: true` is optional and only valid on a top-level `attachment`.
|
|
55
|
-
- Select fields must define `options` during schema design. Options may be strings or objects such as `{"label": "进行中"}`; sample data must use those labels or ids.
|
|
56
|
-
- Relation fields must use `target_app_ref` for same-batch apps or `target_app_key` for existing apps, plus object selectors: `display_field: {"name": "..."}` and `visible_fields: [{"name": "..."}]`. Do not write bare strings for display/visible field selectors.
|
|
57
|
-
- Do not impose a one-relation-field-per-app limit. Model the real business links and let backend validation/readback decide.
|
|
58
|
-
|
|
59
45
|
Create a new package only after the user confirms package creation:
|
|
60
46
|
|
|
61
47
|
```json
|
|
@@ -64,8 +50,7 @@ Create a new package only after the user confirms package creation:
|
|
|
64
50
|
"arguments": {
|
|
65
51
|
"profile": "default",
|
|
66
52
|
"package_name": "研发项目管理",
|
|
67
|
-
"
|
|
68
|
-
"color": "azure"
|
|
53
|
+
"create_if_missing": true
|
|
69
54
|
}
|
|
70
55
|
}
|
|
71
56
|
```
|
|
@@ -91,16 +76,21 @@ Apply schema for a new app:
|
|
|
91
76
|
"profile": "default",
|
|
92
77
|
"app_name": "客户订单",
|
|
93
78
|
"package_id": 1218950,
|
|
94
|
-
"
|
|
95
|
-
"color": "emerald",
|
|
79
|
+
"create_if_missing": true,
|
|
96
80
|
"publish": true,
|
|
97
81
|
"add_fields": [
|
|
98
82
|
{"name": "订单编号", "type": "text", "required": true, "as_data_title": true},
|
|
99
83
|
{"name": "客户名称", "type": "text", "required": true},
|
|
100
84
|
{"name": "订单封面", "type": "attachment", "as_data_cover": true},
|
|
101
85
|
{"name": "订单金额", "type": "amount"},
|
|
102
|
-
{"name": "状态", "type": "
|
|
86
|
+
{"name": "状态", "type": "single_select", "options": ["草稿", "进行中", "已完成"], "required": true}
|
|
103
87
|
],
|
|
88
|
+
"form": {
|
|
89
|
+
"sections": [
|
|
90
|
+
{"title": "基础信息", "rows": [["订单编号", "客户名称"], ["状态"]]},
|
|
91
|
+
{"title": "金额与附件", "rows": [["订单金额"], ["订单封面"]]}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
104
94
|
"update_fields": [],
|
|
105
95
|
"remove_fields": []
|
|
106
96
|
}
|
|
@@ -115,22 +105,24 @@ Apply schema for multiple apps in one call:
|
|
|
115
105
|
"arguments": {
|
|
116
106
|
"profile": "default",
|
|
117
107
|
"package_id": 1218950,
|
|
108
|
+
"create_if_missing": true,
|
|
118
109
|
"publish": true,
|
|
119
110
|
"apps": [
|
|
120
111
|
{
|
|
121
112
|
"client_key": "customer",
|
|
122
113
|
"app_name": "客户",
|
|
123
|
-
"icon": "
|
|
124
|
-
"color": "
|
|
114
|
+
"icon": "user-group",
|
|
115
|
+
"color": "blue",
|
|
125
116
|
"add_fields": [
|
|
126
117
|
{"name": "客户名称", "type": "text", "required": true, "as_data_title": true}
|
|
127
|
-
]
|
|
118
|
+
],
|
|
119
|
+
"form": {"sections": [{"title": "基础信息", "rows": [["客户名称"]]}]}
|
|
128
120
|
},
|
|
129
121
|
{
|
|
130
122
|
"client_key": "order",
|
|
131
123
|
"app_name": "订单",
|
|
132
124
|
"icon": "delivery-box-1",
|
|
133
|
-
"color": "
|
|
125
|
+
"color": "green",
|
|
134
126
|
"add_fields": [
|
|
135
127
|
{"name": "订单编号", "type": "text", "required": true, "as_data_title": true},
|
|
136
128
|
{
|
|
@@ -140,7 +132,8 @@ Apply schema for multiple apps in one call:
|
|
|
140
132
|
"display_field": {"name": "客户名称"},
|
|
141
133
|
"visible_fields": [{"name": "客户名称"}]
|
|
142
134
|
}
|
|
143
|
-
]
|
|
135
|
+
],
|
|
136
|
+
"form": {"sections": [{"title": "基础信息", "rows": [["订单编号", "关联客户"]]}]}
|
|
144
137
|
}
|
|
145
138
|
]
|
|
146
139
|
}
|
|
@@ -153,11 +146,11 @@ Data title is required: mark exactly one top-level field with `as_data_title: tr
|
|
|
153
146
|
|
|
154
147
|
### `APP_NOT_FOUND`
|
|
155
148
|
|
|
156
|
-
|
|
149
|
+
Expected on create. Continue with `create_if_missing=true`.
|
|
157
150
|
|
|
158
151
|
### `CREATE_APP_ROUTE_NOT_FOUND`
|
|
159
152
|
|
|
160
|
-
The create route did not resolve in the current backend route context.
|
|
153
|
+
The create route did not resolve in the current backend route context. Re-run `workspace_select`, then retry the same `app_schema_apply`.
|
|
161
154
|
|
|
162
155
|
### Hierarchy modeling mistake
|
|
163
156
|
|
|
@@ -16,7 +16,7 @@ If the user did not specify an environment, default to `prod`.
|
|
|
16
16
|
Use test for:
|
|
17
17
|
|
|
18
18
|
- first application of a new `SolutionSpec`
|
|
19
|
-
- trying
|
|
19
|
+
- trying `solution_build_all(..., verify=true)`
|
|
20
20
|
- package initialization and schema evolution experiments
|
|
21
21
|
- mock data creation, with at least `5` records per relevant entity unless the user asks for fewer
|
|
22
22
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Auth and workspace
|
|
4
4
|
|
|
5
5
|
- `auth_*` success does not mean a workspace is selected
|
|
6
|
-
-
|
|
6
|
+
- Re-run `workspace_select` after auth changes or route changes
|
|
7
7
|
|
|
8
8
|
## Package ownership
|
|
9
9
|
|
|
@@ -17,14 +17,13 @@
|
|
|
17
17
|
- Another app is not a field
|
|
18
18
|
- If the user names multiple forms/modules that relate to each other, create multiple apps and connect them with relation fields
|
|
19
19
|
- Do not use child app names like “项目/需求/任务/缺陷/团队” as plain text fields inside one app
|
|
20
|
-
- For a complete system, the main creation path is one multi-app `app_schema_apply(package_id=..., apps=[...])` with stable `apps[].client_key` values and same-call relation fields using `target_app_ref`
|
|
21
|
-
- Use `target_app_key` only for an app that already exists or has been confirmed by readback
|
|
22
20
|
|
|
23
|
-
##
|
|
21
|
+
## Publish
|
|
24
22
|
|
|
25
|
-
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `
|
|
26
|
-
-
|
|
27
|
-
- `
|
|
23
|
+
- Always pass `publish: true` explicitly on `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, and `portal_apply` — do not rely on the default
|
|
24
|
+
- Pass `publish: false` on those five tools only when the user explicitly wants to leave changes in draft
|
|
25
|
+
- `app_associated_resources_apply` publishes after at least one write succeeds and does not accept a `publish` parameter
|
|
26
|
+
- `app_charts_apply` is immediate-live and has no publish step
|
|
28
27
|
- `app_publish_verify` is for explicit final verification, not the default next step after every write
|
|
29
28
|
|
|
30
29
|
## BI Reports
|
|
@@ -33,29 +32,18 @@
|
|
|
33
32
|
- Use `app_associated_resources_apply` only when an existing BI report or view needs to appear in the Qingflow app associated-resource area or a specific view.
|
|
34
33
|
- `app_charts_apply` currently creates/updates app-source BI reports only (`dataSourceType=qingflow`); dataset BI reports can only be attached when they already exist.
|
|
35
34
|
- Creating a chart with `app_charts_apply` does not automatically show it in the Qingflow app UI; attach it separately if display is required.
|
|
36
|
-
- Main chart config should use semantic `metric`, `metrics`, `group_by`, and `where`; avoid raw `indicator_field_ids`, `selectedMetrics`, and QingBI filter matrices unless diagnosing or preserving existing raw config.
|
|
37
35
|
- `target` and `table` remain compatibility aliases for QingBI `indicator` and `detail`; use the real QingBI chart type when you need a specific type such as `summary`, `columnar`, `stacked_bar`, `scatter`, or `dualaxes`.
|
|
38
|
-
- Use `app_get_fields.chart_fields` as the source for dimensions, metrics, and filters. Record schema fields or normal form fields are not enough for chart apply.
|
|
39
|
-
- Use `target` / `indicator` for one metric card; do not use `summary` for a single KPI.
|
|
40
36
|
|
|
41
|
-
##
|
|
37
|
+
## View actions
|
|
42
38
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
- When changing one existing button parameter, use `patch_buttons` with `set/unset`. Do not send a partial `upsert_buttons` object and expect the backend to preserve hidden required fields.
|
|
46
|
-
- `addData` / `add_data` creates a related/downstream Qingflow record; use current-record `field_mappings` only on `detail` or `list`. `link` only opens a URL. `qRobot`/`wings` require user-provided exact config and must not be invented.
|
|
47
|
-
- For add-data buttons, prefer semantic `trigger_add_data_config.target_app_key`, `field_mappings`, and `default_values`.
|
|
39
|
+
- Put business actions directly in the target view's `action_buttons`.
|
|
40
|
+
- For add-data actions, use semantic `target_app_key`, `field_mappings`, and `default_values`.
|
|
48
41
|
- Do not handwrite raw `que_relation` unless you are preserving an existing backend config. If `field_mappings` and `que_relation` are mixed, the tool blocks the write.
|
|
49
42
|
- `field_mappings.source_field` can use source app fields and supported system fields such as `数据ID` (`field_id=-17`) and `编号` (`field_id=0`).
|
|
50
43
|
- To fill a target relation field with the current source record, map `{"source_field": "数据ID", "target_field": "目标引用字段"}`. Use `default_values` only for static constants.
|
|
51
|
-
- Do not put current-record `field_mappings` on a `header` button; `header` has no current row. Use `detail` or `list` for current-record add-data actions.
|
|
52
|
-
- Do not model approval, rejection, close-task, or status transition as a generic `link` button. Use workflow/task behavior, or `qRobot`/`wings` only when the user provides existing automation config.
|
|
53
44
|
- For field type compatibility, read `references/match-rules.md`.
|
|
54
|
-
-
|
|
55
|
-
- `view_configs[].buttons` is required in merge mode. Do not send a view config with only `view_key`; it is blocked to avoid no-op writes and accidental publish.
|
|
45
|
+
- Default button placements are `header` and `detail`; these map to the frontend's header and detail button areas.
|
|
56
46
|
- Builder view configs use raw `view_key` from `app_get.views[].view_key`; do not prefix it with `custom:`. The `custom:<viewKey>` form is for record-data `view_id`.
|
|
57
|
-
- View button bindings merge by default. Use `view_configs[].mode="replace"` to replace the full set, or pass an explicit empty `buttons: []` when you intend to clear all custom button bindings for that view.
|
|
58
|
-
- Advanced view button bindings can include `button_limit`, `button_formula`, `button_formula_type`, and `print_tpls`, but keep ordinary buttons simple unless the user asks for conditional visibility or print templates.
|
|
59
47
|
- `placement=list` configures row/list buttons. The tool maps it to the backend `INSIDE` button position, not a raw `LIST` config type.
|
|
60
48
|
|
|
61
49
|
## Associated resources
|
|
@@ -76,18 +64,11 @@
|
|
|
76
64
|
|
|
77
65
|
## Partial update discipline
|
|
78
66
|
|
|
79
|
-
- Existing views,
|
|
67
|
+
- Existing views, associated resources, and charts support the same public partial pattern: `patch_*[].set` plus optional `patch_*[].unset`.
|
|
80
68
|
- The backend may still save a full payload. The MCP/CLI patch path is responsible for reading current config and preserving fields the user did not mention.
|
|
81
|
-
- Do not use `upsert_views`, `
|
|
69
|
+
- Do not use `upsert_views`, `upsert_resources`, or `upsert_charts` for a tiny parameter replacement unless you are deliberately providing the full desired target config.
|
|
82
70
|
- `app_layout_apply(mode=merge)` is already a safe layout merge path; `mode=replace` is full layout replacement.
|
|
83
|
-
- `portal_apply` without `sections` is base-info-only. Supplying `sections` replaces the portal sections list
|
|
84
|
-
- PC portal layout is 24-column. Group components by the same `y`: all components in that row must have the same `rows`, and their `cols` should sum to 24 unless the user explicitly wants blank space.
|
|
85
|
-
- Standard workbench heights: metric cards `rows=5`, BI charts `rows=7`, data views `rows=11`.
|
|
86
|
-
- Business-entry `grid` sections must include real `config.items[]`; an empty grid container is not a valid business entrance.
|
|
87
|
-
- Build portals only after referenced apps, raw `view_key`s, and chart ids/keys are known by readback. Intended names are not enough.
|
|
88
|
-
- Use standard order: business entry -> metric cards -> BI charts -> concrete data views.
|
|
89
|
-
- Do not use platform default views such as `全部数据` / `我的数据` as the main portal views.
|
|
90
|
-
- Do not use portal `source_type: "filter"` as the normal automation path; it is raw/unstable and not part of the unified filter DSL.
|
|
71
|
+
- `portal_apply` without `sections` is base-info-only. Supplying `sections` replaces the portal sections list.
|
|
91
72
|
- `app_flow_apply` is intentionally replace-only for the public linear workflow graph.
|
|
92
73
|
|
|
93
74
|
## Workflow dependencies
|
|
@@ -104,16 +85,9 @@
|
|
|
104
85
|
## Retry discipline
|
|
105
86
|
|
|
106
87
|
- If a write returns `partial_success`, read back before retrying
|
|
107
|
-
- If multi-app schema apply times out, returns `write_executed=true`, returns `safe_to_retry=false`, or has incomplete readback, treat it as `write_may_have_succeeded`; the next action is `readback_before_retry`
|
|
108
|
-
- `readback_before_retry` means read package/app/fields first, classify which intended apps and relation fields actually exist, and retry only the verified missing slice
|
|
109
88
|
- Do not repeat create steps after `app_key` already exists
|
|
110
|
-
- Do not split a complete-system schema create into single-app rebuilds until readback proves exactly what is missing
|
|
111
|
-
- Do not bypass duplicate/conflict states by inventing `V2`, `测试`, timestamp, or random-suffix app names in a real business package
|
|
112
89
|
- For backend rejects, keep the retry narrow: retry only the failed tool, not the whole chain
|
|
113
90
|
- For `VALIDATION_ERROR`, do not keep guessing. Reuse `suggested_next_call`, `canonical_arguments`, `allowed_keys`, and `allowed_values` first.
|
|
114
|
-
- For `builder_tool_contract`, read the returned `json_paths` first. Successful contract data is under `$.contract`; `allowed_values` uses flat dotted keys such as `["field.type"]`, not nested objects. Do not read successful field enums from top-level `allowed_values`.
|
|
115
|
-
- For `workspace_icon_catalog_get`, read icon candidates from `$.icon_names` and colors from `$.icon_colors`.
|
|
116
|
-
- For builder apply responses, read returned `json_paths` first. Stable fields are `$.summary` and `$.resources[]`; use `resources[].id/key/name` before legacy top-level fields.
|
|
117
91
|
- For layout `VALIDATION_ERROR`, also inspect `section_allowed_keys`, `section_aliases`, and `minimal_section_example`. If the same layout-shape error repeats twice, stop free-form retries and re-read `builder_tool_contract(app_layout_apply)`.
|
|
118
92
|
- For flow work, do not replay internal keys from old logs or plan outputs. Public builder calls should stay on:
|
|
119
93
|
- `assignees.role_ids` / `assignees.member_uids` / `assignees.member_emails`
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
# Builder Match Rules
|
|
2
2
|
|
|
3
|
-
Use this reference for builder-side field matching rules in
|
|
3
|
+
Use this reference for builder-side field matching rules in view actions and associated view/report filters.
|
|
4
4
|
|
|
5
5
|
This is not the same thing as `record_access` analysis filters or normal view `filters`.
|
|
6
6
|
|
|
7
|
-
Unified public semantics:
|
|
8
|
-
|
|
9
|
-
- Fixed filters use `field_name + operator + value/values`, for example view `filters` and chart `filters`.
|
|
10
|
-
- Current-record context matches use `target_field + operator + source_field/value`, for example associated resource `match_mappings` and add-data button mappings.
|
|
11
|
-
- Do not handwrite `judgeType`, `judgeValues`, or `matchRules`; the CLI compiles them for the target backend protocol.
|
|
12
|
-
|
|
13
7
|
## Where These Rules Apply
|
|
14
8
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
9
|
+
- `app_views_apply.views[].action_buttons[].field_mappings`
|
|
10
|
+
- `app_views_apply.patch_views[].set.action_buttons[].field_mappings`
|
|
17
11
|
- `app_associated_resources_apply.upsert_resources[].match_mappings`
|
|
18
12
|
- `app_associated_resources_apply.patch_resources[].set.match_mappings`
|
|
19
13
|
|
|
@@ -30,7 +24,7 @@ System fields can participate in mappings:
|
|
|
30
24
|
|
|
31
25
|
Explicit selectors such as `{"field_id": -17}` and `{"field_id": 0}` are allowed and remove ambiguity.
|
|
32
26
|
|
|
33
|
-
##
|
|
27
|
+
## View Actions
|
|
34
28
|
|
|
35
29
|
Use `field_mappings` for dynamic values copied from the current source record:
|
|
36
30
|
|
|
@@ -49,21 +43,25 @@ Use `field_mappings` for dynamic values copied from the current source record:
|
|
|
49
43
|
|
|
50
44
|
Use `default_values` only for static constants. Do not use `default_values` as the preferred way to pass the current record.
|
|
51
45
|
|
|
52
|
-
For an existing
|
|
46
|
+
For an existing view, patch the view's action list through `patch_views[].set.action_buttons`:
|
|
53
47
|
|
|
54
48
|
```json
|
|
55
49
|
{
|
|
56
|
-
"
|
|
50
|
+
"view_key": "VIEW_KEY",
|
|
57
51
|
"set": {
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
"action_buttons": [
|
|
53
|
+
{
|
|
54
|
+
"text": "新建工时",
|
|
55
|
+
"action": "add_data",
|
|
56
|
+
"target_app_key": "WORKLOG_APP",
|
|
57
|
+
"field_mappings": [
|
|
58
|
+
{"source_field": "数据ID", "target_field": "关联员工"}
|
|
59
|
+
],
|
|
60
|
+
"default_values": {
|
|
61
|
+
"状态": "待提交"
|
|
62
|
+
}
|
|
65
63
|
}
|
|
66
|
-
|
|
64
|
+
]
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
```
|
|
@@ -86,15 +84,6 @@ Use `match_mappings` for associated view/report filters:
|
|
|
86
84
|
|
|
87
85
|
Dynamic conditions use `source_field`; static conditions use `value`.
|
|
88
86
|
|
|
89
|
-
Recommended operators are `eq`, `neq`, `in`, `contains`, `gte`, `lte`, `is_empty`, and `not_empty`; aliases such as `equal`, `equals`, `=`, `!=`, `any_of`, `one_of`, and `empty` are accepted. `field_name` and `field` can be used as aliases for `target_field`. Static single-value filters should use `value`; a single-item `values` array is also accepted.
|
|
90
|
-
|
|
91
|
-
Examples:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{"target_field": "客户ID", "operator": "eq", "source_field": "数据ID"}
|
|
95
|
-
{"target_field": "状态", "operator": "eq", "value": "有效"}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
87
|
For an existing associated resource, put the same filter mapping under `patch_resources[].set`:
|
|
99
88
|
|
|
100
89
|
```json
|
|
@@ -39,14 +39,14 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
39
39
|
- `app_layout_apply`
|
|
40
40
|
- `app_flow_apply`
|
|
41
41
|
- `app_views_apply`
|
|
42
|
-
- `app_custom_buttons_apply`
|
|
43
42
|
- `app_associated_resources_apply`
|
|
44
43
|
- `app_charts_apply`
|
|
45
44
|
- `portal_apply`
|
|
46
45
|
- `app_publish_verify`
|
|
47
46
|
- `portal_apply` edit mode may omit `sections` for base-info-only updates
|
|
48
47
|
- `app_charts_apply.visibility` is a public capability and should be treated as a base-only visibility update
|
|
49
|
-
-
|
|
48
|
+
- View actions are declared through `app_views_apply` `action_buttons`
|
|
49
|
+
- Existing object parameter replacement should use `patch_views`, `patch_resources`, and `patch_charts`; `upsert_*` is for creation or full target config
|
|
50
50
|
- `app_get.editability` uses:
|
|
51
51
|
- `can_edit_app_base`
|
|
52
52
|
- `can_edit_form`
|
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Use these when you need a quick reminder of the standard v2 builder sequences.
|
|
4
4
|
|
|
5
|
-
## Create a complete system / app package
|
|
6
|
-
|
|
7
|
-
1. `package_get` or `package_apply`
|
|
8
|
-
2. one multi-app `app_schema_apply(package_id=..., apps=[...])`
|
|
9
|
-
3. use stable `apps[].client_key` values and relation `target_app_ref` for same-call app references
|
|
10
|
-
4. use returned/readback `app_key` values for layout, views, workflow, charts, buttons, associated resources, and portal work
|
|
11
|
-
5. `app_publish_verify` only when the user asks for explicit live verification or a final verification pass is required
|
|
12
|
-
|
|
13
|
-
If the multi-app schema write times out or returns `partial_success`, `write_executed=true`, `safe_to_retry=false`, or incomplete readback, the next action is `readback_before_retry`: read package/app/fields first, then retry only verified missing pieces. Do not repeat the whole apps payload, split into single-app rebuilds, or create `V2` / `测试` / random-suffix apps to dodge duplicate names.
|
|
14
|
-
|
|
15
5
|
## Create a new app in an existing package
|
|
16
6
|
|
|
17
7
|
1. `package_get`
|