@josephyan/qingflow-app-builder-mcp 1.1.26 → 1.1.28

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.
@@ -1,428 +1,234 @@
1
- # Build Complete System(完整系统搭建)
1
+ # Build Complete System
2
2
 
3
- Use this when the user wants a multi-app business system: multiple related forms, shared workflow, cross-app relation fields, a portal dashboard, and sample data.
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.
4
5
 
5
- **Signal phrases**: "建一套系统"、"包含 X 个模块"、"这几个表单之间建立关联"、"完整的业务系统"
6
+ ## Main Chain
6
7
 
7
- For a single new app inside an existing package, use [create-app.md](./create-app.md) instead.
8
-
9
- ---
10
-
11
- ## Execution order (never reorder)
12
-
13
- ```
14
- Phase 0 → Phase 1 → [Phase 2 → 3 → 4] per app → Phase 5 → Phase 6 → Phase 7
15
- ```
16
-
17
- - Phase 1 (schema) must complete for **all apps** before Phase 2/3/4 begins — all `app_key` values must be known first
18
- - Phase 5 (portal) runs after **all** Phase 4 views are created — `view_key` values must be available
19
- - Phase 6 (data) runs after Phase 5 — fields and flows must be live before inserting records
20
-
21
- ---
22
-
23
- ## Phase 0 — Scan workspace packages
24
-
25
- ```json
26
- {"tool_name": "package_list", "arguments": {"profile": "default"}}
27
- ```
28
-
29
- - **Package name already exists in workspace** → tell the user, wait for explicit confirmation before continuing
30
- - **Package name not in workspace** → run `package_apply` immediately, no confirmation needed:
31
-
32
- ```json
33
- {
34
- "tool_name": "package_apply",
35
- "arguments": {
36
- "profile": "default",
37
- "package_name": "客户管理系统",
38
- "create_if_missing": true
39
- }
40
- }
8
+ ```text
9
+ package_apply
10
+ -> app_schema_apply(apps[] with fields, relations, form.sections)
11
+ -> app_views_apply(views[])
12
+ -> portal_apply(sections[] with inline QingBI chart)
13
+ -> workflow / associated resources only when requested or required
14
+ -> readback + publish/visibility summary
41
15
  ```
42
16
 
43
- Record the returned `package_id`. All subsequent phases use it.
44
-
45
- ---
17
+ This is the only recommended chain for a new complete system. Do not split it into separate app creates, separate layout writes, or separate chart creation before portal.
46
18
 
47
- ## Phase 1 — Create all apps and fields in one call
19
+ ## Required Shape
48
20
 
49
- > **Read first**: [update-schema.md](./update-schema.md)
21
+ - Create or resolve the package with `package_apply` / `package_get`.
22
+ - Create all related apps in one `app_schema_apply(package_id=..., apps=[...])`.
23
+ - Every app item must include stable `client_key`, `app_name`, `icon`, `color`, `add_fields`, and exactly one readable `as_data_title: true`.
24
+ - Put form layout directly in `apps[].form.sections`. Do not make `app_layout_apply` a standard second step for new apps.
25
+ - Same-call relations must use `target_app_ref` pointing to another `apps[].client_key`.
26
+ - Use `target_app_key` only for an app that already exists and has been confirmed by readback.
27
+ - Do not create platform fields: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`.
50
28
 
51
- ### Field count requirement
52
-
53
- **12–20 fields per app.** Distribute across types:
54
-
55
- | Type | Count per app | Examples |
56
- |------|--------------|---------|
57
- | `text` / `long_text` | 2–3 | 名称、编号、描述 |
58
- | `single_select` / `multi_select` | 2–4 | 状态、类型、优先级、阶段 |
59
- | `date` / `datetime` | 1–2 | 开始日期、截止日期 |
60
- | `number` / `amount` | 1–3 | 金额、数量、完成率 |
61
- | `member` | 1–2 | 负责人、创建人 |
62
- | `attachment` | 0–1 | 封面图或附件 |
63
- | `relation` | 1–2 | 跨表关联字段 |
64
-
65
- ### Hard rules
66
-
67
- - Exactly one top-level field per app must have `as_data_title: true`
68
- - Every `relation` field must include both `display_field: {"name": "..."}` and `visible_fields: [{"name": "..."}]` — missing either causes `VALIDATION_ERROR` and the entire batch fails with `write_executed=false`; read the `message` field verbatim first before guessing at other causes
69
- - Use `target_app_ref` to reference another app in the same batch by its `client_key`; do not create apps separately and patch relations later
70
- - If part of the batch fails, only resubmit the failed apps by `row_number`; do not resubmit the entire batch
71
-
72
- ### Example (customer + opportunity system)
29
+ ## Schema Payload Pattern
73
30
 
74
31
  ```json
75
32
  {
76
- "tool_name": "app_schema_apply",
77
- "arguments": {
78
- "profile": "default",
79
- "package_id": 1218950,
80
- "create_if_missing": true,
81
- "publish": true,
82
- "apps": [
83
- {
84
- "client_key": "customer",
85
- "app_name": "客户",
86
- "add_fields": [
87
- {"name": "客户名称", "type": "text", "required": true, "as_data_title": true},
88
- {"name": "客户编号", "type": "text"},
89
- {"name": "客户类型", "type": "single_select", "options": ["企业", "个人", "政府"]},
90
- {"name": "行业", "type": "single_select", "options": ["制造业", "互联网", "金融", "零售", "其他"]},
91
- {"name": "客户状态", "type": "single_select", "options": ["潜在", "跟进中", "已签约", "流失"]},
92
- {"name": "负责人", "type": "member"},
93
- {"name": "联系人", "type": "text"},
94
- {"name": "联系电话", "type": "phone"},
95
- {"name": "所在地区", "type": "address"},
96
- {"name": "首次合作日期", "type": "date"},
97
- {"name": "累计合同金额", "type": "amount"},
98
- {"name": "客户简介", "type": "long_text"},
99
- {"name": "客户封面", "type": "attachment", "as_data_cover": true}
100
- ]
101
- },
102
- {
103
- "client_key": "opportunity",
104
- "app_name": "商机",
105
- "add_fields": [
106
- {"name": "商机名称", "type": "text", "required": true, "as_data_title": true},
107
- {"name": "关联客户", "type": "relation", "target_app_ref": "customer",
108
- "display_field": {"name": "客户名称"}, "visible_fields": [{"name": "客户名称"}, {"name": "客户类型"}]},
109
- {"name": "商机阶段", "type": "single_select", "options": ["初步接触", "需求确认", "方案报价", "商务谈判", "赢单", "输单"]},
110
- {"name": "预计金额", "type": "amount"},
111
- {"name": "赢单概率", "type": "number"},
112
- {"name": "负责人", "type": "member"},
113
- {"name": "预计成交日期", "type": "date"},
114
- {"name": "商机来源", "type": "single_select", "options": ["官网", "转介绍", "市场活动", "电话开发", "其他"]},
115
- {"name": "竞争对手", "type": "text"},
116
- {"name": "跟进记录", "type": "long_text"},
117
- {"name": "优先级", "type": "single_select", "options": ["高", "中", "低"]},
118
- {"name": "创建日期", "type": "date"}
33
+ "package_id": 123,
34
+ "apps": [
35
+ {
36
+ "client_key": "customer",
37
+ "app_name": "客户",
38
+ "icon": "user-group",
39
+ "color": "blue",
40
+ "add_fields": [
41
+ {"name": "客户名称", "type": "text", "as_data_title": true},
42
+ {"name": "客户状态", "type": "select", "options": ["潜在", "跟进中", "已成交"]},
43
+ {"name": "负责人", "type": "member"}
44
+ ],
45
+ "form": {
46
+ "sections": [
47
+ {"title": "基础信息", "rows": [["客户名称", "客户状态"], ["负责人"]]}
119
48
  ]
120
49
  }
121
- ]
122
- }
123
- }
124
- ```
125
-
126
- Record all `app_key` values from the response. Do not proceed to Phase 2 until all apps show `status: created`.
127
-
128
- ---
129
-
130
- ## Phase 2 — Per-app: Layout
131
-
132
- > **Read first**: [update-layout.md](./update-layout.md)
133
-
134
- Run for each app in sequence. Group fields into logical sections with 2–3 fields per row.
135
-
136
- ```json
137
- {
138
- "tool_name": "app_layout_apply",
139
- "arguments": {
140
- "profile": "default",
141
- "app_key": "APP_KEY",
142
- "mode": "merge",
143
- "publish": true,
144
- "sections": [
145
- {
146
- "title": "基础信息",
147
- "rows": [
148
- ["客户名称", "客户编号"],
149
- ["客户类型", "行业"],
150
- ["客户状态", "负责人"]
50
+ },
51
+ {
52
+ "client_key": "opportunity",
53
+ "app_name": "商机",
54
+ "icon": "business-trend-up",
55
+ "color": "green",
56
+ "add_fields": [
57
+ {"name": "商机名称", "type": "text", "as_data_title": true},
58
+ {
59
+ "name": "关联客户",
60
+ "type": "relation",
61
+ "target_app_ref": "customer",
62
+ "display_field": {"name": "客户名称"},
63
+ "visible_fields": [{"name": "客户名称"}, {"name": "客户状态"}]
64
+ },
65
+ {"name": "商机阶段", "type": "select", "options": ["初步接触", "方案报价", "赢单", "输单"]},
66
+ {"name": "预计金额", "type": "amount"}
67
+ ],
68
+ "form": {
69
+ "sections": [
70
+ {"title": "基础信息", "rows": [["商机名称", "关联客户"], ["商机阶段", "预计金额"]]}
151
71
  ]
152
- },
153
- {
154
- "title": "联系信息",
155
- "rows": [
156
- ["联系人", "联系电话"],
157
- ["所在地区"]
158
- ]
159
- },
160
- {
161
- "title": "业务数据",
162
- "rows": [
163
- ["首次合作日期", "累计合同金额"],
164
- ["客户简介"]
165
- ]
166
- }
167
- ]
168
- }
169
- }
170
- ```
171
-
172
- ---
173
-
174
- ## Phase 3 — Per-app: Flow
175
-
176
- > **Read first**: [update-flow.md](./update-flow.md) and [flow-actors-and-permissions.md](./flow-actors-and-permissions.md)
177
-
178
- Run for each app. Search for an existing role first; create one if none fits.
179
-
180
- ```json
181
- {"tool_name": "role_search", "arguments": {"profile": "default", "query": "审批"}}
182
- ```
183
-
184
- ```json
185
- {
186
- "tool_name": "app_flow_apply",
187
- "arguments": {
188
- "profile": "default",
189
- "app_key": "APP_KEY",
190
- "preset": "basic_approval",
191
- "publish": true,
192
- "nodes": [
193
- {
194
- "id": "approve_1",
195
- "type": "approve",
196
- "name": "主管审批",
197
- "assignees": {"role_names": ["部门主管"]},
198
- "permissions": {"editable_fields": ["客户状态"]}
199
72
  }
200
- ]
201
- }
73
+ }
74
+ ]
202
75
  }
203
76
  ```
204
77
 
205
- ---
206
-
207
- ## Phase 4 — Per-app: Views (multiple types)
78
+ Agent-friendly field type aliases are allowed: `multiline -> long_text`, `select -> single_select`, `amount -> amount`. Readback may show canonical types; do not treat that as a mismatch.
208
79
 
209
- > **Read first**: [update-views.md](./update-views.md)
80
+ ## Views
210
81
 
211
- Build all applicable view types for each app in one `app_views_apply` call. All views require `query_conditions` with `enabled: true`.
212
-
213
- | Type | Build condition | Key config |
214
- |------|----------------|------------|
215
- | **table** | Always — build first | `columns` + `query_conditions` on title / status / date / member fields |
216
- | **board** | App has a `single_select` status or stage field | `group_by` = that field name |
217
- | **gantt** | App has two date fields | `start_field` + `end_field` |
218
- | **card** | App has an `attachment` field with `as_data_cover: true` | Visual browsing; same `query_conditions` |
82
+ - Use one `app_views_apply(views=[...])` batch for same-app and cross-app views.
83
+ - Do not create platform default views named `全部数据`, `我的数据`, `我发起的`, `待办`, `已办`, or `抄送`.
84
+ - Use business-specific view names.
85
+ - If a view needs business actions, put them directly inside that view item with `action_buttons`.
86
+ - Keep `filters` and `query_conditions` separate:
87
+ - `filters`: fixed saved filters.
88
+ - `query_conditions`: frontend query panel fields.
219
89
 
220
90
  ```json
221
91
  {
222
- "tool_name": "app_views_apply",
223
- "arguments": {
224
- "profile": "default",
225
- "app_key": "APP_KEY",
226
- "publish": true,
227
- "upsert_views": [
228
- {
229
- "name": "全部客户",
230
- "type": "table",
231
- "columns": ["客户名称", "客户类型", "客户状态", "负责人", "首次合作日期", "累计合同金额"],
232
- "query_conditions": {
233
- "enabled": true,
234
- "exact": false,
235
- "hide_before_query": false,
236
- "rows": [["客户名称", "客户类型"], ["客户状态", "负责人"]]
237
- }
238
- },
239
- {
240
- "name": "客户看板",
241
- "type": "board",
242
- "columns": ["客户名称", "客户类型", "负责人", "累计合同金额"],
243
- "group_by": "客户状态",
244
- "query_conditions": {
245
- "enabled": true,
246
- "exact": false,
247
- "hide_before_query": false,
248
- "rows": [["客户名称", "负责人"]]
249
- }
92
+ "views": [
93
+ {
94
+ "operation": "upsert",
95
+ "app_key": "CUSTOMER_APP_KEY",
96
+ "name": "客户跟进视图",
97
+ "type": "table",
98
+ "columns": ["客户名称", "客户状态", "负责人"],
99
+ "query_conditions": {
100
+ "enabled": true,
101
+ "rows": [["客户名称", "客户状态"], ["负责人"]]
250
102
  },
251
- {
252
- "name": "客户卡片",
253
- "type": "card",
254
- "columns": ["客户名称", "客户类型", "客户状态", "负责人"],
255
- "query_conditions": {
256
- "enabled": true,
257
- "exact": false,
258
- "hide_before_query": false,
259
- "rows": [["客户名称", "客户状态"]]
103
+ "action_buttons": [
104
+ {
105
+ "text": "新建商机",
106
+ "action": "add_data",
107
+ "target_app_key": "OPPORTUNITY_APP_KEY",
108
+ "placement": "detail",
109
+ "field_mappings": [
110
+ {"source_field": "数据ID", "target_field": "关联客户"}
111
+ ]
260
112
  }
261
- }
262
- ]
263
- }
113
+ ]
114
+ }
115
+ ]
264
116
  }
265
117
  ```
266
118
 
267
- Record all `view_key` values from the response before proceeding to Phase 5.
268
-
269
- ---
270
-
271
- ## Phase 5 — Charts + Portal
272
-
273
- > **Read first**: [tool-selection.md — portal_apply section](./tool-selection.md)
119
+ ## Portal
274
120
 
275
- ### 5.1 Build charts 8 total
121
+ Use `portal_apply` only after apps and view keys are read back. QingBI charts for the portal are created inline in `sections[].chart`; do not pre-create charts as a separate standard step.
276
122
 
277
- **4 indicator cards + 4 visual charts.** Build via `app_charts_apply` per app and record all `chart_id` values before calling `portal_apply`.
123
+ Portal layout rules:
278
124
 
279
- | Row | Count | Type | Examples |
280
- |-----|-------|------|---------|
281
- | Indicator row | 4 | `target`(指标卡) | 客户总数、商机总金额、赢单数、合同总额 |
282
- | Visual row 1 | 2 | `funnel` / `columnar` | 商机阶段漏斗、客户类型分布 |
283
- | Visual row 2 | 2 | `area` / `columnar` | 月度商机趋势、合同金额趋势 |
284
-
285
- ### 5.2 Portal layout
286
-
287
- ```
288
- y=0, rows=4: 九宫格业务入口 (cols=24)
289
- y=4, rows=3: 指标1(x=0,cols=6) 指标2(x=6,cols=6) 指标3(x=12,cols=6) 指标4(x=18,cols=6)
290
- y=7, rows=8: 可视化图1(x=0,cols=12) 可视化图2(x=12,cols=12)
291
- y=15, rows=8: 可视化图3(x=0,cols=12) 可视化图4(x=12,cols=12)
292
- y=23, rows=8: 数据视图 (cols=24)
293
- ```
294
-
295
- Same-row rule: all components at the same `y` must have identical `rows` and `cols` summing to 24.
125
+ - PC grid has 24 columns.
126
+ - Components in the same row must share the same `y` and `rows`.
127
+ - Same-row `cols` should sum to 24.
128
+ - Recommended order: business entry -> metric cards -> BI charts -> concrete data views.
129
+ - Business entry `grid` must contain real `config.items[]`; never submit an empty grid container.
130
+ - Metric cards: `rows=5`.
131
+ - BI charts: `rows=7`.
132
+ - Data views: `rows=11`.
133
+ - Do not use platform default views such as `全部数据` / `我的数据` as main portal data views.
296
134
 
297
135
  ```json
298
- {
299
- "tool_name": "portal_apply",
300
- "arguments": {
301
- "profile": "default",
302
- "package_id": 1218950,
303
- "dash_name": "客户管理工作台",
304
- "publish": true,
305
- "sections": [
306
- {
307
- "title": "业务入口",
308
- "source_type": "grid",
309
- "position": {"pc": {"x": 0, "y": 0, "cols": 24, "rows": 4}, "mobile": {"x": 0, "y": 0, "cols": 6, "rows": 4}},
310
- "config": {"gridTitle": "业务入口", "beingShowTitle": true}
311
- },
312
- {
313
- "title": "客户总数",
314
- "source_type": "chart",
315
- "position": {"pc": {"x": 0, "y": 4, "cols": 6, "rows": 3}, "mobile": {"x": 0, "y": 4, "cols": 6, "rows": 3}},
316
- "chart_ref": {"app_key": "CUSTOMER_APP_KEY", "chart_id": "INDICATOR_CHART_ID_1"}
317
- },
318
- {
319
- "title": "商机总金额",
320
- "source_type": "chart",
321
- "position": {"pc": {"x": 6, "y": 4, "cols": 6, "rows": 3}, "mobile": {"x": 0, "y": 7, "cols": 6, "rows": 3}},
322
- "chart_ref": {"app_key": "OPPORTUNITY_APP_KEY", "chart_id": "INDICATOR_CHART_ID_2"}
323
- },
324
- {
325
- "title": "赢单数",
326
- "source_type": "chart",
327
- "position": {"pc": {"x": 12, "y": 4, "cols": 6, "rows": 3}, "mobile": {"x": 0, "y": 10, "cols": 6, "rows": 3}},
328
- "chart_ref": {"app_key": "OPPORTUNITY_APP_KEY", "chart_id": "INDICATOR_CHART_ID_3"}
329
- },
330
- {
331
- "title": "合同总额",
332
- "source_type": "chart",
333
- "position": {"pc": {"x": 18, "y": 4, "cols": 6, "rows": 3}, "mobile": {"x": 0, "y": 13, "cols": 6, "rows": 3}},
334
- "chart_ref": {"app_key": "CONTRACT_APP_KEY", "chart_id": "INDICATOR_CHART_ID_4"}
335
- },
336
- {
337
- "title": "商机阶段漏斗",
338
- "source_type": "chart",
339
- "position": {"pc": {"x": 0, "y": 7, "cols": 12, "rows": 8}, "mobile": {"x": 0, "y": 16, "cols": 6, "rows": 8}},
340
- "chart_ref": {"app_key": "OPPORTUNITY_APP_KEY", "chart_id": "VISUAL_CHART_ID_1"}
341
- },
342
- {
343
- "title": "客户类型分布",
344
- "source_type": "chart",
345
- "position": {"pc": {"x": 12, "y": 7, "cols": 12, "rows": 8}, "mobile": {"x": 0, "y": 24, "cols": 6, "rows": 8}},
346
- "chart_ref": {"app_key": "CUSTOMER_APP_KEY", "chart_id": "VISUAL_CHART_ID_2"}
347
- },
348
- {
349
- "title": "月度商机趋势",
350
- "source_type": "chart",
351
- "position": {"pc": {"x": 0, "y": 15, "cols": 12, "rows": 8}, "mobile": {"x": 0, "y": 32, "cols": 6, "rows": 8}},
352
- "chart_ref": {"app_key": "OPPORTUNITY_APP_KEY", "chart_id": "VISUAL_CHART_ID_3"}
353
- },
354
- {
355
- "title": "合同金额趋势",
356
- "source_type": "chart",
357
- "position": {"pc": {"x": 12, "y": 15, "cols": 12, "rows": 8}, "mobile": {"x": 0, "y": 40, "cols": 6, "rows": 8}},
358
- "chart_ref": {"app_key": "CONTRACT_APP_KEY", "chart_id": "VISUAL_CHART_ID_4"}
359
- },
360
- {
361
- "title": "客户列表",
362
- "source_type": "view",
363
- "position": {"pc": {"x": 0, "y": 23, "cols": 24, "rows": 8}, "mobile": {"x": 0, "y": 48, "cols": 6, "rows": 8}},
364
- "view_ref": {"app_key": "CUSTOMER_APP_KEY", "view_key": "CUSTOMER_TABLE_VIEW_KEY"}
365
- }
366
- ]
136
+ [
137
+ {
138
+ "title": "业务入口",
139
+ "source_type": "grid",
140
+ "position": {
141
+ "pc": {"x": 0, "y": 0, "cols": 24, "rows": 4},
142
+ "mobile": {"x": 0, "y": 0, "cols": 6, "rows": 4}
143
+ },
144
+ "config": {
145
+ "items": [
146
+ {"type": 1, "jumpMode": 1, "linkAppKey": "CUSTOMER_APP_KEY", "linkFormType": 1, "title": "客户"},
147
+ {"type": 1, "jumpMode": 1, "linkAppKey": "OPPORTUNITY_APP_KEY", "linkFormType": 1, "title": "商机"}
148
+ ]
149
+ }
150
+ },
151
+ {
152
+ "title": "客户总数",
153
+ "source_type": "chart",
154
+ "role": "metric",
155
+ "position": {
156
+ "pc": {"x": 0, "y": 4, "cols": 6, "rows": 5},
157
+ "mobile": {"x": 0, "y": 4, "cols": 6, "rows": 5}
158
+ },
159
+ "chart": {
160
+ "app_key": "CUSTOMER_APP_KEY",
161
+ "name": "客户总数",
162
+ "chart_type": "target",
163
+ "metric": "count(*)"
164
+ }
165
+ },
166
+ {
167
+ "title": "客户状态分布",
168
+ "source_type": "chart",
169
+ "position": {
170
+ "pc": {"x": 0, "y": 9, "cols": 8, "rows": 7},
171
+ "mobile": {"x": 0, "y": 9, "cols": 6, "rows": 7}
172
+ },
173
+ "chart": {
174
+ "app_key": "CUSTOMER_APP_KEY",
175
+ "name": "客户状态分布",
176
+ "chart_type": "bar",
177
+ "group_by": ["客户状态"],
178
+ "metric": "count(*)"
179
+ }
180
+ },
181
+ {
182
+ "title": "客户跟进视图",
183
+ "source_type": "view",
184
+ "position": {
185
+ "pc": {"x": 0, "y": 16, "cols": 12, "rows": 11},
186
+ "mobile": {"x": 0, "y": 16, "cols": 6, "rows": 11}
187
+ },
188
+ "view_ref": {"app_key": "CUSTOMER_APP_KEY", "view_key": "CUSTOMER_VIEW_KEY"}
367
189
  }
368
- }
190
+ ]
369
191
  ```
370
192
 
371
- ---
193
+ ## Optional Resources
372
194
 
373
- ## Phase 6 Sample data
195
+ Only add workflow or associated resources when the user asks for them or the business process cannot work without them.
374
196
 
375
- > **Hand off to `qingflow-record-insert` skill**. Read the record-insert skill docs before inserting.
197
+ - Workflow: use `app_flow_apply` after schema fields exist.
198
+ - Associated resources: use `app_associated_resources_apply` after target views/charts exist.
376
199
 
377
- **Insertion order**: insert apps with no inbound relation dependencies first. If App A has a relation field pointing to App B, insert B's records before A — otherwise the relation field has no candidates.
200
+ Do not create workflow just to make the system look complete.
378
201
 
379
- Per app: insert **3–5 records** covering different status values and realistic business data.
202
+ ## Recovery
380
203
 
381
- ```json
382
- {"tool_name": "record_insert_schema_get", "arguments": {"profile": "default", "app_key": "APP_KEY"}}
383
- ```
204
+ - Timeout, `partial_success`, `write_executed=true`, `safe_to_retry=false`, or incomplete readback means write state is uncertain, not definitely failed.
205
+ - Next action is always readback: package -> app resolve -> fields/views/portal as needed.
206
+ - Retry only verified missing or incorrect slices.
207
+ - Do not create `V2`, `测试`, timestamp, or random-suffix apps to bypass conflicts.
208
+
209
+ ## Final Summary
210
+
211
+ Before final response, write `tmp/qingflow_system_build_summary.json` and make the response match it:
384
212
 
385
213
  ```json
386
214
  {
387
- "tool_name": "record_insert",
388
- "arguments": {
389
- "profile": "default",
390
- "app_key": "APP_KEY",
391
- "items": [
392
- {"客户名称": "上海科技有限公司", "客户类型": "企业", "客户状态": "已签约", "负责人": "张三", "累计合同金额": 1200000},
393
- {"客户名称": "北京创新集团", "客户类型": "企业", "客户状态": "跟进中", "负责人": "李四", "累计合同金额": 500000},
394
- {"客户名称": "广州贸易公司", "客户类型": "企业", "客户状态": "潜在", "负责人": "王五", "累计合同金额": 0},
395
- {"客户名称": "深圳数字科技", "客户类型": "企业", "客户状态": "跟进中", "负责人": "张三", "累计合同金额": 300000},
396
- {"客户名称": "杭州云计算公司", "客户类型": "企业", "客户状态": "已签约", "负责人": "李四", "累计合同金额": 800000}
397
- ]
398
- }
215
+ "package_id": 0,
216
+ "package_name": "",
217
+ "portal_dash_key": "",
218
+ "portal_live_status": "verified | unverified | not_created",
219
+ "front_end_visible": true,
220
+ "apps": [],
221
+ "warnings": [],
222
+ "partial_items": [],
223
+ "needs_followup": []
399
224
  }
400
225
  ```
401
226
 
402
- Member, department, and relation fields accept natural language values — do not look up IDs manually.
403
-
404
- ---
405
-
406
- ## Phase 7 — Publish verify
227
+ Final response must state:
407
228
 
408
- Run `app_publish_verify` with `app_keys[]` for all apps in one call. Confirm `publish_status` is live and `unplaced_fields` is empty for each.
409
-
410
- ```json
411
- {"tool_name": "app_publish_verify", "arguments": {"profile": "default", "app_keys": ["APP_KEY_1", "APP_KEY_2"]}}
229
+ ```text
230
+ 已完成:...
231
+ 未完成/未验证:...
232
+ 前端可见:是/否/未确认
233
+ 需要继续修复:是/否;原因...
412
234
  ```
413
-
414
- ---
415
-
416
- ## Common failures
417
-
418
- | Error | Phase | Fix |
419
- |-------|-------|-----|
420
- | `VALIDATION_ERROR` on relation field | 1 | Read `message` verbatim first. Add `display_field` + `visible_fields` to the failing relation field. |
421
- | Partial app batch failure | 1 | Only resubmit failed apps by `row_number`. Do not resubmit the entire batch. |
422
- | `UNKNOWN_LAYOUT_FIELD` | 2 | Re-read fields with `app_get_fields`. Field name in `rows` must match exactly. |
423
- | `FLOW_ASSIGNEE_REQUIRED` | 3 | Run `role_search` first. Assign at least one role to every approve/fill node. |
424
- | `FLOW_DEPENDENCY_MISSING` | 3 | Fix schema first, then retry flow. |
425
- | View `partial_success` | 4 | Check `verification.view_query_conditions_verified`. Read `views_diff.failed`. |
426
- | Portal height mismatch or blank space | 5 | All components at the same `y` must have identical `rows` and `cols` summing to 24. |
427
- | `PORTAL_CHART_CARD_TOO_SMALL` | 5 | Indicator cards: `rows ≥ 3`. Visual charts: `rows ≥ 6`. |
428
- | Relation field has no candidates on insert | 6 | The referenced app has no records yet. Insert that app's records first, then retry. |