@josephyan/qingflow-app-builder-mcp 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +6 -5
  2. package/docs/local-agent-install.md +57 -6
  3. package/entry_point.py +1 -1
  4. package/npm/bin/qingflow-app-builder-mcp.mjs +2 -33
  5. package/npm/bin/qingflow-skills.mjs +5 -0
  6. package/npm/lib/runtime.mjs +21 -101
  7. package/npm/scripts/postinstall.mjs +1 -10
  8. package/package.json +3 -2
  9. package/pyproject.toml +1 -1
  10. package/skills/qingflow-app-builder/SKILL.md +51 -34
  11. package/skills/qingflow-app-builder/references/complete-system-development-guide.md +123 -0
  12. package/skills/qingflow-app-builder/references/create-app.md +19 -6
  13. package/skills/qingflow-app-builder/references/environments.md +1 -1
  14. package/skills/qingflow-app-builder/references/gotchas.md +14 -6
  15. package/skills/qingflow-app-builder/references/match-rules.md +15 -0
  16. package/skills/qingflow-app-builder/references/single-app-development-guide.md +58 -0
  17. package/skills/qingflow-app-builder/references/solution-playbooks.md +10 -0
  18. package/skills/qingflow-app-builder/references/tool-selection.md +21 -22
  19. package/skills/qingflow-app-builder/references/update-flow.md +22 -38
  20. package/skills/qingflow-app-builder/references/update-schema.md +3 -0
  21. package/skills/qingflow-app-builder/references/update-views.md +34 -14
  22. package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +124 -0
  23. package/skills/qingflow-app-builder-code-integrations/SKILL.md +5 -3
  24. package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
  25. package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
  26. package/src/qingflow_mcp/__init__.py +1 -1
  27. package/src/qingflow_mcp/__main__.py +6 -2
  28. package/src/qingflow_mcp/builder_facade/models.py +282 -102
  29. package/src/qingflow_mcp/builder_facade/service.py +4166 -929
  30. package/src/qingflow_mcp/cli/commands/builder.py +316 -298
  31. package/src/qingflow_mcp/cli/commands/chart.py +1 -1
  32. package/src/qingflow_mcp/cli/commands/common.py +12 -3
  33. package/src/qingflow_mcp/cli/commands/exports.py +2 -2
  34. package/src/qingflow_mcp/cli/commands/imports.py +3 -3
  35. package/src/qingflow_mcp/cli/commands/portal.py +2 -2
  36. package/src/qingflow_mcp/cli/commands/record.py +101 -27
  37. package/src/qingflow_mcp/cli/commands/task.py +28 -47
  38. package/src/qingflow_mcp/cli/commands/view.py +1 -1
  39. package/src/qingflow_mcp/cli/context.py +0 -3
  40. package/src/qingflow_mcp/cli/formatters.py +784 -16
  41. package/src/qingflow_mcp/cli/main.py +117 -33
  42. package/src/qingflow_mcp/errors.py +43 -2
  43. package/src/qingflow_mcp/public_surface.py +26 -17
  44. package/src/qingflow_mcp/response_trim.py +81 -17
  45. package/src/qingflow_mcp/server.py +14 -12
  46. package/src/qingflow_mcp/server_app_builder.py +65 -21
  47. package/src/qingflow_mcp/server_app_user.py +22 -16
  48. package/src/qingflow_mcp/session_store.py +11 -7
  49. package/src/qingflow_mcp/solution/compiler/__init__.py +3 -1
  50. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
  51. package/src/qingflow_mcp/solution/executor.py +245 -18
  52. package/src/qingflow_mcp/tools/ai_builder_tools.py +1780 -406
  53. package/src/qingflow_mcp/tools/app_tools.py +184 -43
  54. package/src/qingflow_mcp/tools/approval_tools.py +197 -35
  55. package/src/qingflow_mcp/tools/auth_tools.py +92 -16
  56. package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
  57. package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
  58. package/src/qingflow_mcp/tools/directory_tools.py +236 -72
  59. package/src/qingflow_mcp/tools/export_tools.py +244 -34
  60. package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
  61. package/src/qingflow_mcp/tools/file_tools.py +9 -3
  62. package/src/qingflow_mcp/tools/import_tools.py +336 -49
  63. package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
  64. package/src/qingflow_mcp/tools/package_tools.py +118 -6
  65. package/src/qingflow_mcp/tools/portal_tools.py +39 -3
  66. package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
  67. package/src/qingflow_mcp/tools/record_tools.py +1141 -356
  68. package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
  69. package/src/qingflow_mcp/tools/role_tools.py +80 -9
  70. package/src/qingflow_mcp/tools/solution_tools.py +59 -45
  71. package/src/qingflow_mcp/tools/task_context_tools.py +662 -158
  72. package/src/qingflow_mcp/tools/task_tools.py +113 -29
  73. package/src/qingflow_mcp/tools/view_tools.py +106 -3
  74. package/src/qingflow_mcp/tools/workflow_tools.py +48 -4
  75. package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
  76. package/skills/qingflow-app-builder/references/build-complete-system.md +0 -428
  77. package/skills/qingflow-app-builder/references/build-single-app.md +0 -530
  78. package/skills/qingflow-mcp-setup/SKILL.md +0 -111
  79. package/skills/qingflow-mcp-setup/agents/openai.yaml +0 -4
  80. package/skills/qingflow-mcp-setup/references/claude-desktop.md +0 -34
  81. package/skills/qingflow-mcp-setup/references/environments.md +0 -61
  82. package/skills/qingflow-mcp-setup/references/generic-stdio.md +0 -31
  83. package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +0 -38
  84. package/skills/qingflow-workflow-builder/SKILL.md +0 -96
  85. package/skills/qingflow-workflow-builder/manifest.yaml +0 -8
  86. package/skills/qingflow-workflow-builder/references/01-overview.md +0 -45
  87. package/skills/qingflow-workflow-builder/references/02-update-mode.md +0 -53
  88. package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +0 -57
  89. package/skills/qingflow-workflow-builder/references/04-stage1-business-modeling.md +0 -131
  90. package/skills/qingflow-workflow-builder/references/05-stage2-members-roles.md +0 -29
  91. package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +0 -165
  92. package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +0 -33
  93. package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +0 -51
  94. package/skills/qingflow-workflow-builder/references/09-stage6-summary.md +0 -88
  95. package/skills/qingflow-workflow-builder/references/10-node-config-reference.md +0 -93
  96. package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +0 -15
  97. package/skills/qingflow-workflow-builder/scripts/diff_flow_spec.py +0 -275
  98. package/skills/qingflow-workflow-builder/scripts/validate_flow_spec.py +0 -605
@@ -1,428 +0,0 @@
1
- # Build Complete System(完整系统搭建)
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.
4
-
5
- **Signal phrases**: "建一套系统"、"包含 X 个模块"、"这几个表单之间建立关联"、"完整的业务系统"
6
-
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
- }
41
- ```
42
-
43
- Record the returned `package_id`. All subsequent phases use it.
44
-
45
- ---
46
-
47
- ## Phase 1 — Create all apps and fields in one call
48
-
49
- > **Read first**: [update-schema.md](./update-schema.md)
50
-
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)
73
-
74
- ```json
75
- {
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"}
119
- ]
120
- }
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
- ["客户状态", "负责人"]
151
- ]
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
- }
200
- ]
201
- }
202
- }
203
- ```
204
-
205
- ---
206
-
207
- ## Phase 4 — Per-app: Views (multiple types)
208
-
209
- > **Read first**: [update-views.md](./update-views.md)
210
-
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` |
219
-
220
- ```json
221
- {
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
- }
250
- },
251
- {
252
- "name": "客户卡片",
253
- "type": "card",
254
- "columns": ["客户名称", "客户类型", "客户状态", "负责人"],
255
- "query_conditions": {
256
- "enabled": true,
257
- "exact": false,
258
- "hide_before_query": false,
259
- "rows": [["客户名称", "客户状态"]]
260
- }
261
- }
262
- ]
263
- }
264
- }
265
- ```
266
-
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)
274
-
275
- ### 5.1 Build charts — 8 total
276
-
277
- **4 indicator cards + 4 visual charts.** Build via `app_charts_apply` per app and record all `chart_id` values before calling `portal_apply`.
278
-
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.
296
-
297
- ```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
- ]
367
- }
368
- }
369
- ```
370
-
371
- ---
372
-
373
- ## Phase 6 — Sample data
374
-
375
- > **Hand off to `qingflow-record-insert` skill**. Read the record-insert skill docs before inserting.
376
-
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.
378
-
379
- Per app: insert **3–5 records** covering different status values and realistic business data.
380
-
381
- ```json
382
- {"tool_name": "record_insert_schema_get", "arguments": {"profile": "default", "app_key": "APP_KEY"}}
383
- ```
384
-
385
- ```json
386
- {
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
- }
399
- }
400
- ```
401
-
402
- Member, department, and relation fields accept natural language values — do not look up IDs manually.
403
-
404
- ---
405
-
406
- ## Phase 7 — Publish verify
407
-
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"]}}
412
- ```
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. |