@qingflow-tech/qingflow-app-user-mcp 1.0.41 → 1.0.42
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 +2 -4
- package/docs/local-agent-install.md +4 -4
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-user/SKILL.md +3 -3
- package/src/qingflow_mcp/builder_facade/service.py +102 -2
- package/src/qingflow_mcp/cli/commands/builder.py +80 -6
- package/src/qingflow_mcp/response_trim.py +5 -4
- package/skills/qingflow-app-builder/SKILL.md +0 -290
- package/skills/qingflow-app-builder/agents/openai.yaml +0 -4
- package/skills/qingflow-app-builder/references/complete-system-development-guide.md +0 -59
- package/skills/qingflow-app-builder/references/create-app.md +0 -162
- package/skills/qingflow-app-builder/references/environments.md +0 -63
- package/skills/qingflow-app-builder/references/flow-actors-and-permissions.md +0 -123
- package/skills/qingflow-app-builder/references/gotchas.md +0 -113
- package/skills/qingflow-app-builder/references/match-rules.md +0 -129
- package/skills/qingflow-app-builder/references/public-surface-sync.md +0 -75
- package/skills/qingflow-app-builder/references/single-app-development-guide.md +0 -47
- package/skills/qingflow-app-builder/references/solution-playbooks.md +0 -62
- package/skills/qingflow-app-builder/references/tool-selection.md +0 -106
- package/skills/qingflow-app-builder/references/update-flow.md +0 -158
- package/skills/qingflow-app-builder/references/update-layout.md +0 -68
- package/skills/qingflow-app-builder/references/update-schema.md +0 -75
- package/skills/qingflow-app-builder/references/update-views.md +0 -286
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +0 -139
- package/skills/qingflow-app-builder-code-integrations/agents/openai.yaml +0 -4
- package/skills/qingflow-app-builder-code-integrations/references/code-block.md +0 -66
- package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +0 -77
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# Flow Actors And Permissions
|
|
2
|
-
|
|
3
|
-
Use this when the workflow needs real assignees or node-level editable field permissions.
|
|
4
|
-
|
|
5
|
-
## Canonical policy
|
|
6
|
-
|
|
7
|
-
- Approval, fill, and copy nodes must declare at least one assignee.
|
|
8
|
-
- Prefer roles over explicit members.
|
|
9
|
-
- Resolve directory actors before calling `app_flow_apply`.
|
|
10
|
-
- Use canonical keys only:
|
|
11
|
-
- `assignees.role_names`
|
|
12
|
-
- `assignees.role_ids`
|
|
13
|
-
- `assignees.member_names`
|
|
14
|
-
- `assignees.member_emails`
|
|
15
|
-
- `assignees.member_uids`
|
|
16
|
-
- `permissions.editable_fields`
|
|
17
|
-
|
|
18
|
-
## Recommended order
|
|
19
|
-
|
|
20
|
-
1. `app_get_fields`
|
|
21
|
-
2. `app_get_flow`
|
|
22
|
-
3. `role_search`
|
|
23
|
-
4. `member_search` when the user explicitly names people
|
|
24
|
-
5. `role_create` when no reusable role exists and the user wants role-based routing
|
|
25
|
-
6. `app_flow_apply`
|
|
26
|
-
|
|
27
|
-
## Examples
|
|
28
|
-
|
|
29
|
-
### Route an approval node to a reusable role
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"tool_name": "app_flow_apply",
|
|
34
|
-
"arguments": {
|
|
35
|
-
"profile": "default",
|
|
36
|
-
"app_key": "APP_123",
|
|
37
|
-
"preset": "basic_approval",
|
|
38
|
-
"nodes": [
|
|
39
|
-
{
|
|
40
|
-
"id": "approve_1",
|
|
41
|
-
"type": "approve",
|
|
42
|
-
"name": "部门审批",
|
|
43
|
-
"assignees": {
|
|
44
|
-
"role_names": ["项目经理"]
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Route to explicit members when the user names people
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"tool_name": "app_flow_apply",
|
|
57
|
-
"arguments": {
|
|
58
|
-
"profile": "default",
|
|
59
|
-
"app_key": "APP_123",
|
|
60
|
-
"preset": "basic_approval",
|
|
61
|
-
"nodes": [
|
|
62
|
-
{
|
|
63
|
-
"id": "approve_1",
|
|
64
|
-
"type": "approve",
|
|
65
|
-
"name": "部门审批",
|
|
66
|
-
"assignees": {
|
|
67
|
-
"member_names": ["严琪东", "张三"]
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Let one node edit selected fields only
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"tool_name": "app_flow_apply",
|
|
80
|
-
"arguments": {
|
|
81
|
-
"profile": "default",
|
|
82
|
-
"app_key": "APP_123",
|
|
83
|
-
"mode": "replace",
|
|
84
|
-
"publish": true,
|
|
85
|
-
"nodes": [
|
|
86
|
-
{"id": "start", "type": "start", "name": "发起"},
|
|
87
|
-
{
|
|
88
|
-
"id": "approve_1",
|
|
89
|
-
"type": "approve",
|
|
90
|
-
"name": "部门审批",
|
|
91
|
-
"assignees": {
|
|
92
|
-
"role_names": ["项目经理"]
|
|
93
|
-
},
|
|
94
|
-
"permissions": {
|
|
95
|
-
"editable_fields": ["状态", "审批意见", "项目负责人"]
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{"id": "end", "type": "end", "name": "结束"}
|
|
99
|
-
],
|
|
100
|
-
"transitions": [
|
|
101
|
-
{"from": "start", "to": "approve_1"},
|
|
102
|
-
{"from": "approve_1", "to": "end"}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Common recovery
|
|
109
|
-
|
|
110
|
-
### `ROLE_NOT_FOUND` / `AMBIGUOUS_ROLE`
|
|
111
|
-
|
|
112
|
-
- retry with `role_search`
|
|
113
|
-
- if the business wants a reusable route and no exact role exists, create one with `role_create`
|
|
114
|
-
|
|
115
|
-
### `MEMBER_NOT_FOUND` / `AMBIGUOUS_MEMBER`
|
|
116
|
-
|
|
117
|
-
- retry with `member_search`
|
|
118
|
-
- do not guess user ids
|
|
119
|
-
|
|
120
|
-
### `UNKNOWN_FLOW_FIELD`
|
|
121
|
-
|
|
122
|
-
- reread fields with `app_get_fields`
|
|
123
|
-
- only pass real current field names to `permissions.editable_fields`
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Builder Gotchas
|
|
2
|
-
|
|
3
|
-
## Auth and workspace
|
|
4
|
-
|
|
5
|
-
- `auth_*` success does not mean a workspace is selected
|
|
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
|
-
|
|
8
|
-
## Package ownership
|
|
9
|
-
|
|
10
|
-
- Public package work should stay on `package_get / package_apply`
|
|
11
|
-
- Do not treat `package_attach_app` as the public default story anymore; if it still exists in low-level code, treat it as internal/legacy
|
|
12
|
-
- Check package-related readback after schema writes instead of assuming package ownership from the write alone
|
|
13
|
-
|
|
14
|
-
## Package vs app vs field
|
|
15
|
-
|
|
16
|
-
- A package/system is not an app
|
|
17
|
-
- Another app is not a field
|
|
18
|
-
- If the user names multiple forms/modules that relate to each other, create multiple apps and connect them with relation fields
|
|
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
|
-
|
|
23
|
-
## Auto publish
|
|
24
|
-
|
|
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`
|
|
28
|
-
- `app_publish_verify` is for explicit final verification, not the default next step after every write
|
|
29
|
-
|
|
30
|
-
## BI Reports
|
|
31
|
-
|
|
32
|
-
- Use `app_charts_apply` for QingBI report body/config creation or updates.
|
|
33
|
-
- 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
|
-
- `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
|
-
- 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
|
-
- `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`.
|
|
37
|
-
|
|
38
|
-
## Custom buttons
|
|
39
|
-
|
|
40
|
-
- Use `app_custom_buttons_apply` for button creation/update/removal and view placement; do not split placement into `app_views_apply.buttons` unless you are maintaining a legacy patch.
|
|
41
|
-
- 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.
|
|
42
|
-
- For add-data buttons, prefer semantic `trigger_add_data_config.target_app_key`, `field_mappings`, and `default_values`.
|
|
43
|
-
- 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.
|
|
44
|
-
- `field_mappings.source_field` can use source app fields and supported system fields such as `数据ID` (`field_id=-17`) and `编号` (`field_id=0`).
|
|
45
|
-
- To fill a target relation field with the current source record, map `{"source_field": "数据ID", "target_field": "目标引用字段"}`. Use `default_values` only for static constants.
|
|
46
|
-
- For field type compatibility, read `references/match-rules.md`.
|
|
47
|
-
- Default button placements are `header` and `detail`; these map to the frontend's header and detail button areas.
|
|
48
|
-
- `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.
|
|
49
|
-
- 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`.
|
|
50
|
-
- 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.
|
|
51
|
-
- 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.
|
|
52
|
-
- `placement=list` configures row/list buttons. The tool maps it to the backend `INSIDE` button position, not a raw `LIST` config type.
|
|
53
|
-
|
|
54
|
-
## Associated resources
|
|
55
|
-
|
|
56
|
-
- Before creating an associated view/report, check `app_get.associated_resources` for the same `target_app_key + view_key/chart_key`.
|
|
57
|
-
- If the resource already exists, use `patch_resources` with its `associated_item_id`; do not call `upsert_resources` again.
|
|
58
|
-
- For per-view display, remove, and reorder, existing associated reports/views may be referenced by `associated_item_id`, `chart_id`/`chart_key`, or `view_key`; the tool resolves these to the internal id before writing.
|
|
59
|
-
- `client_key` is only a same-call alias for `view_configs[].associated_item_refs`. It is not stored by Qingflow and cannot prevent duplicates in later calls.
|
|
60
|
-
- Repeated `upsert_resources` without `associated_item_id` can create multiple app-level associated items pointing to the same view/report.
|
|
61
|
-
|
|
62
|
-
## Readback scope
|
|
63
|
-
|
|
64
|
-
- Prefer summary reads over large raw payloads
|
|
65
|
-
- Use `app_get_fields` before schema or view work
|
|
66
|
-
- Use `app_get_layout` before layout work
|
|
67
|
-
- Use `app_get_flow` before workflow work
|
|
68
|
-
- Use `app_get_views` before view work
|
|
69
|
-
|
|
70
|
-
## Partial update discipline
|
|
71
|
-
|
|
72
|
-
- Existing views, custom buttons, associated resources, and charts support the same public partial pattern: `patch_*[].set` plus optional `patch_*[].unset`.
|
|
73
|
-
- 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.
|
|
74
|
-
- Do not use `upsert_views`, `upsert_buttons`, `upsert_resources`, or `upsert_charts` for a tiny parameter replacement unless you are deliberately providing the full desired target config.
|
|
75
|
-
- `app_layout_apply(mode=merge)` is already a safe layout merge path; `mode=replace` is full layout replacement.
|
|
76
|
-
- `portal_apply` without `sections` is base-info-only. Supplying `sections` replaces the portal sections list.
|
|
77
|
-
- `app_flow_apply` is intentionally replace-only for the public linear workflow graph.
|
|
78
|
-
|
|
79
|
-
## Workflow dependencies
|
|
80
|
-
|
|
81
|
-
- Approval-style flows usually require an explicit status field
|
|
82
|
-
- Approval, fill, and copy nodes also require at least one assignee
|
|
83
|
-
- Prefer roles over explicit members unless the user explicitly names people
|
|
84
|
-
- Resolve assignees with `role_search` / `member_search` before flow apply
|
|
85
|
-
- Use `permissions.editable_fields` for node-level editable field permissions; do not guess field ids
|
|
86
|
-
- Preset node ids matter. When patching `basic_approval` or `basic_fill_then_approve`, reuse `approve_1` and `fill_1` unless you are explicitly replacing the skeleton.
|
|
87
|
-
- If `app_flow_apply` reports `FLOW_DEPENDENCY_MISSING`, fix schema first
|
|
88
|
-
- Do not switch to hidden `solution_*` tools from public builder flows
|
|
89
|
-
|
|
90
|
-
## Retry discipline
|
|
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
|
|
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
|
|
98
|
-
- For backend rejects, keep the retry narrow: retry only the failed tool, not the whole chain
|
|
99
|
-
- For `VALIDATION_ERROR`, do not keep guessing. Reuse `suggested_next_call`, `canonical_arguments`, `allowed_keys`, and `allowed_values` first.
|
|
100
|
-
- 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)`.
|
|
101
|
-
- For flow work, do not replay internal keys from old logs or plan outputs. Public builder calls should stay on:
|
|
102
|
-
- `assignees.role_ids` / `assignees.member_uids` / `assignees.member_emails`
|
|
103
|
-
- `permissions.editable_fields`
|
|
104
|
-
- For view work, treat `columns` as the only canonical public key. `app_get_views` and `app_views_apply` should all be read and written in that shape.
|
|
105
|
-
- For existing view parameter changes, prefer `patch_views`. Example: to change only query-panel fields, set only `query_conditions`; the tool will preserve columns, filters, date config, card fields, buttons, and other backend-required fields.
|
|
106
|
-
- For layout work, treat `title + rows` as the only canonical public section shape. `fields`, `field_ids`, and `columns` may appear in legacy/internal shapes, but they are not the preferred public write shape.
|
|
107
|
-
- A created view is not enough to claim a filter succeeded. When `app_views_apply` returns `partial_success`, `views_verified=false`, or `details.filter_mismatches`, treat the view as present but the filter as unverified.
|
|
108
|
-
- If duplicate view names exist, do not retry by name. Read the exact `view_key` and target that one.
|
|
109
|
-
- If a view or flow write fails, report the smallest next action:
|
|
110
|
-
- wrong key -> switch to canonical key
|
|
111
|
-
- unsupported preset -> switch to allowed canonical preset
|
|
112
|
-
- backend reject -> re-read summary and retry only the failed patch
|
|
113
|
-
- Do not translate abstract user phrases like “灵活流程” or “默认视图” directly into MCP arguments. First convert them to a preset or explicit patch plan.
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Builder Match Rules
|
|
2
|
-
|
|
3
|
-
Use this reference for builder-side field matching rules in custom buttons and associated view/report filters.
|
|
4
|
-
|
|
5
|
-
This is not the same thing as `record_access` analysis filters or normal view `filters`.
|
|
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
|
-
## Where These Rules Apply
|
|
14
|
-
|
|
15
|
-
- `app_custom_buttons_apply.upsert_buttons[].trigger_add_data_config.field_mappings`
|
|
16
|
-
- `app_custom_buttons_apply.patch_buttons[].set.trigger_add_data_config.field_mappings`
|
|
17
|
-
- `app_associated_resources_apply.upsert_resources[].match_mappings`
|
|
18
|
-
- `app_associated_resources_apply.patch_resources[].set.match_mappings`
|
|
19
|
-
|
|
20
|
-
Prefer semantic mappings. Do not handwrite raw `que_relation` or `match_rules` unless you are preserving an existing backend config.
|
|
21
|
-
|
|
22
|
-
## System Fields
|
|
23
|
-
|
|
24
|
-
System fields can participate in mappings:
|
|
25
|
-
|
|
26
|
-
- `数据ID`, `row_record_id`, `apply_id`, `_id` -> `field_id=-17`
|
|
27
|
-
This is the current record's real apply/record ID.
|
|
28
|
-
- `编号`, `数据编号`, `record_number` -> `field_id=0`
|
|
29
|
-
This is the frontend-visible record number. It may be custom formatted and is not the same as `数据ID`.
|
|
30
|
-
|
|
31
|
-
Explicit selectors such as `{"field_id": -17}` and `{"field_id": 0}` are allowed and remove ambiguity.
|
|
32
|
-
|
|
33
|
-
## Custom Buttons
|
|
34
|
-
|
|
35
|
-
Use `field_mappings` for dynamic values copied from the current source record:
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"target_app_key": "WORKLOG_APP",
|
|
40
|
-
"field_mappings": [
|
|
41
|
-
{"source_field": "数据ID", "target_field": "关联员工"},
|
|
42
|
-
{"source_field": "员工名称", "target_field": "员工姓名"}
|
|
43
|
-
],
|
|
44
|
-
"default_values": {
|
|
45
|
-
"状态": "待提交"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Use `default_values` only for static constants. Do not use `default_values` as the preferred way to pass the current record.
|
|
51
|
-
|
|
52
|
-
For an existing button, put the same semantic config under `patch_buttons[].set`:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"button_id": 3858041,
|
|
57
|
-
"set": {
|
|
58
|
-
"trigger_add_data_config": {
|
|
59
|
-
"target_app_key": "WORKLOG_APP",
|
|
60
|
-
"field_mappings": [
|
|
61
|
-
{"source_field": "数据ID", "target_field": "关联员工"}
|
|
62
|
-
],
|
|
63
|
-
"default_values": {
|
|
64
|
-
"状态": "待提交"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Associated Resources
|
|
72
|
-
|
|
73
|
-
Use `match_mappings` for associated view/report filters:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"graph_type": "view",
|
|
78
|
-
"target_app_key": "WORKLOG_APP",
|
|
79
|
-
"view_key": "WORKLOG_VIEW",
|
|
80
|
-
"match_mappings": [
|
|
81
|
-
{"target_field": "关联员工", "source_field": "数据ID"},
|
|
82
|
-
{"target_field": "状态", "value": "待提交"}
|
|
83
|
-
]
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Dynamic conditions use `source_field`; static conditions use `value`.
|
|
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
|
-
|
|
98
|
-
For an existing associated resource, put the same filter mapping under `patch_resources[].set`:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"associated_item_id": 3497587,
|
|
103
|
-
"set": {
|
|
104
|
-
"match_mappings": [
|
|
105
|
-
{"target_field": "关联员工", "source_field": "数据ID"}
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Type Compatibility
|
|
112
|
-
|
|
113
|
-
- Relation fields: match another relation field with the same target app, or match `数据ID(-17)` when the target relation points to the current source app.
|
|
114
|
-
- Record ID `数据ID(-17)`: can match relation fields that point to the current source app, or ID-compatible text/number fields.
|
|
115
|
-
- Record number `编号(0)`: can match text, long text, number, amount, or another record-number field.
|
|
116
|
-
- Member fields: only match member fields.
|
|
117
|
-
- Department fields: only match department fields.
|
|
118
|
-
- Option fields: single select, multi select, and boolean can match option-family fields or static option values.
|
|
119
|
-
- Date fields: date and datetime can match each other.
|
|
120
|
-
- Text fields: text, long text, phone, and email can match each other.
|
|
121
|
-
- Number fields: number and amount can match each other.
|
|
122
|
-
- Attachment, subtable, code block, Q-Linker, and address fields are not default match fields.
|
|
123
|
-
|
|
124
|
-
## Error Interpretation
|
|
125
|
-
|
|
126
|
-
- Field not found: re-read `app_get` or `app_get_fields` and retry with an exact title or `field_id`.
|
|
127
|
-
- Type mismatch: choose a compatible source/target pair from the matrix above.
|
|
128
|
-
- Reference source mismatch: the target relation field points to a different app; choose a relation field that points back to the current source app, or match a non-relation field.
|
|
129
|
-
- Mixed raw and semantic modes: use either semantic `field_mappings/match_mappings` or raw `que_relation/match_rules`, never both in the same item.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Qingflow Core Public Surface Sync
|
|
2
|
-
|
|
3
|
-
Use this file as the maintenance baseline for the core Qingflow skills.
|
|
4
|
-
It is not a user-facing product spec. It exists to prevent skill drift.
|
|
5
|
-
|
|
6
|
-
## Current Public Defaults
|
|
7
|
-
|
|
8
|
-
### User data
|
|
9
|
-
|
|
10
|
-
- Read range first with `app_get`, then `record_browse_schema_get(view_id=...)`
|
|
11
|
-
- Treat `record_browse_schema_get.fields` as the selected Qingflow table view header schema; `record_access.fields` and `record_list` field selectors must stay aligned with it.
|
|
12
|
-
- Standard flows:
|
|
13
|
-
- analyze: `app_get -> record_browse_schema_get -> record_access -> Python`
|
|
14
|
-
- browse detail: `app_get -> record_browse_schema_get -> record_list / record_get`
|
|
15
|
-
- explicit export/download/Excel: `app_get -> choose view_id -> view_get -> record_export_*` or `record_export_direct`; export tools require explicit `view_id`
|
|
16
|
-
- insert: `record_insert_schema_get -> record_insert(items)`
|
|
17
|
-
- update: `record_get -> record_update`; use `record_update_schema_get` only for failure diagnosis or ambiguous writable-field routing
|
|
18
|
-
|
|
19
|
-
### Tasks
|
|
20
|
-
|
|
21
|
-
- Discovery stays on `task_list`
|
|
22
|
-
- `task_list --query` uses backend search first and only applies local fallback when backend returns zero rows
|
|
23
|
-
- Public actions are:
|
|
24
|
-
- `approve`
|
|
25
|
-
- `reject`
|
|
26
|
-
- `rollback`
|
|
27
|
-
- `transfer`
|
|
28
|
-
- `urge`
|
|
29
|
-
- `save_only`
|
|
30
|
-
- `reject` requires `payload.audit_feedback`
|
|
31
|
-
- `save_only` requires non-empty `fields`
|
|
32
|
-
- `TASK_RUNTIME_CONSUMED_AFTER_ACTION` is a normal post-success warning when the current node runtime is consumed and `46001` appears on re-read
|
|
33
|
-
|
|
34
|
-
### Builder
|
|
35
|
-
|
|
36
|
-
- Official package entry: `package_get`, `package_apply`
|
|
37
|
-
- Official builder writes:
|
|
38
|
-
- `app_schema_apply`
|
|
39
|
-
- `app_layout_apply`
|
|
40
|
-
- `app_flow_apply`
|
|
41
|
-
- `app_views_apply`
|
|
42
|
-
- `app_custom_buttons_apply`
|
|
43
|
-
- `app_associated_resources_apply`
|
|
44
|
-
- `app_charts_apply`
|
|
45
|
-
- `portal_apply`
|
|
46
|
-
- `app_publish_verify`
|
|
47
|
-
- `portal_apply` edit mode may omit `sections` for base-info-only updates
|
|
48
|
-
- `app_charts_apply.visibility` is a public capability and should be treated as a base-only visibility update
|
|
49
|
-
- Existing object parameter replacement should use `patch_views`, `patch_buttons`, `patch_resources`, and `patch_charts`; `upsert_*` is for creation or full target config
|
|
50
|
-
- `app_get.editability` uses:
|
|
51
|
-
- `can_edit_app_base`
|
|
52
|
-
- `can_edit_form`
|
|
53
|
-
- `can_edit_flow`
|
|
54
|
-
- `can_edit_views`
|
|
55
|
-
- `can_edit_charts`
|
|
56
|
-
|
|
57
|
-
## Known High-Drift Areas
|
|
58
|
-
|
|
59
|
-
- Task actions, especially `save_only`, reject payload requirements, and `46001` post-action interpretation
|
|
60
|
-
- Package public tools: do not regress to `package_create` / `package_attach_app` as the public default story
|
|
61
|
-
- App editability: do not let `can_edit_form` imply app base-info writes
|
|
62
|
-
- Portal and chart visibility: keep the public story on `portal_apply` / `app_charts_apply`, not low-level internal writes
|
|
63
|
-
- Analysis path: standard path stays `record_access -> Python`
|
|
64
|
-
|
|
65
|
-
## Release Checklist For Skill Maintenance
|
|
66
|
-
|
|
67
|
-
After each beta that changes public behavior, re-check:
|
|
68
|
-
|
|
69
|
-
1. `public_surface.py`
|
|
70
|
-
2. `README.md`
|
|
71
|
-
3. `server_app_builder.py` and `server.py` top-level guidance
|
|
72
|
-
4. CLI help for `task`, `builder package`, `builder portal`, `builder charts`
|
|
73
|
-
5. Whether new warnings or verification fields need to be explained in skills
|
|
74
|
-
|
|
75
|
-
If a tool behavior changed but the public surface did not, prefer updating the relevant skill section instead of expanding this file.
|
|
@@ -1,47 +0,0 @@
|
|
|
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
|
-
## Standard Path
|
|
28
|
-
|
|
29
|
-
1. Read current target: `app_resolve` or `app_get`.
|
|
30
|
-
2. Read current fields: `app_get_fields`.
|
|
31
|
-
3. Apply fields with `app_schema_apply`.
|
|
32
|
-
4. Apply layout with `app_layout_apply`.
|
|
33
|
-
5. Apply views with `app_views_apply` when list/table/card/gantt behavior is part of the request.
|
|
34
|
-
6. Apply charts/buttons/associated resources only if they are part of the app's actual workflow.
|
|
35
|
-
7. Use `app_publish_verify` only when explicit live verification is required.
|
|
36
|
-
|
|
37
|
-
## Field Rules
|
|
38
|
-
|
|
39
|
-
- Use agent-friendly field types where possible: `text`, `multiline`, `select`, `multi_select`, `number`, `amount`, `date`, `datetime`, `member`, `department`, `attachment`, `relation`.
|
|
40
|
-
- Do not create `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`.
|
|
41
|
-
- Do not create built-in default views such as `全部数据` or `我的数据`; Qingflow provides system views.
|
|
42
|
-
|
|
43
|
-
## Stop Conditions
|
|
44
|
-
|
|
45
|
-
- If the task actually needs multiple business objects, stop and switch to the complete-system guide.
|
|
46
|
-
- If a write returns `partial_success`, `write_executed=true`, or `safe_to_retry=false`, read back before retrying.
|
|
47
|
-
- If the same validation error repeats twice, re-read `builder_tool_contract` instead of guessing.
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Builder Playbooks
|
|
2
|
-
|
|
3
|
-
Use these when you need a quick reminder of the standard v2 builder sequences.
|
|
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
|
-
## Create a new app in an existing package
|
|
16
|
-
|
|
17
|
-
1. `package_get`
|
|
18
|
-
2. `app_resolve`
|
|
19
|
-
3. `app_schema_apply`
|
|
20
|
-
5. `app_publish_verify` only if the user asks for explicit live verification
|
|
21
|
-
|
|
22
|
-
## Update fields on an existing app
|
|
23
|
-
|
|
24
|
-
1. `app_resolve`
|
|
25
|
-
2. `app_get_fields`
|
|
26
|
-
3. `app_schema_apply`
|
|
27
|
-
|
|
28
|
-
## Rework layout
|
|
29
|
-
|
|
30
|
-
1. `app_get_layout`
|
|
31
|
-
2. `app_layout_apply`
|
|
32
|
-
|
|
33
|
-
Prefer `mode=merge`. Use `mode=replace` only when every field placement is intentional.
|
|
34
|
-
|
|
35
|
-
## Add or update workflow
|
|
36
|
-
|
|
37
|
-
1. `app_get_fields`
|
|
38
|
-
2. `app_get_flow`
|
|
39
|
-
3. `role_search` or `member_search`
|
|
40
|
-
4. `role_create` if the business wants a reusable role and no good exact role exists
|
|
41
|
-
5. `app_flow_apply`
|
|
42
|
-
|
|
43
|
-
If `app_flow_apply` reports `FLOW_DEPENDENCY_MISSING`, fix schema first.
|
|
44
|
-
If it reports `FLOW_ASSIGNEE_REQUIRED`, resolve roles or members first and retry with canonical `assignees.*`.
|
|
45
|
-
|
|
46
|
-
## Add or update views
|
|
47
|
-
|
|
48
|
-
1. `app_get_fields`
|
|
49
|
-
2. `app_get_views`
|
|
50
|
-
3. `app_views_apply`
|
|
51
|
-
|
|
52
|
-
For both workflow and view work, prefer `suggested_next_call` over re-guessing arguments after a validation failure.
|
|
53
|
-
|
|
54
|
-
## Final readback
|
|
55
|
-
|
|
56
|
-
Prefer these fields after writes:
|
|
57
|
-
|
|
58
|
-
- `app_get.tag_ids`
|
|
59
|
-
- `app_get.publish_status`
|
|
60
|
-
- `app_get_layout.unplaced_fields`
|
|
61
|
-
- `app_get_views.views`
|
|
62
|
-
- `app_get_flow.nodes`
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# Tool Selection
|
|
2
|
-
|
|
3
|
-
Use the smallest v2 builder tool chain that can finish the task.
|
|
4
|
-
|
|
5
|
-
## Default path
|
|
6
|
-
|
|
7
|
-
`summary read -> apply -> publish_verify`
|
|
8
|
-
|
|
9
|
-
Public builder `apply` tools already perform server-side planning, normalization, and dependency checks internally. Do not route normal public builder work through explicit `*_plan` tools.
|
|
10
|
-
|
|
11
|
-
## Hierarchy first
|
|
12
|
-
|
|
13
|
-
Before picking tools, decide which layer the request targets:
|
|
14
|
-
|
|
15
|
-
- `package`: a solution/app bundle like “研发项目管理” or “费控管理系统”
|
|
16
|
-
- `app`: one form/app inside that package
|
|
17
|
-
- `field`: one field inside one app
|
|
18
|
-
- `relation`: a field that links two apps
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
28
|
-
## Resolve
|
|
29
|
-
|
|
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
|
|
32
|
-
- `member_search`: resolve named people from the directory
|
|
33
|
-
- `role_search`: resolve reusable roles from the directory
|
|
34
|
-
- `role_create`: create a reusable role when the business owner wants role-based routing
|
|
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
|
|
36
|
-
|
|
37
|
-
## Summary reads
|
|
38
|
-
|
|
39
|
-
- `app_get`: overall app config health, publish state, counts, and builder editability
|
|
40
|
-
- `app_get_fields`: field names, types, required flags, section ids
|
|
41
|
-
- `app_get_layout`: sections, rows, unplaced fields
|
|
42
|
-
- `app_get_views`: current view names, types, columns, group-by
|
|
43
|
-
- `app_get_flow`: workflow enabled state, nodes, transitions
|
|
44
|
-
- `app_get_charts`: current chart ids, names, types, order
|
|
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.
|
|
46
|
-
- `portal_get`: current portal config detail and component inventory
|
|
47
|
-
|
|
48
|
-
## Apply tools
|
|
49
|
-
|
|
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.
|
|
51
|
-
|
|
52
|
-
- `app_schema_apply`: create app shell or change fields
|
|
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
|
|
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
|
|
60
|
-
|
|
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.
|
|
62
|
-
|
|
63
|
-
## Explicit post-apply tools
|
|
64
|
-
|
|
65
|
-
- `app_publish_verify`: explicit final publish verification when the user asks for live confirmation
|
|
66
|
-
|
|
67
|
-
## Decision shortcuts
|
|
68
|
-
|
|
69
|
-
- Create one app inside an existing package:
|
|
70
|
-
`package_get -> app_resolve -> app_schema_apply`
|
|
71
|
-
- Create a brand new package, then create one app in it:
|
|
72
|
-
`package_apply(create_if_missing=true) -> app_schema_apply`
|
|
73
|
-
- Create a brand new multi-app system/package:
|
|
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
|
|
75
|
-
- Update fields on an existing app:
|
|
76
|
-
`app_resolve -> app_get_fields -> app_schema_apply`
|
|
77
|
-
- Tidy layout:
|
|
78
|
-
`app_get_fields -> app_get_layout -> builder_tool_contract (if shape is unclear) -> app_layout_apply`
|
|
79
|
-
- Add workflow:
|
|
80
|
-
`builder_tool_contract -> app_get_fields -> app_get_flow -> role_search/member_search -> app_flow_apply -> app_get_flow`
|
|
81
|
-
- Add views:
|
|
82
|
-
`builder_tool_contract -> app_get_fields -> app_get_views -> app_views_apply.patch_views/upsert_views -> app_get_views`
|
|
83
|
-
- Add QingBI charts:
|
|
84
|
-
`builder_tool_contract -> app_get_fields -> app_get_charts -> app_charts_apply.patch_charts/upsert_charts -> app_get_charts`
|
|
85
|
-
- Show an existing QingBI chart inside a Qingflow app/view:
|
|
86
|
-
`app_get -> app_associated_resources_apply.upsert_resources/patch_resources + view_configs -> app_get`
|
|
87
|
-
- Create or update a portal:
|
|
88
|
-
`builder_tool_contract -> portal_get -> portal_apply -> portal_get`
|
|
89
|
-
|
|
90
|
-
## Avoid
|
|
91
|
-
|
|
92
|
-
- Do not handcraft raw Qingflow schema payloads
|
|
93
|
-
- Do not rely on internal `solution_*` tools in public builder flows
|
|
94
|
-
- Do not create a new package without first asking the user to confirm package creation
|
|
95
|
-
- Do not regress to `package_create` or `package_attach_app` as the public default story
|
|
96
|
-
- Do not treat a package/system name as `app_name` when the user clearly wants multiple apps inside it
|
|
97
|
-
- Do not compress multiple business objects into one app with several text fields
|
|
98
|
-
- Do not skip summary reads before flow or view work
|
|
99
|
-
- Do not emit `column_names`; always use `columns`
|
|
100
|
-
- Do not model layout shape with `fields`, `field_ids`, or top-level `columns`; custom layout sections should be `title + rows`
|
|
101
|
-
- Do not reuse internal flow keys such as `role_entries` or `editable_que_ids` in public builder calls
|
|
102
|
-
- Do not pass natural-language preset guesses such as `default_approval`; map them to canonical preset values first
|
|
103
|
-
- Do not omit assignees on approval/fill/copy nodes
|
|
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`
|
|
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`.
|