@qingflow-tech/qingflow-app-builder-mcp 1.0.6 → 1.0.7
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 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +68 -6
- package/skills/qingflow-app-builder/references/create-app.md +4 -1
- package/skills/qingflow-app-builder/references/gotchas.md +13 -1
- package/skills/qingflow-app-builder/references/tool-selection.md +3 -1
- package/skills/qingflow-app-builder/references/update-schema.md +6 -2
- package/skills/qingflow-app-builder/references/update-views.md +126 -5
- package/src/qingflow_mcp/builder_facade/models.py +269 -2
- package/src/qingflow_mcp/builder_facade/service.py +3549 -172
- package/src/qingflow_mcp/cli/commands/builder.py +39 -26
- package/src/qingflow_mcp/cli/commands/record.py +3 -3
- package/src/qingflow_mcp/public_surface.py +2 -5
- package/src/qingflow_mcp/response_trim.py +3 -6
- package/src/qingflow_mcp/server_app_builder.py +33 -20
- package/src/qingflow_mcp/tools/ai_builder_tools.py +395 -117
- package/src/qingflow_mcp/tools/record_tools.py +9 -2
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
6
|
+
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.7
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
12
|
+
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.7 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -38,7 +38,7 @@ Default modeling rules:
|
|
|
38
38
|
- App reads: `app_resolve`, `app_get`, `app_get_fields`, `app_get_layout`, `app_get_views`, `app_get_flow`, `app_get_charts`
|
|
39
39
|
- Builder reads: `portal_list`, `portal_get`, `view_get`, `chart_get`, `builder_tool_contract`
|
|
40
40
|
- Directory: `member_search`, `role_search`, `role_create`
|
|
41
|
-
- Writes: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_charts_apply`, `portal_apply`, `app_release_edit_lock_if_mine`
|
|
41
|
+
- Writes: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_custom_buttons_apply`, `app_associated_resources_apply`, `app_charts_apply`, `portal_apply`, `app_release_edit_lock_if_mine`
|
|
42
42
|
- Verification: `app_publish_verify`
|
|
43
43
|
- Cross-cutting escalation: `feedback_submit` after explicit user confirmation when the public builder surface still cannot satisfy the user's need
|
|
44
44
|
|
|
@@ -60,9 +60,23 @@ Treat these as the official surface. Do not default to `package_create`, `packag
|
|
|
60
60
|
- `app_charts_apply` is the public write path
|
|
61
61
|
- `visibility` is a public capability and should be treated as a base-only permission update
|
|
62
62
|
- do not model chart visibility changes as raw config rewrites
|
|
63
|
+
- Button work:
|
|
64
|
+
- `app_custom_buttons_apply` is the public write path for custom button bodies and view placement
|
|
65
|
+
- for add-data buttons, use `trigger_add_data_config.target_app_key + field_mappings/default_values`; do not handwrite raw `que_relation`
|
|
66
|
+
- bind buttons to views through `view_configs[].buttons[]`; default to `placement`: `header` or `detail`
|
|
67
|
+
- `buttons` is required in merge mode; do not send a view config with only `view_key`
|
|
68
|
+
- `view_configs[].mode` defaults to `merge`; use `mode: "replace"` or an explicit empty `buttons: []` to clear a view's custom button bindings
|
|
69
|
+
- `placement=list` is experimental because some backend deployments reject it with `LIST_BUTTON_BACKEND_UNSUPPORTED`
|
|
70
|
+
- advanced bindings may use `button_limit`, `button_formula`, `button_formula_type`, and `print_tpls` only when visibility or print-template behavior is required
|
|
71
|
+
- Associated resources:
|
|
72
|
+
- `app_associated_resources_apply` is the public write path for the app-level associated report/view pool and per-view display config
|
|
73
|
+
- `associated_item_id` must come from `app_get.associated_resources[].associated_item_id`; it is not `chart_id`, `chart_key`, or `view_key`
|
|
74
|
+
- do not pass backend raw `sourceType`; view resources infer the internal Qingflow view source, report/chart resources default to BI app reports, and dataset reports use `report_source="dataset"`
|
|
63
75
|
- Views and flows:
|
|
64
76
|
- stay on `app_views_apply` / `app_flow_apply`
|
|
65
77
|
- use `builder_tool_contract` whenever the minimal legal shape is unclear
|
|
78
|
+
- keep view `filters` and `query_conditions` separate: `filters` are fixed saved filters; `query_conditions` configure the frontend query panel fields and only take effect after users enter query values
|
|
79
|
+
- configure associated reports/views through `app_associated_resources_apply`, not through `app_views_apply`
|
|
66
80
|
|
|
67
81
|
## Standard Operating Order
|
|
68
82
|
|
|
@@ -74,12 +88,12 @@ Treat these as the official surface. Do not default to `package_create`, `packag
|
|
|
74
88
|
- package-scoped work with known id -> `package_get`
|
|
75
89
|
- portal inventory -> `portal_list`
|
|
76
90
|
5. Read only the smallest config slice needed:
|
|
77
|
-
- app
|
|
91
|
+
- app map -> `app_get` (default entry; includes compact views, charts, custom buttons, and associated resource pool)
|
|
78
92
|
- fields -> `app_get_fields`
|
|
79
93
|
- layout -> `app_get_layout`
|
|
80
|
-
- views -> `app_get_views`
|
|
94
|
+
- views -> `app_get_views` only when the app_get compact list is not enough
|
|
81
95
|
- flow -> `app_get_flow`
|
|
82
|
-
- charts -> `app_get_charts`
|
|
96
|
+
- charts -> `app_get_charts` only when the app_get compact list is not enough
|
|
83
97
|
- portal -> `portal_get`
|
|
84
98
|
6. If the public shape is unclear, call `builder_tool_contract`
|
|
85
99
|
7. Apply the smallest patch tool that fits:
|
|
@@ -98,7 +112,8 @@ Treat these as the official surface. Do not default to `package_create`, `packag
|
|
|
98
112
|
- If `package_id` is unknown, derive it from related app/portal readback when possible; otherwise ask the user instead of falling back to hidden package lookup tools.
|
|
99
113
|
- Do not use `package_create` or `package_attach_app` as a public default path. If they still appear in low-level code, treat them as internal/legacy implementation details.
|
|
100
114
|
- Do not use raw `portal_*` writes or raw `qingbi_report_*` writes as the default builder strategy.
|
|
101
|
-
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default; `app_charts_apply` is immediate-live without publish.
|
|
115
|
+
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default; `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept a draft-only `publish` parameter; `app_charts_apply` is immediate-live without publish.
|
|
116
|
+
- When creating or updating fields, configure the app data title/cover directly in field JSON: `as_data_title: true` is required on exactly one readable top-level title field; `as_data_cover: true` is optional and only valid on one top-level `attachment` field.
|
|
102
117
|
- If the same validation error repeats twice, stop guessing and re-read `builder_tool_contract`.
|
|
103
118
|
- For workflow assignees, prefer `role_search` over explicit members unless the user explicitly wants named members.
|
|
104
119
|
- Public flow building is still intentionally limited to stable linear workflows. If a requirement sounds like branches/conditions, explain the limitation instead of freehanding unsupported graph shapes.
|
|
@@ -122,7 +137,7 @@ Treat these as the official surface. Do not default to `package_create`, `packag
|
|
|
122
137
|
- Read one package: `package_get`
|
|
123
138
|
- Create or update one package: `package_apply`
|
|
124
139
|
- Resolve one app: `app_resolve`
|
|
125
|
-
- Read one app
|
|
140
|
+
- Read one app map: `app_get`
|
|
126
141
|
- Read fields only: `app_get_fields`
|
|
127
142
|
- Read layout summary: `app_get_layout`
|
|
128
143
|
- Read views summary: `app_get_views`
|
|
@@ -135,11 +150,58 @@ Treat these as the official surface. Do not default to `package_create`, `packag
|
|
|
135
150
|
- Merge or replace layout: `app_layout_apply`
|
|
136
151
|
- Replace workflow: `app_flow_apply`
|
|
137
152
|
- Upsert/remove views: `app_views_apply`
|
|
153
|
+
- Upsert/remove custom buttons and bind them to header/detail view positions: `app_custom_buttons_apply`
|
|
154
|
+
- Manage app associated reports/views and per-view display: `app_associated_resources_apply`
|
|
138
155
|
- Upsert/remove/reorder charts: `app_charts_apply`
|
|
139
156
|
- Create or update portal pages: `portal_apply`
|
|
140
157
|
- Release your own stale edit lock: `app_release_edit_lock_if_mine`
|
|
141
158
|
- Final publish verification: `app_publish_verify`
|
|
142
159
|
|
|
160
|
+
## Button Pattern
|
|
161
|
+
|
|
162
|
+
Use `app_custom_buttons_apply` for the whole custom-button path: button body, add-data mapping, default values, and placement.
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"tool_name": "app_custom_buttons_apply",
|
|
167
|
+
"arguments": {
|
|
168
|
+
"app_key": "EMPLOYEE_APP",
|
|
169
|
+
"upsert_buttons": [
|
|
170
|
+
{
|
|
171
|
+
"client_key": "add_worklog",
|
|
172
|
+
"button_text": "快捷添加工时",
|
|
173
|
+
"style_preset": "primary_blue",
|
|
174
|
+
"button_icon": "ex-plus-circle",
|
|
175
|
+
"trigger_action": "addData",
|
|
176
|
+
"trigger_add_data_config": {
|
|
177
|
+
"target_app_key": "WORKLOG_APP",
|
|
178
|
+
"field_mappings": [
|
|
179
|
+
{"source_field": "员工名称", "target_field": "员工"},
|
|
180
|
+
{"source_field": "所属部门", "target_field": "部门"}
|
|
181
|
+
],
|
|
182
|
+
"default_values": {
|
|
183
|
+
"工时类型": "日常工作",
|
|
184
|
+
"状态": "待提交"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"remove_buttons": [],
|
|
190
|
+
"view_configs": [
|
|
191
|
+
{
|
|
192
|
+
"view_key": "EMPLOYEE_VIEW",
|
|
193
|
+
"mode": "merge",
|
|
194
|
+
"buttons": [
|
|
195
|
+
{"button_ref": "add_worklog", "placement": "detail", "primary": true}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`button_ref` may be a same-call `client_key` or an existing `button_id`. Default placements are `header` and `detail`; `list` is experimental and should only be used when the user explicitly asks for row/list buttons.
|
|
204
|
+
|
|
143
205
|
## Resources
|
|
144
206
|
|
|
145
207
|
- Shared public-surface baseline: [public-surface-sync.md](../qingflow-app-user/references/public-surface-sync.md)
|
|
@@ -79,8 +79,9 @@ Apply schema for a new app:
|
|
|
79
79
|
"create_if_missing": true,
|
|
80
80
|
"publish": true,
|
|
81
81
|
"add_fields": [
|
|
82
|
-
{"name": "订单编号", "type": "text", "required": true},
|
|
82
|
+
{"name": "订单编号", "type": "text", "required": true, "as_data_title": true},
|
|
83
83
|
{"name": "客户名称", "type": "text", "required": true},
|
|
84
|
+
{"name": "订单封面", "type": "attachment", "as_data_cover": true},
|
|
84
85
|
{"name": "订单金额", "type": "amount"},
|
|
85
86
|
{"name": "状态", "type": "single_select", "options": ["草稿", "进行中", "已完成"], "required": true}
|
|
86
87
|
],
|
|
@@ -90,6 +91,8 @@ Apply schema for a new app:
|
|
|
90
91
|
}
|
|
91
92
|
```
|
|
92
93
|
|
|
94
|
+
Data title is required: mark exactly one top-level field with `as_data_title: true`. Data cover is optional and only valid on a top-level `attachment` field.
|
|
95
|
+
|
|
93
96
|
## Common failures
|
|
94
97
|
|
|
95
98
|
### `APP_NOT_FOUND`
|
|
@@ -21,9 +21,21 @@
|
|
|
21
21
|
## Auto publish
|
|
22
22
|
|
|
23
23
|
- `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, and `app_views_apply` publish by default
|
|
24
|
-
-
|
|
24
|
+
- For those four tools, pass `publish=false` only when the user explicitly wants to leave changes in draft
|
|
25
|
+
- `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept `publish=false`
|
|
25
26
|
- `app_publish_verify` is for explicit final verification, not the default next step after every write
|
|
26
27
|
|
|
28
|
+
## Custom buttons
|
|
29
|
+
|
|
30
|
+
- 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.
|
|
31
|
+
- For add-data buttons, prefer semantic `trigger_add_data_config.target_app_key`, `field_mappings`, and `default_values`.
|
|
32
|
+
- 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.
|
|
33
|
+
- Default button placements are `header` and `detail`; these map to the frontend's header and detail button areas.
|
|
34
|
+
- `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.
|
|
35
|
+
- 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.
|
|
36
|
+
- 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.
|
|
37
|
+
- `placement=list` is experimental for row/list buttons. Some backend deployments still reject it. If the tool returns `LIST_BUTTON_BACKEND_UNSUPPORTED`, treat `header/detail` as applied when verified and report list placement as unsupported by the current backend route.
|
|
38
|
+
|
|
27
39
|
## Readback scope
|
|
28
40
|
|
|
29
41
|
- Prefer summary reads over large raw payloads
|
|
@@ -40,12 +40,14 @@ If the user asks for multiple forms/modules that relate to each other, this is a
|
|
|
40
40
|
|
|
41
41
|
## Apply tools
|
|
42
42
|
|
|
43
|
-
These execute normalized patches
|
|
43
|
+
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.
|
|
44
44
|
|
|
45
45
|
- `app_schema_apply`: create app shell or change fields
|
|
46
46
|
- `app_layout_apply`: merge or replace layout
|
|
47
47
|
- `app_flow_apply`: replace workflow
|
|
48
48
|
- `app_views_apply`: upsert or remove views
|
|
49
|
+
- `app_custom_buttons_apply`: create, update, or remove custom buttons; configure add-data field mappings/default values; bind buttons to header/detail view positions; merge-mode view configs require `buttons`; use `view_configs[].mode="replace"` or `buttons=[]` to clear a view's custom button bindings; `placement=list` is experimental
|
|
50
|
+
- `app_associated_resources_apply`: manage app associated reports/views and per-view display config; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only for BI dataset reports
|
|
49
51
|
- `app_charts_apply`: upsert/remove/reorder QingBI charts; charts are immediate-live and do not publish; use `chart_id` when names are not unique
|
|
50
52
|
- `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
|
|
51
53
|
|
|
@@ -32,10 +32,12 @@ Apply the patch:
|
|
|
32
32
|
"app_key": "APP_123",
|
|
33
33
|
"publish": true,
|
|
34
34
|
"add_fields": [
|
|
35
|
-
{"name": "跟进日期", "type": "date"}
|
|
35
|
+
{"name": "跟进日期", "type": "date"},
|
|
36
|
+
{"name": "数据封面", "type": "attachment", "as_data_cover": true}
|
|
36
37
|
],
|
|
37
38
|
"update_fields": [
|
|
38
|
-
{"selector": {"name": "金额"}, "set": {"name": "订单金额", "required": true}}
|
|
39
|
+
{"selector": {"name": "金额"}, "set": {"name": "订单金额", "required": true}},
|
|
40
|
+
{"selector": {"name": "客户名称"}, "set": {"as_data_title": true}}
|
|
39
41
|
],
|
|
40
42
|
"remove_fields": [
|
|
41
43
|
{"name": "旧字段"}
|
|
@@ -66,3 +68,5 @@ Treat it as uncertain write state. Read back with `app_get_fields` before retryi
|
|
|
66
68
|
- `mobile -> phone`
|
|
67
69
|
- `select/radio -> single_select`
|
|
68
70
|
- `checkbox -> multi_select`
|
|
71
|
+
- `as_data_title: true` marks the app data title; the final form must have exactly one top-level data title field
|
|
72
|
+
- `as_data_cover: true` marks the app data cover; the cover is optional and must be a top-level `attachment` field
|
|
@@ -6,17 +6,20 @@ Use this when the task is only about table, card, board, or gantt views.
|
|
|
6
6
|
|
|
7
7
|
1. `builder_tool_contract(tool_name="app_views_apply")`
|
|
8
8
|
2. `app_get_fields`
|
|
9
|
-
3. `
|
|
9
|
+
3. `app_get` for current view/chart/button inventory and app-level associated resource ids
|
|
10
10
|
4. `app_views_apply`
|
|
11
|
-
5. `
|
|
11
|
+
5. Use `app_associated_resources_apply` if the task includes associated reports/views
|
|
12
|
+
6. `app_get` or `view_get` again whenever apply returns `failed` or `partial_success`
|
|
12
13
|
|
|
13
14
|
If you are unsure about keys or view types, call `builder_tool_contract(tool_name="app_views_apply")` before guessing.
|
|
14
15
|
|
|
15
16
|
Important verification rule:
|
|
16
17
|
|
|
17
18
|
- `app_views_apply` can create a view object before every filter is fully verified in readback
|
|
18
|
-
- Do not report “筛选已成功应用” unless the apply result also shows `verification.views_verified=true`
|
|
19
|
-
-
|
|
19
|
+
- Do not report “筛选已成功应用” unless the apply result also shows `verification.views_verified=true` and `verification.view_filters_verified=true`
|
|
20
|
+
- Do not report “查询条件已成功配置” unless the apply result also shows `verification.view_query_conditions_verified=true`
|
|
21
|
+
- Do not report “关联资源已成功配置” unless `app_associated_resources_apply` shows `verification.associated_resource_view_configs_verified=true`
|
|
22
|
+
- If apply returns `partial_success`, inspect `verification.by_view`, `details.filter_mismatches`, `details.query_condition_mismatches`, and `details.associated_resource_mismatches` before claiming filters/query conditions/associated resources are active
|
|
20
23
|
|
|
21
24
|
## Example
|
|
22
25
|
|
|
@@ -26,8 +29,10 @@ Canonical rules before any example:
|
|
|
26
29
|
- Do not emit `column_names`
|
|
27
30
|
- Treat `fields` only as a legacy alias the MCP may normalize, not as the preferred shape
|
|
28
31
|
- Use `filters` with canonical keys `field_name`, `operator`, `value`/`values`
|
|
32
|
+
- Use `query_conditions` for the frontend query panel. Do not put query-panel fields into `filters`.
|
|
33
|
+
- Use `app_associated_resources_apply` for the frontend associated report/view area. `associated_item_id` must be copied from `app_get.associated_resources[].associated_item_id`; it is not `chart_id` or `chart_key`. Do not write backend raw `sourceType`; reports default to BI app reports, and dataset reports use `report_source="dataset"`.
|
|
29
34
|
- For gantt, use `start_field`, `end_field`, and optionally `title_field`
|
|
30
|
-
- If `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
|
|
35
|
+
- If `app_get.views` or `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
|
|
31
36
|
|
|
32
37
|
Apply a default table view:
|
|
33
38
|
|
|
@@ -52,6 +57,102 @@ Apply a default table view:
|
|
|
52
57
|
```
|
|
53
58
|
After `app_views_apply` returns canonical arguments or blocking issues, prefer reusing its `suggested_next_call.arguments` directly. Do not rewrite aliases back into non-canonical keys such as `column_names`.
|
|
54
59
|
|
|
60
|
+
Table view with fixed filter plus frontend query conditions:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"tool_name": "app_views_apply",
|
|
65
|
+
"arguments": {
|
|
66
|
+
"profile": "default",
|
|
67
|
+
"app_key": "APP_123",
|
|
68
|
+
"publish": true,
|
|
69
|
+
"upsert_views": [
|
|
70
|
+
{
|
|
71
|
+
"name": "客户查询视图",
|
|
72
|
+
"type": "table",
|
|
73
|
+
"columns": ["客户名称", "负责人", "客户状态", "创建时间"],
|
|
74
|
+
"filters": [
|
|
75
|
+
{
|
|
76
|
+
"field_name": "客户状态",
|
|
77
|
+
"operator": "eq",
|
|
78
|
+
"value": "有效"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"query_conditions": {
|
|
82
|
+
"enabled": true,
|
|
83
|
+
"exact": false,
|
|
84
|
+
"hide_before_query": false,
|
|
85
|
+
"rows": [["客户名称", "负责人"], ["创建时间"]]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"remove_views": []
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Meaning:
|
|
95
|
+
|
|
96
|
+
- `filters` are saved view filters and apply immediately when the view opens.
|
|
97
|
+
- `query_conditions` only configures which fields appear in the frontend query panel. The query values come later from the user through the page.
|
|
98
|
+
- `query_conditions.rows` is a matrix of field names and is compiled to backend `queryCondition` field ids.
|
|
99
|
+
|
|
100
|
+
View associated resources example:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"tool_name": "app_associated_resources_apply",
|
|
105
|
+
"arguments": {
|
|
106
|
+
"profile": "default",
|
|
107
|
+
"app_key": "APP_123",
|
|
108
|
+
"upsert_resources": [],
|
|
109
|
+
"remove_associated_item_ids": [],
|
|
110
|
+
"reorder_associated_item_ids": [],
|
|
111
|
+
"view_configs": [
|
|
112
|
+
{
|
|
113
|
+
"view_key": "VIEW_KEY",
|
|
114
|
+
"visible": true,
|
|
115
|
+
"limit_type": "select",
|
|
116
|
+
"associated_item_ids": [123, 124]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use `{"visible": true, "limit_type": "all"}` to show all app-level associated resources, and `{"visible": false}` to hide the area. The ids above must come from `app_get.associated_resources`. If you create a new associated item in the same call, give it a `client_key` and reference it from `view_configs[].associated_item_refs`.
|
|
124
|
+
|
|
125
|
+
Create and show a BI indicator-card report in the same call:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"tool_name": "app_associated_resources_apply",
|
|
130
|
+
"arguments": {
|
|
131
|
+
"profile": "default",
|
|
132
|
+
"app_key": "APP_123",
|
|
133
|
+
"upsert_resources": [
|
|
134
|
+
{
|
|
135
|
+
"client_key": "total_hours_card",
|
|
136
|
+
"graph_type": "chart",
|
|
137
|
+
"target_app_key": "TIMESHEET_APP",
|
|
138
|
+
"chart_key": "CHART_KEY",
|
|
139
|
+
"report_source": "app"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"remove_associated_item_ids": [],
|
|
143
|
+
"reorder_associated_item_ids": [],
|
|
144
|
+
"view_configs": [
|
|
145
|
+
{
|
|
146
|
+
"view_key": "VIEW_KEY",
|
|
147
|
+
"visible": true,
|
|
148
|
+
"limit_type": "select",
|
|
149
|
+
"associated_item_refs": ["total_hours_card"]
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
55
156
|
Board example:
|
|
56
157
|
|
|
57
158
|
```json
|
|
@@ -151,6 +252,25 @@ Treat this as:
|
|
|
151
252
|
|
|
152
253
|
Do not tell the user the filter is active until the readback verification matches the intended filter.
|
|
153
254
|
|
|
255
|
+
### `VIEW_QUERY_CONDITION_READBACK_MISMATCH`
|
|
256
|
+
|
|
257
|
+
The view object was created or updated, but the readback config did not keep the intended frontend query-condition settings.
|
|
258
|
+
|
|
259
|
+
Treat this as:
|
|
260
|
+
|
|
261
|
+
- the view exists
|
|
262
|
+
- the query panel configuration is **not yet verified**
|
|
263
|
+
|
|
264
|
+
Do not tell the user the query condition is active until readback matches the intended `query_conditions`.
|
|
265
|
+
|
|
266
|
+
### `QUERY_CONDITION_FIELD_NOT_FOUND`
|
|
267
|
+
|
|
268
|
+
At least one `query_conditions.rows` field does not exist on the app.
|
|
269
|
+
|
|
270
|
+
### `INVALID_QUERY_CONDITION_FIELD`
|
|
271
|
+
|
|
272
|
+
The field exists but cannot be used in the frontend query-condition panel, such as attachment, relation, Q-Linker, code block, location/address, or subtable/subfield selections.
|
|
273
|
+
|
|
154
274
|
## Notes
|
|
155
275
|
|
|
156
276
|
- `fields` is accepted as an alias for `columns`, but skill examples should still use `columns`
|
|
@@ -158,5 +278,6 @@ Do not tell the user the filter is active until the readback verification matche
|
|
|
158
278
|
- `app_get_views` should be treated as canonical readback and now returns `columns`
|
|
159
279
|
- If `app_views_apply` returns `AMBIGUOUS_VIEW`, stop and re-run `app_get_views`; then retry with the exact `view_key`
|
|
160
280
|
- `filters` are ANDed together as one flat condition group
|
|
281
|
+
- `query_conditions.rows` does not mean OR; it controls frontend query-field layout
|
|
161
282
|
- `app_views_apply` publishes by default
|
|
162
283
|
- For select-style filters, success means the backend preserved the option value in readback, not just that the view name now exists
|