@josephyan/qingflow-app-builder-mcp 1.1.3 → 1.1.5
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 -5
- package/docs/local-agent-install.md +57 -6
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-app-builder-mcp.mjs +2 -33
- package/npm/bin/qingflow-skills.mjs +5 -0
- package/npm/lib/runtime.mjs +21 -101
- package/npm/scripts/postinstall.mjs +1 -10
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +51 -34
- package/skills/qingflow-app-builder/references/complete-system-development-guide.md +123 -0
- package/skills/qingflow-app-builder/references/create-app.md +19 -6
- package/skills/qingflow-app-builder/references/environments.md +1 -1
- package/skills/qingflow-app-builder/references/gotchas.md +14 -6
- package/skills/qingflow-app-builder/references/match-rules.md +15 -0
- package/skills/qingflow-app-builder/references/single-app-development-guide.md +58 -0
- package/skills/qingflow-app-builder/references/solution-playbooks.md +10 -0
- package/skills/qingflow-app-builder/references/tool-selection.md +21 -22
- package/skills/qingflow-app-builder/references/update-flow.md +22 -38
- package/skills/qingflow-app-builder/references/update-schema.md +3 -0
- package/skills/qingflow-app-builder/references/update-views.md +34 -14
- package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +124 -0
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +5 -3
- 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/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/__main__.py +6 -2
- package/src/qingflow_mcp/builder_facade/models.py +287 -25
- package/src/qingflow_mcp/builder_facade/service.py +4195 -856
- package/src/qingflow_mcp/cli/commands/builder.py +316 -247
- package/src/qingflow_mcp/cli/commands/chart.py +1 -1
- package/src/qingflow_mcp/cli/commands/common.py +12 -3
- 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 +101 -27
- package/src/qingflow_mcp/cli/commands/task.py +28 -47
- package/src/qingflow_mcp/cli/commands/view.py +1 -1
- package/src/qingflow_mcp/cli/context.py +0 -3
- package/src/qingflow_mcp/cli/formatters.py +784 -16
- package/src/qingflow_mcp/cli/main.py +117 -33
- package/src/qingflow_mcp/errors.py +43 -2
- package/src/qingflow_mcp/public_surface.py +26 -17
- package/src/qingflow_mcp/response_trim.py +81 -17
- package/src/qingflow_mcp/server.py +14 -12
- package/src/qingflow_mcp/server_app_builder.py +65 -21
- package/src/qingflow_mcp/server_app_user.py +22 -16
- package/src/qingflow_mcp/session_store.py +11 -7
- package/src/qingflow_mcp/solution/compiler/__init__.py +3 -1
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
- package/src/qingflow_mcp/solution/executor.py +245 -18
- package/src/qingflow_mcp/tools/ai_builder_tools.py +1782 -399
- package/src/qingflow_mcp/tools/app_tools.py +184 -43
- package/src/qingflow_mcp/tools/approval_tools.py +197 -35
- package/src/qingflow_mcp/tools/auth_tools.py +92 -16
- package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
- package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
- package/src/qingflow_mcp/tools/directory_tools.py +236 -72
- package/src/qingflow_mcp/tools/export_tools.py +244 -34
- package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
- package/src/qingflow_mcp/tools/file_tools.py +9 -3
- package/src/qingflow_mcp/tools/import_tools.py +336 -49
- package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
- package/src/qingflow_mcp/tools/package_tools.py +118 -6
- package/src/qingflow_mcp/tools/portal_tools.py +39 -3
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
- package/src/qingflow_mcp/tools/record_tools.py +1141 -356
- package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
- package/src/qingflow_mcp/tools/role_tools.py +80 -9
- package/src/qingflow_mcp/tools/solution_tools.py +59 -45
- package/src/qingflow_mcp/tools/task_context_tools.py +662 -158
- package/src/qingflow_mcp/tools/task_tools.py +113 -29
- package/src/qingflow_mcp/tools/view_tools.py +106 -3
- package/src/qingflow_mcp/tools/workflow_tools.py +48 -4
- package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
- package/skills/qingflow-app-builder/references/build-complete-system.md +0 -428
- package/skills/qingflow-app-builder/references/build-single-app.md +0 -530
- package/skills/qingflow-mcp-setup/SKILL.md +0 -111
- package/skills/qingflow-mcp-setup/agents/openai.yaml +0 -4
- package/skills/qingflow-mcp-setup/references/claude-desktop.md +0 -34
- package/skills/qingflow-mcp-setup/references/environments.md +0 -61
- package/skills/qingflow-mcp-setup/references/generic-stdio.md +0 -31
- package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +0 -38
- package/skills/qingflow-workflow-builder/SKILL.md +0 -96
- package/skills/qingflow-workflow-builder/manifest.yaml +0 -8
- package/skills/qingflow-workflow-builder/references/01-overview.md +0 -45
- package/skills/qingflow-workflow-builder/references/02-update-mode.md +0 -53
- package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +0 -57
- package/skills/qingflow-workflow-builder/references/04-stage1-business-modeling.md +0 -131
- package/skills/qingflow-workflow-builder/references/05-stage2-members-roles.md +0 -29
- package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +0 -165
- package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +0 -33
- package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +0 -51
- package/skills/qingflow-workflow-builder/references/09-stage6-summary.md +0 -88
- package/skills/qingflow-workflow-builder/references/10-node-config-reference.md +0 -93
- package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +0 -15
- package/skills/qingflow-workflow-builder/scripts/diff_flow_spec.py +0 -275
- package/skills/qingflow-workflow-builder/scripts/validate_flow_spec.py +0 -605
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Complete System Development Guide
|
|
2
|
+
|
|
3
|
+
Use this when the user asks for a system, app package, workspace module set, or several related apps/forms.
|
|
4
|
+
Do not compress several business objects into one app.
|
|
5
|
+
|
|
6
|
+
## Recommended Completeness
|
|
7
|
+
|
|
8
|
+
Required:
|
|
9
|
+
|
|
10
|
+
- package exists or is created through `package_apply`
|
|
11
|
+
- core business objects are modeled as separate apps
|
|
12
|
+
- all new apps are created in one multi-app `app_schema_apply(package_id=..., apps=[...])`
|
|
13
|
+
- every app has stable `client_key`, `app_name`, `icon`, `color`, and one readable `as_data_title: true`
|
|
14
|
+
- no app creates platform system fields such as `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`
|
|
15
|
+
- same-call relations use `target_app_ref` to point to another `apps[].client_key`
|
|
16
|
+
- basic operating views exist for each core app
|
|
17
|
+
- package/apps/fields/relations are read back before repair or retry
|
|
18
|
+
|
|
19
|
+
Strongly recommended:
|
|
20
|
+
|
|
21
|
+
- cross-app relation fields for the main business links
|
|
22
|
+
- core metric charts and BI charts using semantic `metric`, `metrics`, `group_by`, and `where`
|
|
23
|
+
- a standard portal: business entry area, core metrics, BI charts, then concrete data views
|
|
24
|
+
- portal grid/business-entry sections contain real `config.items[]`, not empty containers
|
|
25
|
+
|
|
26
|
+
Workflow preflight:
|
|
27
|
+
|
|
28
|
+
- If an app will have approval/fill/copy workflow nodes, create an explicit business status `select` field in schema first, such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`.
|
|
29
|
+
- Do not create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
|
|
30
|
+
- If `app_flow_apply` returns `FLOW_DEPENDENCY_MISSING`, fix schema with the returned `suggested_next_call`, read fields back, then retry the flow. Do not skip the workflow silently.
|
|
31
|
+
|
|
32
|
+
Optional:
|
|
33
|
+
|
|
34
|
+
- workflow, reminders, buttons, associated resources, sample data, roles, and permissions when the user asks for them or the business process clearly depends on them
|
|
35
|
+
|
|
36
|
+
## Standard Path
|
|
37
|
+
|
|
38
|
+
1. Resolve or create package: `package_get` / `package_apply`.
|
|
39
|
+
2. Draft all apps and relations with stable `client_key` values.
|
|
40
|
+
3. Run one multi-app `app_schema_apply` with `apps[]`.
|
|
41
|
+
4. If write result is uncertain, run readback before retrying.
|
|
42
|
+
5. For each app, apply layout and views.
|
|
43
|
+
6. Create charts before portals when the portal needs metrics or BI sections. Submit chart upserts in batches of 4-8; if `CHART_UPSERT_BATCH_TOO_LARGE` appears, execute `details.suggested_batch_payloads[]` one at a time.
|
|
44
|
+
7. Create portal only after referenced apps, views, and charts are known.
|
|
45
|
+
8. Add workflows/buttons/associated resources when they are part of the requested business process.
|
|
46
|
+
9. Before the final response, write the complete-system delivery summary file described below.
|
|
47
|
+
|
|
48
|
+
## Field Modeling Rules
|
|
49
|
+
|
|
50
|
+
- Use agent-friendly field types in drafts: `text`, `multiline`, `select`, `multi_select`, `number`, `amount`, `date`, `datetime`, `member`, `department`, `attachment`, `relation`. The tool normalizes aliases such as `multiline -> long_text` and `select -> single_select`.
|
|
51
|
+
- Create only business fields. Do not create platform system fields listed in Required; reference them only where a tool explicitly supports system fields, such as button `source_field: "数据ID"`.
|
|
52
|
+
- Use `number` for ratios, completion rates, scores, percentages, durations, and quantities that may need decimals. Use `amount` only for currency/money semantics. This prevents sample data from producing decimal values for a field that the backend treats as integer money.
|
|
53
|
+
- For select fields, define the option set during schema design. Later sample data must use only those option labels or ids.
|
|
54
|
+
|
|
55
|
+
## View Query Rules
|
|
56
|
+
|
|
57
|
+
- Use `filters` for fixed saved filters that apply when the view opens.
|
|
58
|
+
- Use `query_conditions` only for the frontend query panel layout. It is not another filter DSL and it does not express OR.
|
|
59
|
+
- `query_conditions.rows` should contain query-panel fields such as text, long text, number, amount, date/datetime, select, member, department, phone, email, or boolean.
|
|
60
|
+
- Do not put relation, attachment, subtable/subfield, address, Q-Linker, or code-block fields in `query_conditions`.
|
|
61
|
+
- For current-record related views/reports, use `app_associated_resources_apply.match_mappings`, not `query_conditions`.
|
|
62
|
+
|
|
63
|
+
## Delivery Summary File
|
|
64
|
+
|
|
65
|
+
For complete-system builds, create or update one local JSON file before the final response:
|
|
66
|
+
|
|
67
|
+
`tmp/qingflow_system_build_summary.json`
|
|
68
|
+
|
|
69
|
+
Use this file as the structured source of truth for the final report. Include at least:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"package_id": 0,
|
|
74
|
+
"package_name": "",
|
|
75
|
+
"portal_dash_key": "",
|
|
76
|
+
"portal_live_status": "verified | unverified | not_created",
|
|
77
|
+
"front_end_visible": true,
|
|
78
|
+
"apps": [
|
|
79
|
+
{
|
|
80
|
+
"app_key": "",
|
|
81
|
+
"app_name": "",
|
|
82
|
+
"fields_count": 0,
|
|
83
|
+
"views_count": 0,
|
|
84
|
+
"flows_count": 0,
|
|
85
|
+
"charts_count": 0,
|
|
86
|
+
"publish_verify_status": "verified | unverified | failed"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"warnings": [],
|
|
90
|
+
"partial_items": [],
|
|
91
|
+
"needs_followup": []
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Rules:
|
|
96
|
+
|
|
97
|
+
- Populate IDs and counts from readback, not from intended payload only.
|
|
98
|
+
- If a required resource is not verified, put it in `partial_items` or `needs_followup` instead of reporting the system as fully complete.
|
|
99
|
+
- If the user later adds a data-entry task, keep that separate from the system-build summary unless the user explicitly wants one combined report.
|
|
100
|
+
- The final response should match this file: completed resources, unverified items, frontend visibility, and follow-up needs must not contradict the JSON.
|
|
101
|
+
- When running from the CLI repo or a test harness, validate the file with:
|
|
102
|
+
`python scripts/validate_system_build_summary.py tmp/qingflow_system_build_summary.json`.
|
|
103
|
+
|
|
104
|
+
## Recovery Rules
|
|
105
|
+
|
|
106
|
+
- Timeout, `partial_success`, `write_executed=true`, `safe_to_retry=false`, or incomplete readback means `write_may_have_succeeded`.
|
|
107
|
+
- Next action is always `readback_before_retry`: read package, resolve intended apps, then read fields/relations.
|
|
108
|
+
- Retry only verified missing apps, fields, or relations.
|
|
109
|
+
- Do not rebuild the system as separate single-app creates.
|
|
110
|
+
- Do not create `V2`, `测试`, timestamp, or random-suffix apps to bypass duplicate names.
|
|
111
|
+
|
|
112
|
+
## Portal Template
|
|
113
|
+
|
|
114
|
+
- Top area: one business entry grid plus one todo/common/frequent component when useful.
|
|
115
|
+
- Metrics: one row of 4-6 indicator/target cards with portal section `role: "metric"`; recommended height 5.
|
|
116
|
+
- BI charts: one row of 2-3 charts, 1-2 rows; recommended height 7.
|
|
117
|
+
- Data views: one row of 1-2 concrete views, 1-2 rows; recommended height 11.
|
|
118
|
+
|
|
119
|
+
## Stop Conditions
|
|
120
|
+
|
|
121
|
+
- If the user only asked for one app, switch to the single-app guide.
|
|
122
|
+
- If required package/app/field/relation readback contradicts the intended model, repair the specific missing slice before building dependent resources.
|
|
123
|
+
- If a public tool cannot express a needed business feature, state the gap and ask before using any fallback or submitting feedback.
|
|
@@ -6,9 +6,10 @@ 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 the related apps in one `app_schema_apply(package_id=..., apps=[...])` call
|
|
10
10
|
3. keep package ownership on the public `package_id` path instead of a separate attach step
|
|
11
|
-
4. add relation fields
|
|
11
|
+
4. add same-call relation fields with `target_app_ref` when one new app references another new app; use `target_app_key` only after the target app already exists or readback confirms it
|
|
12
|
+
5. choose explicit non-template `icon + color` for each new package/app
|
|
12
13
|
|
|
13
14
|
Hierarchy reminder:
|
|
14
15
|
|
|
@@ -37,11 +38,15 @@ then do not treat that as one app.
|
|
|
37
38
|
Use this pattern instead:
|
|
38
39
|
|
|
39
40
|
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[]`
|
|
41
|
+
2. for a multi-app system, run one `app_schema_apply` with `package_id` and `apps[]`
|
|
41
42
|
3. use `apps[].client_key` plus relation field `target_app_ref` when one new app references another new app
|
|
42
43
|
|
|
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
|
+
|
|
43
46
|
## Example
|
|
44
47
|
|
|
48
|
+
When designing fields, do not add platform system fields such as `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`. Qingflow provides them automatically; create only business fields.
|
|
49
|
+
|
|
45
50
|
Create a new package only after the user confirms package creation:
|
|
46
51
|
|
|
47
52
|
```json
|
|
@@ -50,7 +55,9 @@ Create a new package only after the user confirms package creation:
|
|
|
50
55
|
"arguments": {
|
|
51
56
|
"profile": "default",
|
|
52
57
|
"package_name": "研发项目管理",
|
|
53
|
-
"create_if_missing": true
|
|
58
|
+
"create_if_missing": true,
|
|
59
|
+
"icon": "briefcase",
|
|
60
|
+
"color": "azure"
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
```
|
|
@@ -76,6 +83,8 @@ Apply schema for a new app:
|
|
|
76
83
|
"profile": "default",
|
|
77
84
|
"app_name": "客户订单",
|
|
78
85
|
"package_id": 1218950,
|
|
86
|
+
"icon": "delivery-box-1",
|
|
87
|
+
"color": "emerald",
|
|
79
88
|
"create_if_missing": true,
|
|
80
89
|
"publish": true,
|
|
81
90
|
"add_fields": [
|
|
@@ -83,7 +92,7 @@ Apply schema for a new app:
|
|
|
83
92
|
{"name": "客户名称", "type": "text", "required": true},
|
|
84
93
|
{"name": "订单封面", "type": "attachment", "as_data_cover": true},
|
|
85
94
|
{"name": "订单金额", "type": "amount"},
|
|
86
|
-
{"name": "状态", "type": "single_select", "options": ["草稿", "进行中", "已完成"], "required": true}
|
|
95
|
+
{"name": "状态", "type": "single_select", "options": [{"label": "草稿"}, {"label": "进行中"}, {"label": "已完成"}], "required": true}
|
|
87
96
|
],
|
|
88
97
|
"update_fields": [],
|
|
89
98
|
"remove_fields": []
|
|
@@ -105,6 +114,8 @@ Apply schema for multiple apps in one call:
|
|
|
105
114
|
{
|
|
106
115
|
"client_key": "customer",
|
|
107
116
|
"app_name": "客户",
|
|
117
|
+
"icon": "business-personalcard",
|
|
118
|
+
"color": "emerald",
|
|
108
119
|
"add_fields": [
|
|
109
120
|
{"name": "客户名称", "type": "text", "required": true, "as_data_title": true}
|
|
110
121
|
]
|
|
@@ -112,6 +123,8 @@ Apply schema for multiple apps in one call:
|
|
|
112
123
|
{
|
|
113
124
|
"client_key": "order",
|
|
114
125
|
"app_name": "订单",
|
|
126
|
+
"icon": "delivery-box-1",
|
|
127
|
+
"color": "blue",
|
|
115
128
|
"add_fields": [
|
|
116
129
|
{"name": "订单编号", "type": "text", "required": true, "as_data_title": true},
|
|
117
130
|
{
|
|
@@ -138,7 +151,7 @@ Expected on create. Continue with `create_if_missing=true`.
|
|
|
138
151
|
|
|
139
152
|
### `CREATE_APP_ROUTE_NOT_FOUND`
|
|
140
153
|
|
|
141
|
-
The create route did not resolve in the current backend route context.
|
|
154
|
+
The create route did not resolve in the current backend route context. In Wingent Momo runtime, first retry the same `app_schema_apply` after confirming the injected session is still active. Only run `workspace_select` if a business tool explicitly reports a missing or wrong workspace.
|
|
142
155
|
|
|
143
156
|
### Hierarchy modeling mistake
|
|
144
157
|
|
|
@@ -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 builder apply flows end-to-end with readback verification, or `solution_install` when the user is installing an existing packaged solution
|
|
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
|
+
- In Wingent Momo runtime, do not run `workspace_select` before builder work. Re-run it only after an explicit auth/route recovery or when a business tool reports the workspace is missing.
|
|
7
7
|
|
|
8
8
|
## Package ownership
|
|
9
9
|
|
|
@@ -17,13 +17,14 @@
|
|
|
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
|
|
20
22
|
|
|
21
|
-
##
|
|
23
|
+
## Auto publish
|
|
22
24
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept
|
|
26
|
-
- `app_charts_apply` is immediate-live and has no publish step
|
|
25
|
+
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default
|
|
26
|
+
- For those four tools, pass `publish=false` only when the user explicitly wants to leave changes in draft
|
|
27
|
+
- `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept `publish=false`
|
|
27
28
|
- `app_publish_verify` is for explicit final verification, not the default next step after every write
|
|
28
29
|
|
|
29
30
|
## BI Reports
|
|
@@ -89,9 +90,16 @@
|
|
|
89
90
|
## Retry discipline
|
|
90
91
|
|
|
91
92
|
- If a write returns `partial_success`, read back before retrying
|
|
93
|
+
- 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`
|
|
94
|
+
- `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
|
|
92
95
|
- Do not repeat create steps after `app_key` already exists
|
|
96
|
+
- Do not split a complete-system schema create into single-app rebuilds until readback proves exactly what is missing
|
|
97
|
+
- Do not bypass duplicate/conflict states by inventing `V2`, `测试`, timestamp, or random-suffix app names in a real business package
|
|
93
98
|
- For backend rejects, keep the retry narrow: retry only the failed tool, not the whole chain
|
|
94
99
|
- For `VALIDATION_ERROR`, do not keep guessing. Reuse `suggested_next_call`, `canonical_arguments`, `allowed_keys`, and `allowed_values` first.
|
|
100
|
+
- 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`.
|
|
101
|
+
- For `workspace_icon_catalog_get`, read icon candidates from `$.icon_names` and colors from `$.icon_colors`.
|
|
102
|
+
- 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.
|
|
95
103
|
- 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)`.
|
|
96
104
|
- For flow work, do not replay internal keys from old logs or plan outputs. Public builder calls should stay on:
|
|
97
105
|
- `assignees.role_ids` / `assignees.member_uids` / `assignees.member_emails`
|
|
@@ -4,6 +4,12 @@ Use this reference for builder-side field matching rules in custom buttons and a
|
|
|
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
|
+
|
|
7
13
|
## Where These Rules Apply
|
|
8
14
|
|
|
9
15
|
- `app_custom_buttons_apply.upsert_buttons[].trigger_add_data_config.field_mappings`
|
|
@@ -80,6 +86,15 @@ Use `match_mappings` for associated view/report filters:
|
|
|
80
86
|
|
|
81
87
|
Dynamic conditions use `source_field`; static conditions use `value`.
|
|
82
88
|
|
|
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
|
+
|
|
83
98
|
For an existing associated resource, put the same filter mapping under `patch_resources[].set`:
|
|
84
99
|
|
|
85
100
|
```json
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Single App Development Guide
|
|
2
|
+
|
|
3
|
+
Use this when the user asks for one app/form, or gives one `app_key`.
|
|
4
|
+
If the user asks for a package, system, or several related modules, use `complete-system-development-guide.md` instead.
|
|
5
|
+
|
|
6
|
+
## Recommended Completeness
|
|
7
|
+
|
|
8
|
+
Required:
|
|
9
|
+
|
|
10
|
+
- target package/app resolved by `package_get`, `app_resolve`, or `app_get`
|
|
11
|
+
- business fields created or updated through `app_schema_apply`
|
|
12
|
+
- exactly one readable top-level `as_data_title: true`
|
|
13
|
+
- no platform system fields in `add_fields`
|
|
14
|
+
- layout places the important fields
|
|
15
|
+
- at least one business view beyond platform default views when the task includes user-facing list work
|
|
16
|
+
|
|
17
|
+
Strongly recommended:
|
|
18
|
+
|
|
19
|
+
- saved filters and query panel fields for the main operating views
|
|
20
|
+
- simple charts when the app has status, amount, date, or owner fields worth tracking
|
|
21
|
+
- associated resources or buttons only when they support a concrete workflow
|
|
22
|
+
|
|
23
|
+
Optional:
|
|
24
|
+
|
|
25
|
+
- workflow, portal entry, sample data, roles, or visibility changes when requested by the user or clearly needed by the app's job
|
|
26
|
+
|
|
27
|
+
Workflow preflight:
|
|
28
|
+
|
|
29
|
+
- If the app will have approval/fill/copy workflow nodes, add one explicit business status `select` field first, such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`.
|
|
30
|
+
- Do not create platform workflow system fields: `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
|
|
31
|
+
|
|
32
|
+
## Standard Path
|
|
33
|
+
|
|
34
|
+
1. Read current target: `app_resolve` or `app_get`.
|
|
35
|
+
2. Read current fields: `app_get_fields`.
|
|
36
|
+
3. Apply fields with `app_schema_apply`.
|
|
37
|
+
4. Apply layout with `app_layout_apply`.
|
|
38
|
+
5. Apply views with `app_views_apply` when list/table/card/gantt behavior is part of the request.
|
|
39
|
+
6. Apply charts/buttons/associated resources only if they are part of the app's actual workflow.
|
|
40
|
+
7. Use `app_publish_verify` only when explicit live verification is required.
|
|
41
|
+
|
|
42
|
+
## Field Rules
|
|
43
|
+
|
|
44
|
+
- Use agent-friendly field types where possible: `text`, `multiline`, `select`, `multi_select`, `number`, `amount`, `date`, `datetime`, `member`, `department`, `attachment`, `relation`.
|
|
45
|
+
- Do not create `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
|
|
46
|
+
- Do not create built-in default views such as `全部数据` or `我的数据`; Qingflow provides system views.
|
|
47
|
+
|
|
48
|
+
## View Query Rules
|
|
49
|
+
|
|
50
|
+
- `filters` are fixed saved filters; `query_conditions` only configures frontend query-panel fields.
|
|
51
|
+
- Put only query-panel fields in `query_conditions.rows`: text, long text, number, amount, date/datetime, select, member, department, phone, email, or boolean.
|
|
52
|
+
- Do not put relation, attachment, subtable/subfield, address, Q-Linker, or code-block fields in `query_conditions`; use fixed `filters` or associated-resource `match_mappings` instead.
|
|
53
|
+
|
|
54
|
+
## Stop Conditions
|
|
55
|
+
|
|
56
|
+
- If the task actually needs multiple business objects, stop and switch to the complete-system guide.
|
|
57
|
+
- If a write returns `partial_success`, `write_executed=true`, or `safe_to_retry=false`, read back before retrying.
|
|
58
|
+
- If the same validation error repeats twice, re-read `builder_tool_contract` instead of guessing.
|
|
@@ -2,6 +2,16 @@
|
|
|
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
|
+
|
|
5
15
|
## Create a new app in an existing package
|
|
6
16
|
|
|
7
17
|
1. `package_get`
|
|
@@ -19,28 +19,30 @@ Before picking tools, decide which layer the request targets:
|
|
|
19
19
|
|
|
20
20
|
If the user asks for multiple forms/modules that relate to each other, this is a package-level multi-app task, not a single-app create.
|
|
21
21
|
|
|
22
|
+
Use this split consistently:
|
|
23
|
+
|
|
24
|
+
- Complete system/package: `package_apply` first, then one `app_schema_apply(package_id=..., apps=[...])`.
|
|
25
|
+
- Single app: `app_resolve/app_get` first, then app-scoped apply tools.
|
|
26
|
+
- Record/task/data operation: leave builder and use record/task skills.
|
|
27
|
+
|
|
22
28
|
## Resolve
|
|
23
29
|
|
|
24
|
-
- `package_get`: read one known package by `package_id`
|
|
25
|
-
- `package_apply`: create or update one package; use `create_if_missing=true` only after explicit user intent
|
|
30
|
+
- `package_get`: read one known package by `package_id`; it reads package `baseInfo` first and may warn `PACKAGE_DETAIL_READ_DEGRADED` when the richer detail endpoint needs package edit/add-app permission. Treat that warning as degraded detail, not as package-read failure.
|
|
31
|
+
- `package_apply`: create or update one package; use `create_if_missing=true` only after explicit user intent; layout/group/order changes require package edit permission because they call the backend package ordering route
|
|
26
32
|
- `member_search`: resolve named people from the directory
|
|
27
33
|
- `role_search`: resolve reusable roles from the directory
|
|
28
34
|
- `role_create`: create a reusable role when the business owner wants role-based routing
|
|
29
|
-
- `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id`
|
|
35
|
+
- `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id`; by-name resolution checks package detail/current visible apps before using broader admin-style app search, so a `/app/item` permission miss is not a frontend-visible-app failure
|
|
30
36
|
|
|
31
37
|
## Summary reads
|
|
32
38
|
|
|
33
|
-
All `app_get_*` tools accept either `app_key` (single) or `app_keys[]` (batch). Batch returns `{status, apps[], errors[]}` — prefer batch when reading multiple apps in one step.
|
|
34
|
-
|
|
35
39
|
- `app_get`: overall app config health, publish state, counts, and builder editability
|
|
36
40
|
- `app_get_fields`: field names, types, required flags, section ids
|
|
37
41
|
- `app_get_layout`: sections, rows, unplaced fields
|
|
38
42
|
- `app_get_views`: current view names, types, columns, group-by
|
|
39
|
-
- `app_get_flow`: workflow enabled state,
|
|
43
|
+
- `app_get_flow`: workflow enabled state, nodes, transitions
|
|
40
44
|
- `app_get_charts`: current chart ids, names, types, order
|
|
41
|
-
- `
|
|
42
|
-
- `app_get_associated_resources`: current associated resource pool (draft state)
|
|
43
|
-
- `app_publish_verify`: publish state and package tag verification — accepts `app_keys[]` for multi-app batch
|
|
45
|
+
- `chart_get`: one chart's base/config detail; base info is read through the Qingflow/qflow visible route first, and config may degrade from chart data when the CHART_SEE config endpoint is unavailable. Treat degraded config as a read-mode warning, not as proof the user cannot see the chart.
|
|
44
46
|
- `portal_get`: current portal config detail and component inventory
|
|
45
47
|
|
|
46
48
|
## Apply tools
|
|
@@ -48,15 +50,15 @@ All `app_get_*` tools accept either `app_key` (single) or `app_keys[]` (batch).
|
|
|
48
50
|
These execute normalized patches. Some app apply tools publish by default and still accept `publish=false`; custom button and associated-resource apply publish after at least one write succeeds and do not expose that switch.
|
|
49
51
|
|
|
50
52
|
- `app_schema_apply`: create app shell or change fields
|
|
51
|
-
- `app_layout_apply`: merge or replace layout
|
|
52
|
-
- `app_flow_apply`: replace
|
|
53
|
-
- `app_views_apply`: use `patch_views` for existing-view parameter replacement; use `upsert_views` for creation or full target config; remove views by key; new views default associated report/view display to visible with `limit_type="all"
|
|
54
|
-
- `app_custom_buttons_apply`: use `patch_buttons` for existing-button parameter replacement; use `upsert_buttons` for creation or full target config; configure add-data field mappings/default values; bind buttons to header/detail/list view positions; `placement=list` maps to the backend `INSIDE` row/list button position; merge-mode view configs require `buttons`; use `view_configs[].mode="replace"` or `buttons=[]` to clear a view's custom button bindings. For child-record creation linked to the current source record, map `source_field: "数据ID"` to the target relation field.
|
|
55
|
-
- `app_associated_resources_apply`: attach existing BI reports/views to the Qingflow app associated-resource pool and per-view display area; it does not create or edit QingBI report bodies/configs. Use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; `view_configs`, remove, and reorder may reference existing resources by internal `associated_item_id` or by `chart_id`/`chart_key`/`view_key`; use `match_mappings` for associated view/report filters; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only to attach an existing BI dataset report. Before `upsert_resources`, read `app_get.associated_resources` and reuse an existing matching `target_app_key + view_key/chart_key`; repeated upsert can create duplicates because `client_key` is only valid inside one apply call.
|
|
56
|
-
- `app_charts_apply`: create/edit/remove/reorder app-source QingBI report bodies/configs with `dataSourceType=qingflow`; it does not create/edit dataset BI reports and does not attach reports to Qingflow app associated-resource display. Use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; supports `target/table` aliases plus QingBI chart types such as `summary`, `columnar`, `area`, `funnel`, `radar`, `scatter`, `dualaxes`, and `map`; charts are immediate-live and do not publish; use `chart_id` when names are not unique;
|
|
57
|
-
- `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics
|
|
53
|
+
- `app_layout_apply`: merge or replace layout
|
|
54
|
+
- `app_flow_apply`: replace workflow
|
|
55
|
+
- `app_views_apply`: use `patch_views` for existing-view parameter replacement; use `upsert_views` for creation or full target config; remove views by key; new views default associated report/view display to visible with `limit_type="all"`
|
|
56
|
+
- `app_custom_buttons_apply`: use `patch_buttons` for existing-button parameter replacement; use `upsert_buttons` for creation or full target config; configure add-data field mappings/default values; bind buttons to header/detail/list view positions; `placement=list` maps to the backend `INSIDE` row/list button position; merge-mode view configs require `buttons`; use `view_configs[].mode="replace"` or `buttons=[]` to clear a view's custom button bindings. For child-record creation linked to the current source record, map `source_field: "数据ID"` to the target relation field.
|
|
57
|
+
- `app_associated_resources_apply`: attach existing BI reports/views to the Qingflow app associated-resource pool and per-view display area; it does not create or edit QingBI report bodies/configs. Permission is split like the backend: resource pool writes use EditAppAuth, while `view_configs` uses the view config/DataManageAuth path. Use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; `view_configs`, remove, and reorder may reference existing resources by internal `associated_item_id` or by `chart_id`/`chart_key`/`view_key`; use `match_mappings` with `target_field + operator + source_field/value` for associated view/report filters; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only to attach an existing BI dataset report. Before `upsert_resources`, read `app_get.associated_resources` and reuse an existing matching `target_app_key + view_key/chart_key`; repeated upsert can create duplicates because `client_key` is only valid inside one apply call.
|
|
58
|
+
- `app_charts_apply`: create/edit/remove/reorder app-source QingBI report bodies/configs with `dataSourceType=qingflow`; it does not create/edit dataset BI reports and does not attach reports to Qingflow app associated-resource display. Use `filters` with `field_name + operator + value/values`; the tool compiles them to QingBI string judge types. Use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; supports `target/table` aliases plus QingBI chart types such as `summary`, `columnar`, `area`, `funnel`, `radar`, `scatter`, `dualaxes`, and `map`; charts are immediate-live and do not publish; use `chart_id` when names are not unique; for complete systems, submit large chart sets in batches of 4-8 upserts. More than 8 upserts is blocked before write with `CHART_UPSERT_BATCH_TOO_LARGE`; execute `details.suggested_batch_payloads[]` one batch at a time.
|
|
59
|
+
- `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; create mode only prechecks package add_app, matching backend portal creation; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics
|
|
58
60
|
|
|
59
|
-
For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `patch_buttons: [{"button_id": 1001, "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]
|
|
61
|
+
For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `patch_buttons: [{"button_id": 1001, "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]`. The tool reads the current backend config, merges the patch, then submits the full backend payload internally. Do not send a partial `upsert_*` and expect missing required fields to be preserved.
|
|
60
62
|
|
|
61
63
|
## Explicit post-apply tools
|
|
62
64
|
|
|
@@ -69,15 +71,13 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
|
|
|
69
71
|
- Create a brand new package, then create one app in it:
|
|
70
72
|
`package_apply(create_if_missing=true) -> app_schema_apply`
|
|
71
73
|
- Create a brand new multi-app system/package:
|
|
72
|
-
`package_apply(create_if_missing=true) -> app_schema_apply(apps[])`
|
|
74
|
+
`package_apply(create_if_missing=true) -> app_schema_apply(apps[])`; use `apps[].client_key` plus `target_app_ref`, or `target_app` when referencing by app name
|
|
73
75
|
- Update fields on an existing app:
|
|
74
76
|
`app_resolve -> app_get_fields -> app_schema_apply`
|
|
75
77
|
- Tidy layout:
|
|
76
78
|
`app_get_fields -> app_get_layout -> builder_tool_contract (if shape is unclear) -> app_layout_apply`
|
|
77
79
|
- Add workflow:
|
|
78
80
|
`builder_tool_contract -> app_get_fields -> app_get_flow -> role_search/member_search -> app_flow_apply -> app_get_flow`
|
|
79
|
-
- Update specific flow nodes:
|
|
80
|
-
`app_get_flow -> app_flow_apply.patch_nodes[]`
|
|
81
81
|
- Add views:
|
|
82
82
|
`builder_tool_contract -> app_get_fields -> app_get_views -> app_views_apply.patch_views/upsert_views -> app_get_views`
|
|
83
83
|
- Add QingBI charts:
|
|
@@ -86,8 +86,6 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
|
|
|
86
86
|
`app_get -> app_associated_resources_apply.upsert_resources/patch_resources + view_configs -> app_get`
|
|
87
87
|
- Create or update a portal:
|
|
88
88
|
`builder_tool_contract -> portal_get -> portal_apply -> portal_get`
|
|
89
|
-
- Update portal section(s) without replacing all:
|
|
90
|
-
`portal_get -> portal_apply.patch_sections[]`
|
|
91
89
|
|
|
92
90
|
## Avoid
|
|
93
91
|
|
|
@@ -105,3 +103,4 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
|
|
|
105
103
|
- Do not omit assignees on approval/fill/copy nodes
|
|
106
104
|
- Do not patch preset flows with brand new approval/fill node ids unless you are intentionally replacing the skeleton; reuse preset ids like `approve_1` and `fill_1`
|
|
107
105
|
- Do not guess role ids, member ids, or editable field ids; resolve names first
|
|
106
|
+
- Do not force agent-authored schema into backend-internal names when public keys exist: write icons as `icon + color` first; `icon_config` / `icon:{name,color}` are compatibility aliases only. Options may use `{label,value}`, and same-call relation targets may use `target_app_ref` / `target_app`.
|
|
@@ -6,18 +6,19 @@ Use this when the app already exists and the task is only about workflow.
|
|
|
6
6
|
|
|
7
7
|
1. `builder_tool_contract(tool_name="app_flow_apply")`
|
|
8
8
|
2. `app_get_fields`
|
|
9
|
-
3. `
|
|
10
|
-
4. `
|
|
11
|
-
5. `
|
|
12
|
-
6.
|
|
13
|
-
7.
|
|
14
|
-
8.
|
|
9
|
+
3. Confirm the app has one explicit business status field, usually a `select` named `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`
|
|
10
|
+
4. `app_get_flow`
|
|
11
|
+
5. `role_search` or `member_search`
|
|
12
|
+
6. `role_create` if the user wants a reusable directory role and no good role exists
|
|
13
|
+
7. start from a canonical preset when possible
|
|
14
|
+
8. patch the skeleton instead of freehanding a full graph
|
|
15
|
+
9. reuse preset node ids when patching:
|
|
15
16
|
- `basic_approval` -> patch `approve_1`
|
|
16
17
|
- `basic_fill_then_approve` -> patch `fill_1` and `approve_1`
|
|
17
18
|
Do not add a second approval/fill node with a new id unless you are intentionally replacing the skeleton.
|
|
18
19
|
The MCP now auto-aligns the simplest single-node preset overrides, but still prefer explicit preset ids so the merged graph stays predictable.
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
10. `app_flow_apply`
|
|
21
|
+
11. `app_get_flow` when apply returns `partial_success` or the user asked for verification
|
|
21
22
|
|
|
22
23
|
If you are unsure about presets or node shapes, call `builder_tool_contract(tool_name="app_flow_apply")` before guessing.
|
|
23
24
|
|
|
@@ -61,34 +62,6 @@ For flexible business requirements, do not jump straight to a full custom graph.
|
|
|
61
62
|
2. identify the business-specific changes
|
|
62
63
|
3. patch nodes/transitions explicitly
|
|
63
64
|
|
|
64
|
-
## Targeted node updates
|
|
65
|
-
|
|
66
|
-
To change one or a few nodes without rewriting the full spec, use `patch_nodes[]` instead of `spec`:
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
{
|
|
70
|
-
"tool_name": "app_flow_apply",
|
|
71
|
-
"arguments": {
|
|
72
|
-
"profile": "default",
|
|
73
|
-
"app_key": "APP_123",
|
|
74
|
-
"publish": true,
|
|
75
|
-
"patch_nodes": [
|
|
76
|
-
{
|
|
77
|
-
"id": "approve_1",
|
|
78
|
-
"set": {
|
|
79
|
-
"name": "总监审批",
|
|
80
|
-
"assignees": {"role_names": ["总监"]}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
`patch_nodes[]` reads the current flow, merges `set` keys and removes `unset` keys on the matched node, then writes the full spec back. It returns `FLOW_NODE_NOT_FOUND` if the `id` does not match any existing node — call `app_get_flow` first to confirm ids.
|
|
89
|
-
|
|
90
|
-
Do NOT use `patch_nodes` and `spec` together in the same call.
|
|
91
|
-
|
|
92
65
|
Public flow building is intentionally limited to linear workflows. Use only:
|
|
93
66
|
|
|
94
67
|
- `start`
|
|
@@ -124,7 +97,18 @@ Preferred fix order:
|
|
|
124
97
|
|
|
125
98
|
### `FLOW_DEPENDENCY_MISSING`
|
|
126
99
|
|
|
127
|
-
The workflow depends on fields that do not exist yet, usually
|
|
100
|
+
The workflow depends on fields that do not exist yet, usually an explicit business status field. Fix schema first.
|
|
101
|
+
|
|
102
|
+
Do:
|
|
103
|
+
|
|
104
|
+
- add a business field such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`
|
|
105
|
+
- use type `select` / `single_select`
|
|
106
|
+
- use business options such as `草稿`, `进行中`, `已完成`
|
|
107
|
+
|
|
108
|
+
Do not:
|
|
109
|
+
|
|
110
|
+
- create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`
|
|
111
|
+
- skip the flow and still report workflow completion
|
|
128
112
|
|
|
129
113
|
Preferred recovery:
|
|
130
114
|
|
|
@@ -177,7 +161,7 @@ Do not copy internal keys from old plan outputs or logs, including:
|
|
|
177
161
|
|
|
178
162
|
## Notes
|
|
179
163
|
|
|
180
|
-
- `mode=replace` is the only supported flow apply mode
|
|
164
|
+
- `mode=replace` is the only supported flow apply mode
|
|
181
165
|
- `app_flow_apply` publishes by default
|
|
182
166
|
- Prefer roles over explicit members unless the user explicitly asks for named members
|
|
183
167
|
- `basic_approval` and `basic_fill_then_approve` are skeletons, not complete business workflows
|
|
@@ -10,6 +10,8 @@ Use this when the app already exists and the task is only about fields.
|
|
|
10
10
|
|
|
11
11
|
## Example
|
|
12
12
|
|
|
13
|
+
Do not add platform system fields as form controls: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`. They are generated by Qingflow; use readback/list fields when you need them.
|
|
14
|
+
|
|
13
15
|
Read current fields first:
|
|
14
16
|
|
|
15
17
|
```json
|
|
@@ -70,3 +72,4 @@ Treat it as uncertain write state. Read back with `app_get_fields` before retryi
|
|
|
70
72
|
- `checkbox -> multi_select`
|
|
71
73
|
- `as_data_title: true` marks the app data title; the final form must have exactly one top-level data title field
|
|
72
74
|
- `as_data_cover: true` marks the app data cover; the cover is optional and must be a top-level `attachment` field
|
|
75
|
+
- `数据ID`, `编号`, applicant/creation/update time, and workflow status fields are system-generated and must not appear in `add_fields`
|