@dazitech/cli 3.0.0

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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +104 -0
  3. package/dist/bin/dazi-app.cjs +4 -0
  4. package/dist/bin/dazi-flow.cjs +4 -0
  5. package/dist/bin/dazi-onto.cjs +4 -0
  6. package/dist/bin/dazi.cjs +4 -0
  7. package/dist/bin/run-cli-bin.cjs +62 -0
  8. package/dist/clis/dazi-app.js +16697 -0
  9. package/dist/clis/dazi-flow.js +6093 -0
  10. package/dist/clis/dazi-onto.js +3948 -0
  11. package/dist/clis/dazi.js +5677 -0
  12. package/dist/docs/app/app-init.md +69 -0
  13. package/dist/docs/app/build-upload.md +77 -0
  14. package/dist/docs/app/release-guide.md +51 -0
  15. package/dist/docs/app//344/270/273/350/246/201/350/264/242/345/212/241/346/214/207/346/240/207/345/244/215/346/235/202/346/212/245/350/241/250/345/274/200/345/217/221/345/256/236/350/267/265.md +261 -0
  16. package/dist/docs/auth/auth-login.md +41 -0
  17. package/dist/docs/auth/token-management.md +42 -0
  18. package/dist/docs/data/cube-guide.md +23 -0
  19. package/dist/docs/data/data-spaces.md +30 -0
  20. package/dist/docs/data/table-preview.md +41 -0
  21. package/dist/docs/flow/flow-project-guide.md +505 -0
  22. package/dist/docs/flow/flows-guide.md +302 -0
  23. package/dist/docs/flow/node-code-guide.md +399 -0
  24. package/dist/docs/flow/plan-guide.md +59 -0
  25. package/dist/docs/flow/run-guide.md +98 -0
  26. package/dist/docs/flow/source-guide.md +44 -0
  27. package/dist/docs/flow/variables-guide.md +406 -0
  28. package/dist/docs/flow//346/265/201/347/250/213/345/274/200/345/217/221/346/234/200/344/275/263/345/256/236/350/267/265-VS-flow0/346/241/210/344/276/213.md +344 -0
  29. package/dist/docs/guides/cli-invocation.md +93 -0
  30. package/dist/docs/guides/cli-reference.md +98 -0
  31. package/dist/docs/guides/mcp-setup.md +89 -0
  32. package/dist/docs/guides/migrate-v2-v3.md +54 -0
  33. package/dist/docs/guides/quickstart.md +77 -0
  34. package/dist/docs/guides/troubleshooting.md +82 -0
  35. package/dist/docs/guides/workspace-v3.md +53 -0
  36. package/dist/docs/index.json +204 -0
  37. package/dist/docs/onto/action-guide.md +48 -0
  38. package/dist/docs/onto/dazi_script_sdk_reference.md +168 -0
  39. package/dist/docs/onto/dazi_script_seed_data_guide.md +155 -0
  40. package/dist/docs/onto/function-guide.md +68 -0
  41. package/dist/docs/onto/rule-guide.md +52 -0
  42. package/dist/docs/onto/space-management.md +46 -0
  43. package/dist/docs/onto//346/234/254/344/275/223/350/204/232/346/234/254/347/274/226/345/206/231/346/214/207/345/215/227.md +145 -0
  44. package/dist/docs/onto//346/234/254/344/275/223/350/247/204/345/210/222/346/214/207/345/215/227.md +131 -0
  45. package/dist/docs/onto//350/247/204/345/210/222/347/244/272/344/276/213_/345/210/251/346/266/246/345/210/206/346/236/220/346/234/254/344/275/223/346/226/271/346/241/210.md +541 -0
  46. package/dist/examples/index.json +36 -0
  47. package/dist/examples/onto/function/profit_fn_customer_segmentation.py +117 -0
  48. package/dist/examples/onto/function/profit_fn_mom_analysis.py +89 -0
  49. package/dist/examples/onto/function/profit_fn_top_products.py +89 -0
  50. package/dist/examples/onto/function/profit_fn_yoy_analysis.py +89 -0
  51. package/dist/examples/onto/setup/profit_ontology_init.py +388 -0
  52. package/dist/prompts/app/ui-design.md +48 -0
  53. package/dist/prompts/data/data-analysis.md +42 -0
  54. package/dist/prompts/data/sql-query.md +36 -0
  55. package/dist/prompts/flow/flow-design.md +77 -0
  56. package/dist/prompts/flow/plan-generate.md +61 -0
  57. package/dist/prompts/flow/run-debug.md +66 -0
  58. package/dist/prompts/flow/run-fix-loop.md +77 -0
  59. package/dist/prompts/general/ask-dazi.md +30 -0
  60. package/dist/prompts/general/code-review.md +31 -0
  61. package/dist/prompts/general/troubleshoot.md +41 -0
  62. package/dist/prompts/index.json +20 -0
  63. package/dist/prompts/onto/action-design.md +47 -0
  64. package/dist/prompts/onto/function-design.md +44 -0
  65. package/dist/prompts/onto/rule-seed.md +41 -0
  66. package/dist/prompts/onto/script-publish-run.md +146 -0
  67. package/package.json +27 -0
@@ -0,0 +1,505 @@
1
+ # 数据流程项目开发指南
2
+
3
+ **文档 ID**: `flow/flow-project-guide`
4
+ **适用**: `dazi-vscode` v3.1+、`dazi-work` 工作区、`项目/flow_*` 流程项目
5
+
6
+ ---
7
+
8
+ ## 1. 定位与核心约定
9
+
10
+ | 维度 | 说明 |
11
+ |------|------|
12
+ | CLI 入口 | `.\scripts\dazi.ps1 flow …` → `dazi-flow`(Trae / VS Code / Cursor 交付环境) |
13
+ | 工作区 | `dazi-work` + `项目/flow_<名>/` |
14
+ | 本地流程树 | `流程/<名>/flow.json` + `节点/<名>/code.*` |
15
+ | 画布真理源 | **`flow.json`**(= 平台 `config_json` 镜像,代码已剥离) |
16
+ | 代码真理源 | **`节点/<名>/code.sql|py`** + `node push` |
17
+ | 主交互 | **资源管理器右键** + MVP 流程设计器 |
18
+ | AI | **Cursor 侧读文件** + `dazi-flow mcp` |
19
+
20
+ API 根路径:**`{serverUrl}/api/data-pipelines/v1`**(搭子数据流程引擎)。
21
+
22
+ ---
23
+
24
+ ## 2. 工作区目录
25
+
26
+ ```text
27
+ dazi-work/
28
+ ├── scripts/
29
+ │ └── dazi.ps1 ← 终端/Trae 中运行搭子 CLI 的入口
30
+ └── 项目/
31
+ └── flow_数据集成01/
32
+ ├── README.md 项目元信息
33
+ ├── 快速启动.md 项目级入门
34
+ ├── 规划/
35
+ └── 流程/
36
+ └── 客户数据清洗/ ← 一个流程 = 一个目录
37
+ ├── 快速启动_<流程名>.md pull 后生成(flowId、常用命令、AI 单文件入口)
38
+ ├── flow.json ★ 画布(节点配置 + 边,不含代码正文)
39
+ ├── flow.meta.json flowId、uuid 映射、代码指纹
40
+ ├── 节点/
41
+ │ └── SQL查询/
42
+ │ ├── code.sql ★ 代码唯一真理源
43
+ │ └── node.info.json
44
+ ├── 变量/ 调试 Run 变量只读派生(schema + 预览)
45
+ │ └── sales_df.json
46
+ └── _run/ 测试/运行产物(*.last-error.md 等)
47
+ ```
48
+
49
+ **关键约定**
50
+
51
+ - 节点 `type` 在画布上恒为 `"custom"`,**业务类型在 `data.type`**(如 `sql-query`、`python-script`)。
52
+ - 流程项目**不绑定**数据空间;`connectionId` 只是节点配置字段。
53
+ - `flow.json` 由设计器/CLI 管理;AI 若手改拓扑,**必须**遵守 [§6.2 画布节点与连线规范](#62-画布节点与连线规范ai-创建--编辑-flowjson-必读)(节点 200px、锚点 `l/t/r/b/true/false`、条件分支)。
54
+ - 改代码请编辑 `code.*`,不要把代码正文写回 `flow.json`。
55
+
56
+ ---
57
+
58
+ ## 3. CLI 怎么跑:`dazi.ps1` 与 `dazi-flow`
59
+
60
+ ### 3.1 调用链(Trae / VS Code / Cursor 交付环境)
61
+
62
+ ```text
63
+ .\scripts\dazi.ps1 flow <子命令...>
64
+
65
+ ▼ node bundled/clis/dazi.js
66
+ │ (设置 DAZI_BUNDLED_DIR,cwd = dazi-work 根)
67
+
68
+ forward → node bundled/clis/dazi-flow.js <子命令...>
69
+ ```
70
+
71
+ - **没有**全局 `dazi-flow` 命令;与本体一致,统一走 **`.\scripts\dazi.ps1`**。
72
+ - 扩展侧栏/右键菜单与上述 CLI **同源**(同一套 bundled `dazi-flow.js`)。
73
+ - 首次使用:在 **`dazi-work` 根**执行 `.\scripts\doctor-cli.ps1` → `.\scripts\dazi.ps1 auth login`。
74
+
75
+ ### 3.2 命令写法对照
76
+
77
+ | 文档/扩展内部 | 在 `dazi-work` 根目录终端 |
78
+ |---------------|---------------------------|
79
+ | `dazi-flow project pull …` | `.\scripts\dazi.ps1 flow project pull …` |
80
+ | `dazi-flow node push …` | `.\scripts\dazi.ps1 flow node push …` |
81
+ | `dazi-flow run node-exec …` | `.\scripts\dazi.ps1 flow run node-exec …` |
82
+ | `dazi-flow variable pull …` | `.\scripts\dazi.ps1 flow variable pull …` |
83
+
84
+ **工作目录技巧**:多数命令支持 `--dir <流程目录>`。也可 **`cd` 到流程目录**后省略 `--dir`(cwd 即 `流程/<名>/`)。
85
+
86
+ ```powershell
87
+ # 在 dazi-work 根
88
+ cd D:\path\to\dazi-work
89
+ .\scripts\dazi.ps1 auth whoami
90
+
91
+ # 拉取平台流程到本地(首次)
92
+ .\scripts\dazi.ps1 flow project pull --flow 98 --dir "项目\flow_流程项目01\流程\MyFlow0529"
93
+
94
+ # 进入流程目录后,后续命令可省略 --dir
95
+ cd "项目\flow_流程项目01\流程\MyFlow0529"
96
+ .\scripts\dazi.ps1 flow project status
97
+ .\scripts\dazi.ps1 flow node push --node <node_uuid>
98
+ ```
99
+
100
+ **常用子命令速查**(拉取 / 提交 / 测试 / 变量等)见 [Flow 文档索引 · 流程项目常用命令](./flows-guide.md#流程项目flow_-常用命令)。Plan、数据源等专题见 [执行计划](./plan-guide.md)、[数据源管理](./source-guide.md)。
101
+
102
+ ---
103
+
104
+ ## 4. 推荐开发循环
105
+
106
+ ```text
107
+ 1. 新建或拉取
108
+ 扩展:项目/flow_* → 新建流程 / 拉取平台流程
109
+ CLI: flow project pull --flow <id> --dir <流程目录>
110
+
111
+ 2. 改代码
112
+ 打开 节点/<名>/code.sql 或 code.py
113
+ (详见 [节点代码编写指南](./node-code-guide.md))
114
+
115
+ 3. 改画布配置(连线、connectionId、output_variable_name…)
116
+ 右键 flow.json → 打开流程设计器 → 保存 flow.json
117
+ (AI 手改拓扑须遵守 [§6.2 画布节点与连线规范](#62-画布节点与连线规范ai-创建--编辑-flowjson-必读))
118
+
119
+ 4. 单节点测试
120
+ 右键 节点/ 或 code.* → 测试运行节点
121
+ CLI: flow run node-exec --node <uuid> --dir .
122
+
123
+ 5. 查看变量(表变量 schema + 前 10 行)
124
+ 设计器属性面板 output_variable_name 旁 📊
125
+ 或: flow variable pull --name <变量名> --dir .
126
+
127
+ 6. 提交到平台
128
+ 右键 → 提交流程(智能:代码脏节点 + 画布变更)
129
+ CLI: flow project push --dir . --canvas
130
+
131
+ 7. 失败时
132
+ 阅读 _run/*.last-error.md(整流程另见 flow.last-run.md)
133
+ - **对话模式**:用户确认后再交 AI 修复(扩展不自动改库)
134
+ - **Agent 模式**:AI 自行改错循环,见 `快速启动_<流程名>.md` §AI 自主运行与改错闭环 或提示词 `flow/run-fix-loop`
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 5. 同步策略(pull / push)
140
+
141
+ | 操作 | API / 行为 |
142
+ |------|------------|
143
+ | **pull** | `GET /flows/{id}/snapshot` 一次拿全 → 拆成 `flow.json` + `节点/*/code.*` + `flow.meta.json` |
144
+ | **push 代码** | 仅脏节点:`PATCH /flows/{id}/flow-nodes/{uuid}`(乐观锁 `expected_version`) |
145
+ | **push 画布** | `PUT /flows/{id}` body `{ data: 完整 document }`(`--canvas`) |
146
+ | **status** | 本地 `code.*` 的 sha1 与 meta 中 `codeHash` 比对 |
147
+
148
+ 冲突时:先 **拉取** 或 **`node push --force`**(慎用覆盖)。
149
+
150
+ ---
151
+
152
+ ## 6. 资源管理器菜单(主交互)
153
+
154
+ | 右键对象 | 常用命令 |
155
+ |----------|----------|
156
+ | `flow.json` / 流程目录 | 打开设计器、拉取、**提交**、状态、运行整流程 |
157
+ | `节点/<名>/` | 打开代码、拉取/提交节点、**测试运行** |
158
+ | `节点/<名>/code.*` | 提交、测试、拉取 |
159
+ | `变量/` | 同步变量到本地 |
160
+ | `变量/<名>.json` | 刷新变量、查看变量信息 |
161
+ | `项目/flow_*` | 新建流程、拉取平台流程 |
162
+ | **数据资源 → 文件上传管理** | 浏览平台登记文件、**拉取到本地资源**、复制 AI 附加说明 |
163
+
164
+ 设计器工具栏:**保存 / 校验 / 运行 / 提交 / 拉取**。
165
+
166
+ ---
167
+
168
+ ## 6.1 文件上传管理(Excel 等流程数据源)
169
+
170
+ 侧栏 **数据资源 → 文件上传管理** 展示平台 `managed_files` 目录树(与 Web 端「文件上传管理」同源)。
171
+
172
+ **拉取到本地** 后写入工作区:
173
+
174
+ ```text
175
+ dazi-work/资源/files/<显示名>_<fileId前8位>/
176
+ ├── 文件信息.json 登记元数据 + managed_file_id
177
+ ├── 原文件.xlsx 二进制原文件
178
+ ├── 原生解析.md Excel 原生解析(无缓存时会触发 parse)
179
+ ├── 表结构.json AI 表结构(需平台已生成)
180
+ └── 报表布局.json 复杂报表 RLIR(需平台「报表布局」页签已生成)
181
+ ```
182
+
183
+ - **excel-python 节点**画布请使用 **`managed_file_id`**(即 `文件信息.json` 中的 `file_id`),**不是** data upload 的 `id`。
184
+ - **Excel 文件(`.xlsx`/`.xls`)优先 `excel-python`**,**不要用 `file-source`**(file-source 仅透传原始文件、不解析 Excel)。
185
+ - 拉取后可用 **「复制 AI 附加说明」** 或在 Cursor 聊天中 `@` 引用上述文件,辅助编写流程与解析逻辑。
186
+
187
+ CLI 等价命令:
188
+
189
+ ```powershell
190
+ .\scripts\dazi.ps1 flow managed-files list
191
+ .\scripts\dazi.ps1 flow managed-files dirs --path excel
192
+ .\scripts\dazi.ps1 flow managed-files pull --file-id <uuid> --relative-dir excel
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 6.2 画布节点与连线规范(AI 创建 / 编辑 flow.json 必读)
198
+
199
+ Web 端 `@xyflow/react` 与 VS Code MVP 设计器共用同一套 **`flow.json` 拓扑约定**。AI 新建或修改流程时,**必须**遵守本节,否则画布错位、连线无法渲染、条件分支执行错误。
200
+
201
+ > 代码正文写在 `节点/<名>/code.*`,**不要**塞进 `flow.json`;本节只规范 **节点位置、锚点、边**。
202
+
203
+ ### 6.2.1 节点尺寸与布局
204
+
205
+ | 项 | 规范值 | 说明 |
206
+ |----|--------|------|
207
+ | 最小宽度 | **200px** | 对齐 Web `CustomNode` 的 `min-w-[200px]` |
208
+ | 典型高度 | **约 88px** | header(约 36px)+ body(约 52px);内容多时会增高 |
209
+ | 边框 / 圆角 | 2px / 8px | 与系统设计器一致 |
210
+ | 锚点直径 | **12px** | 对应 Tailwind `w-3 h-3` |
211
+ | 横向间距 | **≥ 260px** | 相邻节点 `position.x` 差值,避免 200px 宽节点重叠 |
212
+ | 纵向间距 | **≥ 140px** | 相邻节点 `position.y` 差值 |
213
+ | 首节点参考坐标 | `x: 80, y: 80` | 从左上网格起点排布 |
214
+
215
+ **结构**:每个节点为 **header(标题)+ body(状态摘要)** 双层;`position` 为节点**左上角**在画布上的像素坐标。
216
+
217
+ **推荐排布**(AI 新建流程时):
218
+
219
+ ```text
220
+ [开始] --260px--> [SQL] --260px--> [条件] --260px--> [Python-True]
221
+ |
222
+ 140px ↓
223
+ [Python-False] --260px--> [结束]
224
+ ```
225
+
226
+ ### 6.2.2 锚点(连线端点)约定
227
+
228
+ 锚点 ID 写入边的 **`sourceHandle`**(输出端)与 **`targetHandle`**(输入端)。**必须显式填写**,不要省略后依赖推断。
229
+
230
+ | 锚点 ID | 节点上的位置 | 角色 | 用于 |
231
+ |---------|--------------|------|------|
232
+ | `l` | 左侧中点 | **输入**(target) | 常规入边(最常见) |
233
+ | `t` | 顶部中点 | **输入**(target) | 自下方节点连入 |
234
+ | `r` | 右侧中点 | **输出**(source) | 常规出边(最常见) |
235
+ | `b` | 底部中点 | **输出**(source) | 连到下方节点 |
236
+ | `true` | 右侧 **30%** 高度 | **输出**(source) | **仅** `condition` 节点 True 分支 |
237
+ | `false` | 右侧 **70%** 高度 | **输出**(source) | **仅** `condition` 节点 False 分支 |
238
+
239
+ **合法组合**
240
+
241
+ - `sourceHandle` 只能是:`r` | `b` | `true` | `false`
242
+ - `targetHandle` 只能是:`l` | `t`
243
+ - **禁止**把 `l`/`t` 写在 `sourceHandle`,或把 `r`/`b`/`true`/`false` 写在 `targetHandle`
244
+ - **禁止**自连接(`source === target`)
245
+ - 同一对 `(source, target, sourceHandle, targetHandle)` 只能有一条边
246
+
247
+ **常用拓扑与锚点配对**
248
+
249
+ | 场景 | sourceHandle | targetHandle |
250
+ |------|--------------|--------------|
251
+ | 左 → 右(主流水线) | `r` | `l` |
252
+ | 上 → 下 | `b` | `t` |
253
+ | 右 → 下 | `r` | `t` |
254
+ | 下 → 左 | `b` | `l` |
255
+ | 条件 True 分支 | `true` | `l` 或 `t` |
256
+ | 条件 False 分支 | `false` | `l` 或 `t` |
257
+
258
+ **边 `id` 命名**(与 React Flow 一致,便于 diff):
259
+
260
+ ```text
261
+ xy-edge__{source节点id}{sourceHandle}-{target节点id}{targetHandle}
262
+ ```
263
+
264
+ 示例:`xy-edge__start-noder-sql-1l`
265
+
266
+ ### 6.2.3 各类节点锚点一览
267
+
268
+ | `data.type` | 输入 `l`/`t` | 输出 `r`/`b` | 输出 `true`/`false` | 备注 |
269
+ |-------------|:------------:|:------------:|:-------------------:|------|
270
+ | `start` | — | `r`, `b` | — | 无入边;语义 id 常为 `start-node` |
271
+ | `end` | `l`, `t` | — | — | 无出边;语义 id 常为 `end-node` |
272
+ | `condition` | `l`, `t` | — | **`true`, `false`** | **不用** `r`/`b` |
273
+ | 其他业务节点 | `l`, `t` | `r`, `b` | — | 如 `sql-query`、`python-script` 等 |
274
+
275
+ 画布上节点 **`type` 恒为 `"custom"`**,业务类型在 **`data.type`**。
276
+
277
+ ### 6.2.4 条件节点(`condition`)
278
+
279
+ **画布**
280
+
281
+ - `data.type`: `"condition"`
282
+ - `data.label`: 显示名(如「金额判断」)
283
+ - 条件表达式写在 **`节点/<名>/code.py`**(平台键 `pythonCode`),**不要**写进 `flow.json`
284
+ - 必须有 **至少一条入边**(`targetHandle` 为 `l` 或 `t`)
285
+ - 两条出边应分别使用 **`sourceHandle: "true"`** 与 **`sourceHandle: "false"`**(各连不同下游)
286
+ - 可视化:True 分支 **绿色**、False 分支 **红色**(Web / VS Code 设计器均如此)
287
+
288
+ **运行**
289
+
290
+ - 对入边上游表注入 **`df`**(不注入 `get_variable`)
291
+ - `code.py` 为 Python 表达式,求值结果为布尔值,决定走 True 还是 False 边
292
+ - 单节点测试前须先运行入边上游;详见 [流程变量系统指南 §6.7](./variables-guide.md#67-condition条件分支)
293
+
294
+ **条件节点示例 `code.py`**
295
+
296
+ ```python
297
+ # 表达式或单行,eval 后决定分支
298
+ df.shape[0] > 0 and df["amount"].sum() > 10000
299
+ ```
300
+
301
+ **反例(AI 勿犯)**
302
+
303
+ - 从条件节点用 `sourceHandle: "r"` 连下游 → **错误**,应用 `true` 或 `false`
304
+ - 只连 True 不连 False → 允许保存,但 False 分支下游永远不会被调度
305
+ - 两条出边都用 `true` → **错误**,分支无法区分
306
+
307
+ ### 6.2.5 `flow.json` 边(edges)字段
308
+
309
+ 每条边 **最少** 包含:
310
+
311
+ ```json
312
+ {
313
+ "id": "xy-edge__start-noder-sql-1l",
314
+ "source": "start-node",
315
+ "target": "sql-1",
316
+ "sourceHandle": "r",
317
+ "targetHandle": "l"
318
+ }
319
+ ```
320
+
321
+ - **`source` / `target`**:节点的语义 **`id`** 字段(不是 `node_uuid`)
322
+ - **`sourceHandle` / `targetHandle`**:见 §6.2.2
323
+ - 条件分支边示例:
324
+
325
+ ```json
326
+ {
327
+ "id": "xy-edge__cond-1true-py-okl",
328
+ "source": "cond-1",
329
+ "target": "py-ok",
330
+ "sourceHandle": "true",
331
+ "targetHandle": "l"
332
+ }
333
+ ```
334
+
335
+ ### 6.2.6 完整拓扑示例(AI 参考)
336
+
337
+ ```json
338
+ {
339
+ "nodes": [
340
+ {
341
+ "id": "start-node",
342
+ "type": "custom",
343
+ "node_uuid": "00000000-0000-0000-0000-000000000001",
344
+ "position": { "x": 80, "y": 120 },
345
+ "data": { "type": "start", "label": "开始" }
346
+ },
347
+ {
348
+ "id": "sql-1",
349
+ "type": "custom",
350
+ "node_uuid": "00000000-0000-0000-0000-000000000002",
351
+ "position": { "x": 340, "y": 120 },
352
+ "data": {
353
+ "type": "sql-query",
354
+ "label": "汇总销售",
355
+ "output_variable_name": "sales_agg"
356
+ }
357
+ },
358
+ {
359
+ "id": "cond-1",
360
+ "type": "custom",
361
+ "node_uuid": "00000000-0000-0000-0000-000000000003",
362
+ "position": { "x": 600, "y": 120 },
363
+ "data": { "type": "condition", "label": "金额判断" }
364
+ },
365
+ {
366
+ "id": "py-ok",
367
+ "type": "custom",
368
+ "node_uuid": "00000000-0000-0000-0000-000000000004",
369
+ "position": { "x": 860, "y": 80 },
370
+ "data": {
371
+ "type": "python-script",
372
+ "label": "大额处理",
373
+ "output_variable_name": "big_deal"
374
+ }
375
+ },
376
+ {
377
+ "id": "py-skip",
378
+ "type": "custom",
379
+ "node_uuid": "00000000-0000-0000-0000-000000000005",
380
+ "position": { "x": 860, "y": 220 },
381
+ "data": {
382
+ "type": "python-script",
383
+ "label": "小额跳过",
384
+ "output_variable_name": "small_deal"
385
+ }
386
+ },
387
+ {
388
+ "id": "end-node",
389
+ "type": "custom",
390
+ "node_uuid": "00000000-0000-0000-0000-000000000006",
391
+ "position": { "x": 1120, "y": 120 },
392
+ "data": { "type": "end", "label": "结束" }
393
+ }
394
+ ],
395
+ "edges": [
396
+ {
397
+ "id": "xy-edge__start-noder-sql-1l",
398
+ "source": "start-node",
399
+ "target": "sql-1",
400
+ "sourceHandle": "r",
401
+ "targetHandle": "l"
402
+ },
403
+ {
404
+ "id": "xy-edge__sql-1r-cond-1l",
405
+ "source": "sql-1",
406
+ "target": "cond-1",
407
+ "sourceHandle": "r",
408
+ "targetHandle": "l"
409
+ },
410
+ {
411
+ "id": "xy-edge__cond-1true-py-okl",
412
+ "source": "cond-1",
413
+ "target": "py-ok",
414
+ "sourceHandle": "true",
415
+ "targetHandle": "l"
416
+ },
417
+ {
418
+ "id": "xy-edge__cond-1false-py-skipl",
419
+ "source": "cond-1",
420
+ "target": "py-skip",
421
+ "sourceHandle": "false",
422
+ "targetHandle": "l"
423
+ },
424
+ {
425
+ "id": "xy-edge__py-okr-end-nodel",
426
+ "source": "py-ok",
427
+ "target": "end-node",
428
+ "sourceHandle": "r",
429
+ "targetHandle": "l"
430
+ },
431
+ {
432
+ "id": "xy-edge__py-skipr-end-nodel",
433
+ "source": "py-skip",
434
+ "target": "end-node",
435
+ "sourceHandle": "r",
436
+ "targetHandle": "l"
437
+ }
438
+ ]
439
+ }
440
+ ```
441
+
442
+ > `node_uuid` 由平台分配;AI **新建节点**应走 `flow node new` 或设计器「组件」面板,**不要**伪造 uuid。仅调整连线/坐标时可只改 `edges` 与 `position`。
443
+
444
+ ### 6.2.7 AI 自检清单
445
+
446
+ 创建或修改 `flow.json` 后,逐项核对:
447
+
448
+ 1. 存在 **`start`** 与 **`end`** 节点,且可达(从 start 沿边能到 end)
449
+ 2. 每条边的 **`sourceHandle` / `targetHandle`** 已填写且组合合法(§6.2.2)
450
+ 3. **`condition`** 节点的出边仅使用 **`true` / `false`**,不用 `r` / `b`
451
+ 4. 相邻节点 **`position` 间距** ≥ 260(横)/ 140(纵)
452
+ 5. 节点 **`type`** 为 `"custom"`,业务类型在 **`data.type`**
453
+ 6. 代码类节点无内嵌 `pythonCode` / `sql`(应在 `节点/*/code.*`)
454
+ 7. 变量名在 `output_variable_name` 中**全局不重名**(见 [variables-guide](./variables-guide.md))
455
+ 8. 改动画布后执行 **`flow project push --dir . --canvas`**
456
+
457
+ ### 6.2.8 设计器交互(人工)
458
+
459
+ VS Code **打开流程设计器**(右键 `flow.json`)时:
460
+
461
+ - 从**输出**锚点拖到**输入**锚点:新建连线(自动写入 handle)
462
+ - **点击连线**选中;**Delete** 或中点 **×** 删除
463
+ - 条件分支显示 **绿色 True / 红色 False** 标签
464
+ - 开始 / 结束 / 条件节点左侧有色条;拖拽连线时有虚线预览
465
+
466
+ 保存或 **`project push --canvas`** 后,与 Web 设计器互通。
467
+
468
+ ---
469
+
470
+ ## 7. 变量从哪里来(debug_run_id)
471
+
472
+ 运行期变量不在 `flow.json` 里,而在 **`ads_flows.debug_run_id` → `flow_runs.id` → `flow_run_variables`**。
473
+
474
+ 1. 单节点测试或整流程运行前,服务端会 **`GET /flows/{id}/debug-run`**(无则创建并写回 `debug_run_id`)。
475
+ 2. 节点配置了 **`output_variable_name`** 且执行成功后,输出写入该调试 Run(表 → Parquet,标量 → 库字段)。
476
+ 3. 查看变量时 CLI 同样先确保 debug-run,再 `GET /flows/{id}/variables`,拉 schema + preview 到 **`变量/<name>.json`**。
477
+
478
+ **代码节点如何用变量**(`get_variable`、SQL 表名、`result_df` 等)见 **[流程变量系统指南](./variables-guide.md)**。
479
+
480
+ 变量尚未产出时,占位 JSON 会提示:**先运行产出该变量的上游节点**。
481
+
482
+ ---
483
+
484
+ ## 8. 相关文档
485
+
486
+ | 文档 | 内容 |
487
+ |------|------|
488
+ | [流程变量系统指南](./variables-guide.md) | 变量模型、`output_variable_name`、各节点读写变量与代码示例 |
489
+ | [节点代码编写指南](./node-code-guide.md) | `python-script`、`sql-query` 等单节点代码约定 |
490
+ | [Flow 运行与测试](./run-guide.md) | `node-exec`、`flow-exec`、变量命令 |
491
+ | [CLI 调用约定](../guides/cli-invocation.md) | `dazi.ps1`、Trae 扩展路径、doctor |
492
+ | [CLI 命令速查](../guides/cli-reference.md) | 完整命令表 |
493
+ | [Flow 管理入门](./flows-guide.md) | 文档索引、**AI 创建流程速查**、平台级 Flow 操作 |
494
+
495
+ ---
496
+
497
+ ## 9. 常见问题
498
+
499
+ | 现象 | 处理 |
500
+ |------|------|
501
+ | `dazi-flow` 找不到 | 使用 `.\scripts\dazi.ps1 flow …`,运行 `doctor-cli.ps1` |
502
+ | 提交 HTTP 405 | 画布提交须 `PUT /flows/{id}`,用 `project push --canvas`,勿对 `apply-patch` 发 PUT |
503
+ | 变量查看失败 | 先 **测试节点** 或 **运行流程**;确认 `flow.meta.json` 有 `flowId` |
504
+ | 节点测试报缺上游变量 | 先运行上游节点,或 **运行整流程(debug)** 再测当前节点 |
505
+ | 代码改了平台没更新 | `node push` 或 `project push`;看 `project status` 是否脏 |