@nocobase/plugin-workflow 2.1.0-alpha.2 → 2.1.0-alpha.20

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 (136) hide show
  1. package/LICENSE +201 -661
  2. package/README.md +79 -10
  3. package/dist/client/214.88c6cd534bd4fc1c.js +10 -0
  4. package/dist/client/261.404a35cf5ae2ceba.js +10 -0
  5. package/dist/client/67.f904ef4520868b8a.js +10 -0
  6. package/dist/client/964.6251d37b35710747.js +10 -0
  7. package/dist/client/hooks/{useWorkflowFilterActionProps.d.ts → useResourceFilterActionProps.d.ts} +1 -1
  8. package/dist/client/index.js +1 -1
  9. package/dist/client/nodes/create.d.ts +10 -0
  10. package/dist/client/nodes/destroy.d.ts +10 -0
  11. package/dist/client/nodes/index.d.ts +3 -0
  12. package/dist/client/nodes/query.d.ts +18 -2
  13. package/dist/client/nodes/update.d.ts +10 -0
  14. package/dist/client/schemas/collection.d.ts +8 -2
  15. package/dist/client/schemas/executions.d.ts +41 -22
  16. package/dist/client/triggers/collection.d.ts +14 -1
  17. package/dist/client/triggers/index.d.ts +4 -0
  18. package/dist/client/triggers/schedule/constants.d.ts +4 -0
  19. package/dist/client/triggers/schedule/index.d.ts +15 -0
  20. package/dist/common/collections/executions.d.ts +22 -22
  21. package/dist/common/collections/executions.js +12 -0
  22. package/dist/common/collections/jobs.js +7 -0
  23. package/dist/common/collections/workflows.d.ts +22 -9
  24. package/dist/common/collections/workflows.js +9 -1
  25. package/dist/externalVersion.js +15 -13
  26. package/dist/locale/zh-CN.json +4 -1
  27. package/dist/node_modules/cron-parser/package.json +1 -1
  28. package/dist/node_modules/joi/dist/joi-browser.min.js +1 -0
  29. package/dist/node_modules/joi/lib/annotate.js +175 -0
  30. package/dist/node_modules/joi/lib/base.js +1069 -0
  31. package/dist/node_modules/joi/lib/cache.js +143 -0
  32. package/dist/node_modules/joi/lib/common.js +216 -0
  33. package/dist/node_modules/joi/lib/compile.js +283 -0
  34. package/dist/node_modules/joi/lib/errors.js +271 -0
  35. package/dist/node_modules/joi/lib/extend.js +312 -0
  36. package/dist/node_modules/joi/lib/index.d.ts +2365 -0
  37. package/dist/node_modules/joi/lib/index.js +1 -0
  38. package/dist/node_modules/joi/lib/manifest.js +476 -0
  39. package/dist/node_modules/joi/lib/messages.js +178 -0
  40. package/dist/node_modules/joi/lib/modify.js +267 -0
  41. package/dist/node_modules/joi/lib/ref.js +414 -0
  42. package/dist/node_modules/joi/lib/schemas.js +302 -0
  43. package/dist/node_modules/joi/lib/state.js +166 -0
  44. package/dist/node_modules/joi/lib/template.js +463 -0
  45. package/dist/node_modules/joi/lib/trace.js +346 -0
  46. package/dist/node_modules/joi/lib/types/alternatives.js +364 -0
  47. package/dist/node_modules/joi/lib/types/any.js +174 -0
  48. package/dist/node_modules/joi/lib/types/array.js +809 -0
  49. package/dist/node_modules/joi/lib/types/binary.js +100 -0
  50. package/dist/node_modules/joi/lib/types/boolean.js +150 -0
  51. package/dist/node_modules/joi/lib/types/date.js +233 -0
  52. package/dist/node_modules/joi/lib/types/function.js +93 -0
  53. package/dist/node_modules/joi/lib/types/keys.js +1067 -0
  54. package/dist/node_modules/joi/lib/types/link.js +168 -0
  55. package/dist/node_modules/joi/lib/types/number.js +363 -0
  56. package/dist/node_modules/joi/lib/types/object.js +22 -0
  57. package/dist/node_modules/joi/lib/types/string.js +850 -0
  58. package/dist/node_modules/joi/lib/types/symbol.js +102 -0
  59. package/dist/node_modules/joi/lib/validator.js +750 -0
  60. package/dist/node_modules/joi/lib/values.js +263 -0
  61. package/dist/node_modules/joi/node_modules/@hapi/topo/lib/index.d.ts +60 -0
  62. package/dist/node_modules/joi/node_modules/@hapi/topo/lib/index.js +225 -0
  63. package/dist/node_modules/joi/node_modules/@hapi/topo/package.json +30 -0
  64. package/dist/node_modules/joi/package.json +1 -0
  65. package/dist/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
  66. package/dist/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +10 -0
  67. package/dist/node_modules/lru-cache/dist/commonjs/index.d.ts +1381 -0
  68. package/dist/node_modules/lru-cache/dist/commonjs/index.js +1692 -0
  69. package/dist/node_modules/lru-cache/dist/commonjs/index.min.js +1 -0
  70. package/dist/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
  71. package/dist/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
  72. package/dist/node_modules/lru-cache/dist/esm/browser/index.d.ts +1381 -0
  73. package/dist/node_modules/lru-cache/dist/{mjs → esm/browser}/index.js +537 -179
  74. package/dist/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
  75. package/dist/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
  76. package/dist/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
  77. package/dist/node_modules/lru-cache/dist/esm/index.d.ts +1381 -0
  78. package/dist/node_modules/lru-cache/dist/{cjs → esm}/index.js +538 -184
  79. package/dist/node_modules/lru-cache/dist/esm/index.min.js +2 -0
  80. package/dist/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
  81. package/dist/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +7 -0
  82. package/dist/node_modules/lru-cache/dist/esm/node/index.d.ts +1381 -0
  83. package/dist/node_modules/lru-cache/dist/esm/node/index.js +1688 -0
  84. package/dist/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
  85. package/dist/node_modules/lru-cache/package.json +1 -1
  86. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  87. package/dist/server/Dispatcher.d.ts +3 -2
  88. package/dist/server/Dispatcher.js +74 -61
  89. package/dist/server/Plugin.d.ts +1 -0
  90. package/dist/server/Plugin.js +28 -2
  91. package/dist/server/actions/nodes.d.ts +5 -0
  92. package/dist/server/actions/nodes.js +34 -2
  93. package/dist/server/actions/workflows.d.ts +6 -0
  94. package/dist/server/actions/workflows.js +38 -0
  95. package/dist/server/instructions/ConditionInstruction.d.ts +2 -0
  96. package/dist/server/instructions/ConditionInstruction.js +17 -0
  97. package/dist/server/instructions/CreateInstruction.d.ts +3 -0
  98. package/dist/server/instructions/CreateInstruction.js +25 -0
  99. package/dist/server/instructions/DestroyInstruction.d.ts +3 -0
  100. package/dist/server/instructions/DestroyInstruction.js +25 -0
  101. package/dist/server/instructions/EndInstruction.d.ts +2 -0
  102. package/dist/server/instructions/EndInstruction.js +4 -0
  103. package/dist/server/instructions/MultiConditionsInstruction.d.ts +2 -0
  104. package/dist/server/instructions/MultiConditionsInstruction.js +23 -0
  105. package/dist/server/instructions/OutputInstruction.d.ts +2 -0
  106. package/dist/server/instructions/OutputInstruction.js +14 -0
  107. package/dist/server/instructions/QueryInstruction.d.ts +3 -0
  108. package/dist/server/instructions/QueryInstruction.js +32 -7
  109. package/dist/server/instructions/UpdateInstruction.d.ts +3 -0
  110. package/dist/server/instructions/UpdateInstruction.js +27 -0
  111. package/dist/server/instructions/index.d.ts +4 -0
  112. package/dist/server/instructions/index.js +18 -0
  113. package/dist/server/triggers/CollectionTrigger.d.ts +3 -0
  114. package/dist/server/triggers/CollectionTrigger.js +28 -0
  115. package/dist/server/triggers/ScheduleTrigger/index.d.ts +3 -0
  116. package/dist/server/triggers/ScheduleTrigger/index.js +18 -3
  117. package/dist/server/triggers/index.d.ts +3 -0
  118. package/dist/server/triggers/index.js +18 -0
  119. package/dist/server/utils.d.ts +17 -0
  120. package/dist/server/utils.js +51 -2
  121. package/dist/swagger/index.d.ts +830 -109
  122. package/dist/swagger/index.js +947 -208
  123. package/package.json +6 -5
  124. package/dist/client/27bd65abee87cafa.js +0 -10
  125. package/dist/client/478692c1637f2742.js +0 -10
  126. package/dist/client/c1347b9d21f864d9.js +0 -10
  127. package/dist/client/f39e94207f92e352.js +0 -10
  128. package/dist/node_modules/lru-cache/LICENSE +0 -15
  129. package/dist/node_modules/lru-cache/dist/cjs/index-cjs.d.ts +0 -7
  130. package/dist/node_modules/lru-cache/dist/cjs/index-cjs.js +0 -1
  131. package/dist/node_modules/lru-cache/dist/cjs/index.d.ts +0 -807
  132. package/dist/node_modules/lru-cache/dist/cjs/index.min.js +0 -2
  133. package/dist/node_modules/lru-cache/dist/mjs/index.d.ts +0 -807
  134. package/dist/node_modules/lru-cache/dist/mjs/index.min.js +0 -2
  135. /package/dist/node_modules/lru-cache/dist/{cjs → commonjs}/package.json +0 -0
  136. /package/dist/node_modules/lru-cache/dist/{mjs → esm}/package.json +0 -0
@@ -34,15 +34,69 @@ var swagger_default = {
34
34
  info: {
35
35
  title: "NocoBase API - Workflow plugin"
36
36
  },
37
- tags: [],
37
+ tags: [
38
+ { name: "workflows", description: "Workflow management: CRUD, versioning, sync, manual execution" },
39
+ { name: "workflows.nodes", description: "Create nodes inside a workflow (association resource)" },
40
+ { name: "flow_nodes", description: "Flow node management: update, delete, move, duplicate, test" },
41
+ { name: "executions", description: "Execution record management: list, get, cancel, delete" },
42
+ { name: "jobs", description: "Node job management: list, get, resume" },
43
+ { name: "userWorkflowTasks", description: "Current-user workflow task queries" }
44
+ ],
38
45
  paths: {
46
+ // ─────────────────────────────────────────────────────────────────────────
47
+ // workflows
48
+ // ─────────────────────────────────────────────────────────────────────────
39
49
  "/workflows:list": {
40
50
  get: {
41
51
  tags: ["workflows"],
42
- description: "",
52
+ summary: "List workflows",
53
+ description: [
54
+ "Get paginated list of workflows.",
55
+ "",
56
+ "Tip: filter by `current: true` to retrieve only the active version of each workflow.",
57
+ "",
58
+ "Example:",
59
+ "```",
60
+ 'GET /api/workflows:list?filter={"current":true}&sort=-createdAt&except[]=config',
61
+ "```"
62
+ ].join("\n"),
43
63
  parameters: [
64
+ { $ref: "#/components/schemas/workflow/filter" },
44
65
  {
45
- $ref: "#/components/schemas/workflow/filter"
66
+ name: "sort",
67
+ in: "query",
68
+ description: "Sort fields. Prefix with `-` for descending. e.g. `-createdAt`",
69
+ schema: { type: "string" }
70
+ },
71
+ {
72
+ name: "fields",
73
+ in: "query",
74
+ description: "Return only specified fields",
75
+ schema: { type: "array", items: { type: "string" } }
76
+ },
77
+ {
78
+ name: "except",
79
+ in: "query",
80
+ description: "Exclude specified fields from response (e.g. `config` to reduce payload)",
81
+ schema: { type: "array", items: { type: "string" } }
82
+ },
83
+ {
84
+ name: "appends",
85
+ in: "query",
86
+ description: "Append association data (e.g. `stats`, `versionStats`)",
87
+ schema: { type: "array", items: { type: "string" } }
88
+ },
89
+ {
90
+ name: "page",
91
+ in: "query",
92
+ description: "Page number (1-based)",
93
+ schema: { type: "integer", default: 1 }
94
+ },
95
+ {
96
+ name: "pageSize",
97
+ in: "query",
98
+ description: "Number of items per page",
99
+ schema: { type: "integer", default: 20 }
46
100
  }
47
101
  ],
48
102
  responses: {
@@ -52,9 +106,7 @@ var swagger_default = {
52
106
  "application/json": {
53
107
  schema: {
54
108
  type: "array",
55
- items: {
56
- $ref: "#/components/schemas/workflow/model"
57
- }
109
+ items: { $ref: "#/components/schemas/workflow/model" }
58
110
  }
59
111
  }
60
112
  }
@@ -65,13 +117,29 @@ var swagger_default = {
65
117
  "/workflows:get": {
66
118
  get: {
67
119
  tags: ["workflows"],
68
- description: "Get single workflow",
120
+ summary: "Get single workflow",
121
+ description: [
122
+ "Get details of a single workflow. Use `appends` to include nodes and statistics.",
123
+ "",
124
+ "Example:",
125
+ "```",
126
+ "GET /api/workflows:get?filterByTk=1&appends[]=nodes&appends[]=versionStats",
127
+ "```"
128
+ ].join("\n"),
69
129
  parameters: [
130
+ { $ref: "#/components/schemas/workflow/filterByTk" },
131
+ { $ref: "#/components/schemas/workflow/filter" },
70
132
  {
71
- $ref: "#/components/schemas/workflow/filterByTk"
133
+ name: "appends",
134
+ in: "query",
135
+ description: "Append associations: `nodes`, `stats`, `versionStats`, `executions`",
136
+ schema: { type: "array", items: { type: "string" } }
72
137
  },
73
138
  {
74
- $ref: "#/components/schemas/workflow/filter"
139
+ name: "except",
140
+ in: "query",
141
+ description: "Exclude fields from response",
142
+ schema: { type: "array", items: { type: "string" } }
75
143
  }
76
144
  ],
77
145
  responses: {
@@ -81,17 +149,13 @@ var swagger_default = {
81
149
  "application/json": {
82
150
  schema: {
83
151
  allOf: [
84
- {
85
- $ref: "#/components/schemas/workflow/model"
86
- },
152
+ { $ref: "#/components/schemas/workflow/model" },
87
153
  {
88
154
  type: "object",
89
155
  properties: {
90
156
  nodes: {
91
157
  type: "array",
92
- items: {
93
- $ref: "#/components/schemas/node"
94
- }
158
+ items: { $ref: "#/components/schemas/node" }
95
159
  }
96
160
  }
97
161
  }
@@ -106,23 +170,29 @@ var swagger_default = {
106
170
  "/workflows:create": {
107
171
  post: {
108
172
  tags: ["workflows"],
109
- description: "Create new workflow",
173
+ summary: "Create new workflow",
174
+ description: [
175
+ "Create a new workflow. The `type` (trigger type) must be specified at creation time.",
176
+ "",
177
+ "Note: `sync` mode (synchronous/asynchronous execution) **cannot be changed after creation**."
178
+ ].join("\n"),
110
179
  parameters: [],
111
180
  requestBody: {
112
181
  content: {
113
182
  "application/json": {
114
183
  schema: {
115
184
  type: "object",
185
+ required: ["title", "type"],
116
186
  properties: {
117
- title: {
118
- $ref: "#/components/schemas/workflow/model/properties/title"
119
- },
120
- type: {
121
- $ref: "#/components/schemas/workflow/model/properties/type"
122
- },
123
- description: {
124
- $ref: "#/components/schemas/workflow/model/properties/description"
125
- }
187
+ title: { $ref: "#/components/schemas/workflow/model/properties/title" },
188
+ type: { $ref: "#/components/schemas/workflow/model/properties/type" },
189
+ description: { $ref: "#/components/schemas/workflow/model/properties/description" },
190
+ enabled: { $ref: "#/components/schemas/workflow/model/properties/enabled" },
191
+ sync: { $ref: "#/components/schemas/workflow/model/properties/sync" },
192
+ triggerTitle: { $ref: "#/components/schemas/workflow/model/properties/triggerTitle" },
193
+ config: { $ref: "#/components/schemas/workflow/model/properties/config" },
194
+ options: { $ref: "#/components/schemas/workflow/model/properties/options" },
195
+ categories: { $ref: "#/components/schemas/workflow/model/properties/categories" }
126
196
  }
127
197
  }
128
198
  }
@@ -133,13 +203,7 @@ var swagger_default = {
133
203
  description: "OK",
134
204
  content: {
135
205
  "application/json": {
136
- schema: {
137
- allOf: [
138
- {
139
- $ref: "#/components/schemas/workflow"
140
- }
141
- ]
142
- }
206
+ schema: { $ref: "#/components/schemas/workflow/model" }
143
207
  }
144
208
  }
145
209
  }
@@ -149,34 +213,38 @@ var swagger_default = {
149
213
  "/workflows:update": {
150
214
  post: {
151
215
  tags: ["workflows"],
152
- description: "Update a workflow",
153
- parameters: [],
216
+ summary: "Update a workflow",
217
+ description: [
218
+ "Update workflow properties.",
219
+ "",
220
+ "Allowed fields (server-side whitelist): `title`, `description`, `enabled`, `triggerTitle`, `config`, `options`, `categories`.",
221
+ "",
222
+ "**Constraint:** `config` (trigger configuration) cannot be updated if the workflow version",
223
+ "has already been executed (`versionStats.executed > 0`). Create a new revision instead."
224
+ ].join("\n"),
225
+ parameters: [{ $ref: "#/components/schemas/workflow/filterByTk" }],
154
226
  requestBody: {
155
227
  content: {
156
228
  "application/json": {
157
229
  schema: {
158
230
  type: "object",
159
231
  properties: {
160
- title: {
161
- $ref: "#/components/schemas/workflow/model/properties/title"
162
- },
163
- enabled: {
164
- $ref: "#/components/schemas/workflow/model/properties/enabled"
165
- },
166
- description: {
167
- $ref: "#/components/schemas/workflow/model/properties/description"
168
- },
169
- config: {
170
- $ref: "#/components/schemas/workflow/model/properties/config"
171
- }
232
+ title: { $ref: "#/components/schemas/workflow/model/properties/title" },
233
+ enabled: { $ref: "#/components/schemas/workflow/model/properties/enabled" },
234
+ description: { $ref: "#/components/schemas/workflow/model/properties/description" },
235
+ triggerTitle: { $ref: "#/components/schemas/workflow/model/properties/triggerTitle" },
236
+ config: { $ref: "#/components/schemas/workflow/model/properties/config" },
237
+ options: { $ref: "#/components/schemas/workflow/model/properties/options" },
238
+ categories: { $ref: "#/components/schemas/workflow/model/properties/categories" }
172
239
  }
173
240
  }
174
241
  }
175
242
  }
176
243
  },
177
244
  responses: {
178
- 200: {
179
- description: "OK"
245
+ 200: { description: "OK" },
246
+ 400: {
247
+ description: "Bad Request. `config` cannot be updated when the workflow version has already been executed."
180
248
  }
181
249
  }
182
250
  }
@@ -184,122 +252,248 @@ var swagger_default = {
184
252
  "/workflows:destroy": {
185
253
  post: {
186
254
  tags: ["workflows"],
187
- description: "Delete workflows. Also will delete all nodes and executions of the workflow.",
255
+ summary: "Delete workflows",
256
+ description: [
257
+ "Delete one or more workflows, along with all their nodes and execution records.",
258
+ "",
259
+ "- If `filterByTk` targets a **current** (latest) version, **all other revisions** sharing",
260
+ " the same `key` are also deleted automatically.",
261
+ "- If `filter.key` is provided, all versions sharing that key are deleted."
262
+ ].join("\n"),
188
263
  parameters: [
189
264
  {
190
265
  name: "filterByTk",
191
266
  in: "query",
192
- description: "Primary key of a record",
193
- schema: {
194
- type: "integer",
195
- description: "ID. The only workflow with ID will be deleted."
196
- }
267
+ description: "ID of the workflow to delete",
268
+ schema: { type: "integer" }
197
269
  },
198
270
  {
199
271
  name: "filter",
200
272
  in: "query",
201
- description: "Filter",
273
+ description: "Filter to select workflows for deletion",
202
274
  schema: {
203
275
  type: "object",
204
276
  properties: {
205
277
  key: {
206
278
  type: "string",
207
- description: "Key. If provided, all workflow with same key will be deleted."
279
+ description: "Workflow key. All versions sharing this key will be deleted."
208
280
  }
209
281
  }
210
282
  }
211
283
  }
212
284
  ],
213
285
  responses: {
214
- 200: {
215
- description: "OK"
216
- }
286
+ 200: { description: "OK" }
217
287
  }
218
288
  }
219
289
  },
220
290
  "/workflows:revision": {
221
291
  post: {
222
292
  tags: ["workflows"],
223
- description: "Duplicate a workflow to a new version or a new workflow. All nodes will be duplicated too.",
293
+ summary: "Duplicate a workflow (create a revision)",
294
+ description: [
295
+ "Duplicate an existing workflow. All nodes are duplicated too.",
296
+ "",
297
+ "- If `filter.key` is provided, creates a **new version** under the same key (version control).",
298
+ "- Otherwise, creates an independent copy as a **new workflow** with a new key.",
299
+ "",
300
+ "The new workflow/version is created with `enabled: false` and `current: false` by default",
301
+ "unless overridden via `values`."
302
+ ].join("\n"),
224
303
  parameters: [
225
304
  {
226
305
  name: "filterByTk",
227
306
  in: "query",
228
- description: "Primary key of a record",
229
- schema: {
230
- type: "integer",
231
- description: "ID. The workflow to duplicate."
232
- }
307
+ description: "ID of the workflow to duplicate",
308
+ schema: { type: "integer" }
233
309
  },
234
310
  {
235
311
  name: "filter",
236
312
  in: "query",
237
- description: "Filter",
313
+ description: "Filter options",
238
314
  schema: {
239
315
  type: "object",
240
316
  properties: {
241
317
  key: {
242
318
  type: "string",
243
- description: "Key. If provided, only duplicate to a new version. Or will be duplicated to a new workflow."
319
+ description: "If provided, creates a new version under the same key. Otherwise duplicates as a new workflow."
244
320
  }
245
321
  }
246
322
  }
247
323
  }
248
324
  ],
325
+ requestBody: {
326
+ content: {
327
+ "application/json": {
328
+ schema: {
329
+ type: "object",
330
+ description: "Override fields for the new workflow/version",
331
+ properties: {
332
+ title: { type: "string", description: "Override title" },
333
+ enabled: { type: "boolean", description: "Override enabled state" },
334
+ current: { type: "boolean", description: "Set as current version" }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ },
249
340
  responses: {
250
341
  200: {
251
- description: "OK"
342
+ description: "OK",
343
+ content: {
344
+ "application/json": {
345
+ schema: { $ref: "#/components/schemas/workflow/model" }
346
+ }
347
+ }
252
348
  }
253
349
  }
254
350
  }
255
351
  },
256
- "/workflows:trigger": {
352
+ "/workflows:sync": {
257
353
  post: {
258
354
  tags: ["workflows"],
259
- description: "",
355
+ summary: "Sync workflow trigger registration",
356
+ description: [
357
+ "Re-register one or more workflows in the trigger system.",
358
+ "",
359
+ "This is used to reload a workflow's trigger listener after its configuration has been",
360
+ "changed directly in the database or via external tooling, bypassing the normal update API.",
361
+ "",
362
+ "Returns HTTP 204 No Content on success."
363
+ ].join("\n"),
260
364
  parameters: [
261
365
  {
262
- name: "triggerWorkflows",
366
+ name: "filterByTk",
263
367
  in: "query",
264
- description: "A combined string to describe workflows to trigger and context data to use. e.g. `?triggerWorkflows=1,2!category`. Each comma separated part is a trigger pair, as `1` and `2!category`. The number part is the ID of workflow, exclamation means the path of association to use in form data. If ignored, will trigger with the full form data object.",
265
- schema: {
266
- type: "string"
267
- }
368
+ description: "ID of the workflow to sync",
369
+ schema: { type: "integer" }
370
+ },
371
+ {
372
+ name: "filter",
373
+ in: "query",
374
+ description: "Filter to select multiple workflows to sync",
375
+ schema: { type: "object" }
268
376
  }
269
377
  ],
270
378
  responses: {
271
- 202: {
272
- description: "Accepted"
379
+ 204: { description: "No Content. Sync successful." }
380
+ }
381
+ }
382
+ },
383
+ "/workflows:execute": {
384
+ post: {
385
+ tags: ["workflows"],
386
+ summary: "Manually execute a workflow",
387
+ description: [
388
+ "Manually trigger execution of a workflow by ID.",
389
+ "",
390
+ "**Requirements:**",
391
+ "- `filterByTk` (query param) is required.",
392
+ "- Request body is required \u2014 the **entire JSON body** is treated as trigger context/input.",
393
+ "",
394
+ "**autoRevision:** When set to `1`, if the workflow has never been executed",
395
+ "(`executed === 0`), a new revision is created automatically after execution.",
396
+ "",
397
+ "**Returns:** `{ execution: { id, status }, newVersionId? }`"
398
+ ].join("\n"),
399
+ parameters: [
400
+ {
401
+ name: "filterByTk",
402
+ in: "query",
403
+ required: true,
404
+ description: "ID of the workflow to execute",
405
+ schema: { type: "integer" }
273
406
  },
274
- 400: {
275
- description: "Bad Request"
407
+ {
408
+ name: "autoRevision",
409
+ in: "query",
410
+ description: "If `1`, automatically create a new revision after the first execution",
411
+ schema: { type: "integer", enum: [0, 1] }
412
+ }
413
+ ],
414
+ requestBody: {
415
+ required: true,
416
+ content: {
417
+ "application/json": {
418
+ schema: {
419
+ type: "object",
420
+ description: "Trigger context/input data. The body itself is mapped to `params.values` on the server. Structure depends on trigger type.",
421
+ additionalProperties: true
422
+ }
423
+ }
276
424
  }
425
+ },
426
+ responses: {
427
+ 200: {
428
+ description: "OK",
429
+ content: {
430
+ "application/json": {
431
+ schema: {
432
+ type: "object",
433
+ properties: {
434
+ execution: {
435
+ type: "object",
436
+ properties: {
437
+ id: { type: "integer", description: "Execution ID" },
438
+ status: { type: "integer", description: "Execution status code" }
439
+ }
440
+ },
441
+ newVersionId: {
442
+ type: "integer",
443
+ nullable: true,
444
+ description: "ID of the newly created revision, if autoRevision was triggered"
445
+ }
446
+ }
447
+ }
448
+ }
449
+ }
450
+ },
451
+ 400: {
452
+ description: "Bad Request. Request body or `filterByTk` is missing/invalid, or workflow not triggered."
453
+ },
454
+ 404: { description: "Not Found. Workflow does not exist." }
277
455
  }
278
456
  }
279
457
  },
458
+ // ─────────────────────────────────────────────────────────────────────────
459
+ // workflows.nodes (association: create node within a workflow)
460
+ // ─────────────────────────────────────────────────────────────────────────
280
461
  "/workflows/{workflowId}/nodes:create": {
281
462
  post: {
282
463
  tags: ["workflows.nodes"],
283
- description: "Create a new node in workflow",
284
- parameters: [],
464
+ summary: "Create a node in a workflow",
465
+ description: [
466
+ "Create a new node inside the specified workflow.",
467
+ "",
468
+ "**Insertion logic:**",
469
+ "- `upstreamId: null` \u2014 node becomes the new head; the previous head (if any) becomes its downstream.",
470
+ "- `branchIndex: null` \u2014 node is inserted in the main chain after `upstreamId`.",
471
+ "- `branchIndex: <n>` \u2014 node becomes the head of branch `n` from `upstreamId`.",
472
+ "",
473
+ "**Constraint:** Cannot create nodes in a workflow version that has already been executed.",
474
+ "An optional `WORKFLOW_NODES_LIMIT` env var caps the total number of nodes allowed per workflow."
475
+ ].join("\n"),
476
+ parameters: [
477
+ {
478
+ name: "workflowId",
479
+ in: "path",
480
+ required: true,
481
+ description: "Workflow ID",
482
+ schema: { type: "integer" }
483
+ }
484
+ ],
285
485
  requestBody: {
286
486
  content: {
287
487
  "application/json": {
288
488
  schema: {
289
489
  type: "object",
490
+ required: ["type"],
290
491
  properties: {
291
- title: {
292
- $ref: "#/components/schemas/node/properties/title"
293
- },
294
- type: {
295
- $ref: "#/components/schemas/node/properties/type"
296
- },
297
- upstreamId: {
298
- $ref: "#/components/schemas/node/properties/upstreamId"
299
- },
300
- branchIndex: {
301
- $ref: "#/components/schemas/node/properties/branchIndex"
302
- }
492
+ type: { $ref: "#/components/schemas/node/properties/type" },
493
+ title: { $ref: "#/components/schemas/node/properties/title" },
494
+ config: { $ref: "#/components/schemas/node/properties/config" },
495
+ upstreamId: { $ref: "#/components/schemas/node/properties/upstreamId" },
496
+ branchIndex: { $ref: "#/components/schemas/node/properties/branchIndex" }
303
497
  }
304
498
  }
305
499
  }
@@ -311,14 +505,48 @@ var swagger_default = {
311
505
  content: {
312
506
  "application/json": {
313
507
  schema: {
314
- allOf: [
315
- {
316
- $ref: "#/components/schemas/node"
317
- }
318
- ]
508
+ allOf: [{ $ref: "#/components/schemas/node" }]
319
509
  }
320
510
  }
321
511
  }
512
+ },
513
+ 400: {
514
+ description: "Bad Request. Cannot create node in an already-executed workflow version, or node limit exceeded."
515
+ }
516
+ }
517
+ }
518
+ },
519
+ // ─────────────────────────────────────────────────────────────────────────
520
+ // flow_nodes
521
+ // ─────────────────────────────────────────────────────────────────────────
522
+ "/flow_nodes:get": {
523
+ get: {
524
+ tags: ["flow_nodes"],
525
+ summary: "Get single node",
526
+ description: "Get details of a single flow node.",
527
+ parameters: [
528
+ {
529
+ name: "filterByTk",
530
+ in: "query",
531
+ required: true,
532
+ description: "Node ID",
533
+ schema: { type: "integer" }
534
+ },
535
+ {
536
+ name: "appends",
537
+ in: "query",
538
+ description: "Append associations (e.g. `upstream`, `downstream`)",
539
+ schema: { type: "array", items: { type: "string" } }
540
+ }
541
+ ],
542
+ responses: {
543
+ 200: {
544
+ description: "OK",
545
+ content: {
546
+ "application/json": {
547
+ schema: { $ref: "#/components/schemas/node" }
548
+ }
549
+ }
322
550
  }
323
551
  }
324
552
  }
@@ -326,16 +554,23 @@ var swagger_default = {
326
554
  "/flow_nodes:update": {
327
555
  post: {
328
556
  tags: ["flow_nodes"],
329
- description: "Update node properties.",
557
+ summary: "Update node properties",
558
+ description: [
559
+ "Update properties or configuration of a flow node.",
560
+ "",
561
+ "**Constraint:** Cannot update nodes in a workflow version that has already been executed",
562
+ "(`versionStats.executed > 0`).",
563
+ "",
564
+ "`updateAssociationValues` can be used to update linked nodes simultaneously,",
565
+ "e.g. when re-connecting upstream/downstream after inserting a new node."
566
+ ].join("\n"),
330
567
  parameters: [
331
568
  {
332
569
  name: "filterByTk",
333
570
  in: "query",
334
- description: "Primary key of a record",
335
- schema: {
336
- type: "integer",
337
- description: "ID"
338
- }
571
+ required: true,
572
+ description: "Node ID",
573
+ schema: { type: "integer" }
339
574
  }
340
575
  ],
341
576
  requestBody: {
@@ -344,11 +579,13 @@ var swagger_default = {
344
579
  schema: {
345
580
  type: "object",
346
581
  properties: {
347
- title: {
348
- $ref: "#/components/schemas/node/properties/title"
349
- },
350
- config: {
351
- $ref: "#/components/schemas/node/properties/config"
582
+ title: { $ref: "#/components/schemas/node/properties/title" },
583
+ config: { $ref: "#/components/schemas/node/properties/config" },
584
+ branchIndex: { $ref: "#/components/schemas/node/properties/branchIndex" },
585
+ updateAssociationValues: {
586
+ type: "array",
587
+ description: 'Association fields to update simultaneously (e.g. `["upstream"]` to reconnect upstream node)',
588
+ items: { type: "string" }
352
589
  }
353
590
  }
354
591
  }
@@ -356,11 +593,9 @@ var swagger_default = {
356
593
  }
357
594
  },
358
595
  responses: {
359
- 200: {
360
- description: "OK"
361
- },
596
+ 200: { description: "OK" },
362
597
  400: {
363
- description: "Bad Request. Node in exected workflow cannot be updated."
598
+ description: "Bad Request. Node in executed workflow cannot be updated."
364
599
  }
365
600
  }
366
601
  }
@@ -368,33 +603,287 @@ var swagger_default = {
368
603
  "/flow_nodes:destroy": {
369
604
  post: {
370
605
  tags: ["flow_nodes"],
371
- description: "Delete a node. All nodes in sub-branches will also be deleted.",
606
+ summary: "Delete a node",
607
+ description: [
608
+ "Delete a node from the workflow. All nodes in sub-branches are also deleted by default.",
609
+ "",
610
+ "**keepBranch:** Optionally preserve one branch by specifying its `branchIndex`.",
611
+ "The kept branch will be reconnected to the deleted node's upstream/downstream.",
612
+ "",
613
+ "**Constraint:** Cannot delete nodes in a workflow version that has already been executed."
614
+ ].join("\n"),
372
615
  parameters: [
373
616
  {
374
617
  name: "filterByTk",
375
618
  in: "query",
376
- description: "Primary key of a record",
377
- schema: {
378
- type: "integer",
379
- description: "ID"
619
+ required: true,
620
+ description: "Node ID",
621
+ schema: { type: "integer" }
622
+ },
623
+ {
624
+ name: "keepBranch",
625
+ in: "query",
626
+ description: "Branch index to preserve (all other branches will be deleted)",
627
+ schema: { type: "integer" }
628
+ }
629
+ ],
630
+ responses: {
631
+ 200: { description: "OK" },
632
+ 400: {
633
+ description: "Bad Request. Node in executed workflow cannot be deleted."
634
+ }
635
+ }
636
+ }
637
+ },
638
+ "/flow_nodes:destroyBranch": {
639
+ post: {
640
+ tags: ["flow_nodes"],
641
+ summary: "Delete a specific branch of a branching node",
642
+ description: [
643
+ "Delete all nodes under a specific branch of a branching node (e.g. a condition node).",
644
+ "",
645
+ "**shift:** If `1`, branches with a higher `branchIndex` are shifted down by 1",
646
+ "to keep indexes contiguous after deletion.",
647
+ "",
648
+ "**Constraint:** Cannot delete branches in a workflow version that has already been executed."
649
+ ].join("\n"),
650
+ parameters: [
651
+ {
652
+ name: "filterByTk",
653
+ in: "query",
654
+ required: true,
655
+ description: "ID of the parent branching node",
656
+ schema: { type: "integer" }
657
+ },
658
+ {
659
+ name: "branchIndex",
660
+ in: "query",
661
+ required: true,
662
+ description: "Index of the branch to delete",
663
+ schema: { type: "integer" }
664
+ },
665
+ {
666
+ name: "shift",
667
+ in: "query",
668
+ description: "If `1`, shift remaining branch indexes down after deletion",
669
+ schema: { type: "integer", enum: [0, 1] }
670
+ }
671
+ ],
672
+ responses: {
673
+ 200: { description: "OK" },
674
+ 400: {
675
+ description: "Bad Request. Branch in executed workflow cannot be deleted, or `branchIndex` is missing/invalid."
676
+ }
677
+ }
678
+ }
679
+ },
680
+ "/flow_nodes:duplicate": {
681
+ post: {
682
+ tags: ["flow_nodes"],
683
+ summary: "Duplicate a node",
684
+ description: [
685
+ "Duplicate an existing node to a new position in the same workflow.",
686
+ "The node's `type`, `title`, and `config` are copied. If the instruction defines a",
687
+ "`duplicateConfig` method, it is called to transform the config during duplication.",
688
+ "",
689
+ "**Constraint:** Cannot duplicate into a workflow version that has already been executed.",
690
+ "An optional `WORKFLOW_NODES_LIMIT` env var caps the total number of nodes allowed."
691
+ ].join("\n"),
692
+ parameters: [
693
+ {
694
+ name: "filterByTk",
695
+ in: "query",
696
+ required: true,
697
+ description: "ID of the source node to duplicate",
698
+ schema: { type: "integer" }
699
+ }
700
+ ],
701
+ requestBody: {
702
+ content: {
703
+ "application/json": {
704
+ schema: {
705
+ type: "object",
706
+ description: "Target position and optional config override for the new node",
707
+ properties: {
708
+ upstreamId: { $ref: "#/components/schemas/node/properties/upstreamId" },
709
+ branchIndex: { $ref: "#/components/schemas/node/properties/branchIndex" },
710
+ config: { $ref: "#/components/schemas/node/properties/config" }
711
+ }
712
+ }
713
+ }
714
+ }
715
+ },
716
+ responses: {
717
+ 200: {
718
+ description: "OK",
719
+ content: {
720
+ "application/json": {
721
+ schema: { $ref: "#/components/schemas/node" }
722
+ }
380
723
  }
724
+ },
725
+ 400: {
726
+ description: "Bad Request. Cannot duplicate node in executed workflow, or node limit exceeded."
727
+ },
728
+ 404: { description: "Not Found. Source node not found." }
729
+ }
730
+ }
731
+ },
732
+ "/flow_nodes:move": {
733
+ post: {
734
+ tags: ["flow_nodes"],
735
+ summary: "Move a node to a different position",
736
+ description: [
737
+ "Move a node to a new position in the workflow graph.",
738
+ "Upstream/downstream connections of both the old and new positions are automatically re-linked.",
739
+ "",
740
+ "**Target position (in `values`):**",
741
+ "- `upstreamId: null` \u2014 move node to the head of the workflow.",
742
+ "- `upstreamId: <id>` + `branchIndex: null` \u2014 insert into the main chain after that node.",
743
+ "- `upstreamId: <id>` + `branchIndex: <n>` \u2014 insert as head of branch `n` from that node.",
744
+ "",
745
+ "**Constraint:** Cannot move nodes in a workflow version that has already been executed."
746
+ ].join("\n"),
747
+ parameters: [
748
+ {
749
+ name: "filterByTk",
750
+ in: "query",
751
+ required: true,
752
+ description: "ID of the node to move",
753
+ schema: { type: "integer" }
381
754
  }
382
755
  ],
756
+ requestBody: {
757
+ content: {
758
+ "application/json": {
759
+ schema: {
760
+ type: "object",
761
+ description: "Target position descriptor",
762
+ properties: {
763
+ upstreamId: {
764
+ type: "integer",
765
+ nullable: true,
766
+ description: "Target upstream node ID. `null` = move to head position."
767
+ },
768
+ branchIndex: {
769
+ type: "integer",
770
+ nullable: true,
771
+ description: "Branch index at the target upstream. `null` = main chain."
772
+ }
773
+ }
774
+ }
775
+ }
776
+ }
777
+ },
383
778
  responses: {
384
779
  200: {
385
- description: "OK"
780
+ description: "OK",
781
+ content: {
782
+ "application/json": {
783
+ schema: { $ref: "#/components/schemas/node" }
784
+ }
785
+ }
386
786
  },
387
787
  400: {
388
- description: "Bad Request. Node in exected workflow cannot be deleted."
788
+ description: "Bad Request. Cannot move node in executed workflow, or target position is invalid."
789
+ },
790
+ 404: { description: "Not Found. Node or target upstream node not found." }
791
+ }
792
+ }
793
+ },
794
+ "/flow_nodes:test": {
795
+ post: {
796
+ tags: ["flow_nodes"],
797
+ summary: "Test a node configuration",
798
+ description: [
799
+ "Test a node's configuration without creating a real workflow execution.",
800
+ "Only applicable to node types whose instruction implements a `test` method.",
801
+ "",
802
+ "Returns the result produced by the instruction's `test(config)` method."
803
+ ].join("\n"),
804
+ parameters: [],
805
+ requestBody: {
806
+ required: true,
807
+ content: {
808
+ "application/json": {
809
+ schema: {
810
+ type: "object",
811
+ required: ["type", "config"],
812
+ properties: {
813
+ type: { $ref: "#/components/schemas/node/properties/type" },
814
+ config: { $ref: "#/components/schemas/node/properties/config" }
815
+ }
816
+ }
817
+ }
389
818
  }
819
+ },
820
+ responses: {
821
+ 200: {
822
+ description: "OK. Returns the test result from the instruction.",
823
+ content: {
824
+ "application/json": {
825
+ schema: { type: "object" }
826
+ }
827
+ }
828
+ },
829
+ 400: {
830
+ description: "Bad Request. Node type not registered or `test` method not implemented."
831
+ },
832
+ 500: { description: "Internal Server Error. Test execution threw an error." }
390
833
  }
391
834
  }
392
835
  },
836
+ // ─────────────────────────────────────────────────────────────────────────
837
+ // executions
838
+ // ─────────────────────────────────────────────────────────────────────────
393
839
  "/executions:list": {
394
840
  get: {
395
841
  tags: ["executions"],
396
- description: "Get list of executions",
397
- parameters: [],
842
+ summary: "List executions",
843
+ description: [
844
+ "Get paginated list of workflow execution records.",
845
+ "",
846
+ "Example:",
847
+ "```",
848
+ 'GET /api/executions:list?filter={"workflowId":1}&sort=-id&page=1&pageSize=20',
849
+ "```"
850
+ ].join("\n"),
851
+ parameters: [
852
+ {
853
+ name: "filter",
854
+ in: "query",
855
+ description: "Filter conditions (e.g. `{ workflowId: 1, status: 1 }`)",
856
+ schema: { type: "object" }
857
+ },
858
+ {
859
+ name: "appends",
860
+ in: "query",
861
+ description: "Append associations (e.g. `jobs`, `workflow`)",
862
+ schema: { type: "array", items: { type: "string" } }
863
+ },
864
+ {
865
+ name: "except",
866
+ in: "query",
867
+ description: "Exclude fields to reduce payload",
868
+ schema: { type: "array", items: { type: "string" } }
869
+ },
870
+ {
871
+ name: "sort",
872
+ in: "query",
873
+ description: "Sort fields. Prefix with `-` for descending. e.g. `-id`",
874
+ schema: { type: "string" }
875
+ },
876
+ {
877
+ name: "page",
878
+ in: "query",
879
+ schema: { type: "integer", default: 1 }
880
+ },
881
+ {
882
+ name: "pageSize",
883
+ in: "query",
884
+ schema: { type: "integer", default: 20 }
885
+ }
886
+ ],
398
887
  responses: {
399
888
  200: {
400
889
  description: "OK",
@@ -420,16 +909,34 @@ var swagger_default = {
420
909
  "/executions:get": {
421
910
  get: {
422
911
  tags: ["executions"],
423
- description: "Get single execution",
912
+ summary: "Get single execution",
913
+ description: [
914
+ "Get details of a single execution. Use `appends` to include jobs, workflow and node data.",
915
+ "",
916
+ "Example:",
917
+ "```",
918
+ "GET /api/executions:get?filterByTk=1&appends[]=jobs&appends[]=workflow&appends[]=workflow.nodes",
919
+ "```"
920
+ ].join("\n"),
424
921
  parameters: [
425
922
  {
426
923
  name: "filterByTk",
427
924
  in: "query",
428
- description: "Primary key of a record",
429
- schema: {
430
- type: "integer",
431
- description: "ID"
432
- }
925
+ required: true,
926
+ description: "Execution ID",
927
+ schema: { type: "integer" }
928
+ },
929
+ {
930
+ name: "appends",
931
+ in: "query",
932
+ description: "Append associations: `jobs`, `workflow`, `workflow.nodes`, `workflow.versionStats`, `workflow.stats`",
933
+ schema: { type: "array", items: { type: "string" } }
934
+ },
935
+ {
936
+ name: "except",
937
+ in: "query",
938
+ description: "Exclude fields to reduce payload (e.g. `jobs.result`, `workflow.options`)",
939
+ schema: { type: "array", items: { type: "string" } }
433
940
  }
434
941
  ],
435
942
  responses: {
@@ -437,20 +944,115 @@ var swagger_default = {
437
944
  description: "OK",
438
945
  content: {
439
946
  "application/json": {
440
- schema: {
441
- $ref: "#/components/schemas/execution"
442
- }
947
+ schema: { $ref: "#/components/schemas/execution" }
948
+ }
949
+ }
950
+ }
951
+ }
952
+ }
953
+ },
954
+ "/executions:cancel": {
955
+ post: {
956
+ tags: ["executions"],
957
+ summary: "Cancel a running execution",
958
+ description: [
959
+ "Abort a currently running execution.",
960
+ "Sets the execution status to `ABORTED` (-3) and all `PENDING` (0) jobs to `ABORTED` (-3).",
961
+ "",
962
+ "**Constraint:** Only executions with `status = 0` (STARTED) can be cancelled.",
963
+ "",
964
+ "Returns the updated execution record."
965
+ ].join("\n"),
966
+ parameters: [
967
+ {
968
+ name: "filterByTk",
969
+ in: "query",
970
+ required: true,
971
+ description: "Execution ID",
972
+ schema: { type: "integer" }
973
+ }
974
+ ],
975
+ responses: {
976
+ 200: {
977
+ description: "OK. Returns the updated execution.",
978
+ content: {
979
+ "application/json": {
980
+ schema: { $ref: "#/components/schemas/execution" }
443
981
  }
444
982
  }
983
+ },
984
+ 400: {
985
+ description: "Bad Request. Execution has already ended (status \u2260 0)."
986
+ },
987
+ 404: { description: "Not Found. Execution does not exist." }
988
+ }
989
+ }
990
+ },
991
+ "/executions:destroy": {
992
+ post: {
993
+ tags: ["executions"],
994
+ summary: "Delete execution records",
995
+ description: [
996
+ "Delete one or more execution records.",
997
+ "**Running executions (`status = 0`, STARTED) cannot be deleted.**",
998
+ "Call `executions:cancel` first if you need to delete a running execution."
999
+ ].join("\n"),
1000
+ parameters: [
1001
+ {
1002
+ name: "filterByTk",
1003
+ in: "query",
1004
+ description: "Execution ID",
1005
+ schema: { type: "integer" }
1006
+ },
1007
+ {
1008
+ name: "filter",
1009
+ in: "query",
1010
+ description: "Filter for batch deletion. Running executions are automatically excluded from deletion.",
1011
+ schema: { type: "object" }
445
1012
  }
1013
+ ],
1014
+ responses: {
1015
+ 200: { description: "OK" }
446
1016
  }
447
1017
  }
448
1018
  },
449
- "/workflowManualTasks:list": {
1019
+ // ─────────────────────────────────────────────────────────────────────────
1020
+ // jobs
1021
+ // ─────────────────────────────────────────────────────────────────────────
1022
+ "/jobs:list": {
450
1023
  get: {
451
- tags: ["workflowManualTasks"],
452
- description: "List manual jobs",
453
- parameters: [],
1024
+ tags: ["jobs"],
1025
+ summary: "List jobs",
1026
+ description: 'Get list of node job records. Usually more convenient to access via `executions:get` with `appends: ["jobs"]`.',
1027
+ parameters: [
1028
+ {
1029
+ name: "filter",
1030
+ in: "query",
1031
+ description: "Filter conditions (e.g. `{ executionId: 1 }`, `{ nodeId: 2 }`)",
1032
+ schema: { type: "object" }
1033
+ },
1034
+ {
1035
+ name: "appends",
1036
+ in: "query",
1037
+ description: "Append associations",
1038
+ schema: { type: "array", items: { type: "string" } }
1039
+ },
1040
+ {
1041
+ name: "sort",
1042
+ in: "query",
1043
+ schema: { type: "string" }
1044
+ },
1045
+ {
1046
+ name: "page",
1047
+ in: "query",
1048
+ schema: { type: "integer" }
1049
+ },
1050
+ {
1051
+ name: "pageSize",
1052
+ in: "query",
1053
+ schema: { type: "integer" }
1054
+ }
1055
+ ],
454
1056
  responses: {
455
1057
  200: {
456
1058
  description: "OK",
@@ -458,10 +1060,7 @@ var swagger_default = {
458
1060
  "application/json": {
459
1061
  schema: {
460
1062
  type: "array",
461
- description: "List of manual jobs",
462
- items: {
463
- $ref: "#/components/schemas/user_job"
464
- }
1063
+ items: { $ref: "#/components/schemas/job" }
465
1064
  }
466
1065
  }
467
1066
  }
@@ -469,50 +1068,59 @@ var swagger_default = {
469
1068
  }
470
1069
  }
471
1070
  },
472
- "/workflowManualTasks:get": {
1071
+ "/jobs:get": {
473
1072
  get: {
474
- tags: ["workflowManualTasks"],
475
- description: "Single user job",
476
- parameters: [],
1073
+ tags: ["jobs"],
1074
+ summary: "Get single job",
1075
+ description: "Get details of a single node job record.",
1076
+ parameters: [
1077
+ {
1078
+ name: "filterByTk",
1079
+ in: "query",
1080
+ required: true,
1081
+ description: "Job ID",
1082
+ schema: { type: "integer" }
1083
+ },
1084
+ {
1085
+ name: "appends",
1086
+ in: "query",
1087
+ description: "Append associations",
1088
+ schema: { type: "array", items: { type: "string" } }
1089
+ }
1090
+ ],
477
1091
  responses: {
478
1092
  200: {
479
1093
  description: "OK",
480
1094
  content: {
481
1095
  "application/json": {
482
- schema: {
483
- allOf: [
484
- {
485
- $ref: "#/components/schemas/user_job"
486
- },
487
- {
488
- type: "object",
489
- properties: {
490
- execution: {
491
- $ref: "#/components/schemas/execution"
492
- }
493
- }
494
- }
495
- ]
496
- }
1096
+ schema: { $ref: "#/components/schemas/job" }
497
1097
  }
498
1098
  }
499
1099
  }
500
1100
  }
501
1101
  }
502
1102
  },
503
- "/workflowManualTasks:submit": {
1103
+ "/jobs:resume": {
504
1104
  post: {
505
- tags: ["workflowManualTasks"],
506
- description: "",
1105
+ tags: ["jobs"],
1106
+ summary: "Resume execution via a job",
1107
+ description: [
1108
+ "Update a job's fields and signal the workflow processor to resume the paused execution.",
1109
+ "",
1110
+ "This is the mechanism for continuing execution after a waiting/interactive node",
1111
+ "(e.g. manual processing, approval) has been handled.",
1112
+ "",
1113
+ "The job must exist. After the update the execution is resumed asynchronously.",
1114
+ "",
1115
+ "Returns HTTP 202 Accepted with the updated job."
1116
+ ].join("\n"),
507
1117
  parameters: [
508
1118
  {
509
1119
  name: "filterByTk",
510
1120
  in: "query",
511
- description: "Primary key of a record",
512
- schema: {
513
- type: "integer",
514
- description: "ID"
515
- }
1121
+ required: true,
1122
+ description: "Job ID",
1123
+ schema: { type: "integer" }
516
1124
  }
517
1125
  ],
518
1126
  requestBody: {
@@ -520,17 +1128,19 @@ var swagger_default = {
520
1128
  "application/json": {
521
1129
  schema: {
522
1130
  type: "object",
1131
+ description: "Fields to update on the job before resuming",
523
1132
  properties: {
1133
+ status: {
1134
+ type: "integer",
1135
+ description: "Job status: 1=RESOLVED, -1=FAILED, -3=ABORTED, -4=CANCELED, -5=REJECTED"
1136
+ },
524
1137
  result: {
525
1138
  type: "object",
526
- properties: {
527
- $formKey: {
528
- type: "object"
529
- },
530
- _: {
531
- type: "string"
532
- }
533
- }
1139
+ description: "Result data to store on the job"
1140
+ },
1141
+ meta: {
1142
+ type: "object",
1143
+ description: "Metadata to store on the job"
534
1144
  }
535
1145
  }
536
1146
  }
@@ -539,15 +1149,80 @@ var swagger_default = {
539
1149
  },
540
1150
  responses: {
541
1151
  202: {
542
- description: "Accepted"
1152
+ description: "Accepted. Job updated and execution resume signalled.",
1153
+ content: {
1154
+ "application/json": {
1155
+ schema: { $ref: "#/components/schemas/job" }
1156
+ }
1157
+ }
543
1158
  },
544
- 400: {
545
- description: "Bad Request. Status of the job is not 0."
1159
+ 404: { description: "Not Found. Job does not exist." }
1160
+ }
1161
+ }
1162
+ },
1163
+ // ─────────────────────────────────────────────────────────────────────────
1164
+ // userWorkflowTasks
1165
+ // ─────────────────────────────────────────────────────────────────────────
1166
+ "/userWorkflowTasks:listMine": {
1167
+ get: {
1168
+ tags: ["userWorkflowTasks"],
1169
+ summary: "List my workflow tasks",
1170
+ description: [
1171
+ "Get workflow tasks assigned to the currently logged-in user.",
1172
+ "The server automatically injects `userId = currentUser.id` into the filter.",
1173
+ "",
1174
+ "This is the base action for listing user-specific interactive tasks.",
1175
+ "Extension plugins (e.g. plugin-workflow-manual, plugin-workflow-approval) may",
1176
+ "provide additional task-type-specific actions on this same resource."
1177
+ ].join("\n"),
1178
+ parameters: [
1179
+ {
1180
+ name: "filter",
1181
+ in: "query",
1182
+ description: "Additional filter conditions",
1183
+ schema: { type: "object" }
1184
+ },
1185
+ {
1186
+ name: "appends",
1187
+ in: "query",
1188
+ description: "Append associations",
1189
+ schema: { type: "array", items: { type: "string" } }
1190
+ },
1191
+ {
1192
+ name: "sort",
1193
+ in: "query",
1194
+ schema: { type: "string" }
1195
+ },
1196
+ {
1197
+ name: "page",
1198
+ in: "query",
1199
+ schema: { type: "integer" }
1200
+ },
1201
+ {
1202
+ name: "pageSize",
1203
+ in: "query",
1204
+ schema: { type: "integer" }
1205
+ }
1206
+ ],
1207
+ responses: {
1208
+ 200: {
1209
+ description: "OK",
1210
+ content: {
1211
+ "application/json": {
1212
+ schema: {
1213
+ type: "array",
1214
+ items: { $ref: "#/components/schemas/user_job" }
1215
+ }
1216
+ }
1217
+ }
546
1218
  }
547
1219
  }
548
1220
  }
549
1221
  }
550
1222
  },
1223
+ // ───────────────────────────────────────────────────────────────────────────
1224
+ // Schemas
1225
+ // ───────────────────────────────────────────────────────────────────────────
551
1226
  components: {
552
1227
  schemas: {
553
1228
  workflow: {
@@ -561,7 +1236,7 @@ var swagger_default = {
561
1236
  },
562
1237
  key: {
563
1238
  type: "string",
564
- description: "Key. Variant versions of the same workflow share the same key."
1239
+ description: "Version group key. All versions of the same workflow share the same key."
565
1240
  },
566
1241
  title: {
567
1242
  type: "string",
@@ -571,40 +1246,69 @@ var swagger_default = {
571
1246
  type: "string",
572
1247
  description: "Description"
573
1248
  },
1249
+ triggerTitle: {
1250
+ type: "string",
1251
+ description: "Trigger display label (optional, UI only)"
1252
+ },
574
1253
  current: {
575
1254
  type: "boolean",
576
- description: "Current version"
1255
+ description: "Whether this is the active version. Only one version per `key` can have `current: true`."
577
1256
  },
578
1257
  enabled: {
579
1258
  type: "boolean",
580
- description: "Enabled"
1259
+ description: "Whether the workflow is enabled. Enabling registers the trigger listener."
581
1260
  },
582
1261
  type: {
583
1262
  type: "string",
584
- description: "Event type"
1263
+ description: "Trigger type (e.g. `collection`, `schedule`)"
1264
+ },
1265
+ sync: {
1266
+ type: "boolean",
1267
+ description: "Synchronous execution mode. `true` = execute immediately and return; `false` = queue async. Cannot be changed after creation."
585
1268
  },
586
1269
  config: {
587
1270
  type: "object",
588
- description: "Configuration JSON object"
1271
+ description: "Trigger configuration JSON object. Structure depends on `type`."
1272
+ },
1273
+ options: {
1274
+ type: "object",
1275
+ description: "Engine options",
1276
+ properties: {
1277
+ deleteExecutionOnStatus: {
1278
+ type: "array",
1279
+ description: "Auto-delete execution records when they reach any of these status codes.",
1280
+ items: { type: "integer" }
1281
+ },
1282
+ stackLimit: {
1283
+ type: "integer",
1284
+ description: "Maximum recursive trigger depth. Executions beyond this limit are skipped. Default: 1.",
1285
+ default: 1
1286
+ }
1287
+ }
1288
+ },
1289
+ categories: {
1290
+ type: "array",
1291
+ description: "Category IDs (belongsToMany `workflowCategories`)",
1292
+ items: { type: "integer" }
589
1293
  },
590
1294
  nodes: {
591
1295
  type: "array",
592
- description: "Workflow nodes"
1296
+ description: "Workflow nodes (association)"
593
1297
  },
594
1298
  executions: {
595
1299
  type: "array",
596
- description: "Executions"
1300
+ description: "Executions (association)"
597
1301
  },
598
1302
  revisions: {
599
1303
  type: "array",
600
- description: "Revisions"
1304
+ description: "Other versions sharing the same `key` (association)"
601
1305
  }
602
1306
  }
603
1307
  },
604
1308
  filterByTk: {
605
1309
  name: "filterByTk",
606
1310
  in: "query",
607
- description: "Primary key of a record",
1311
+ description: "Primary key (ID) of the workflow",
608
1312
  schema: {
609
1313
  type: "integer",
610
1314
  description: "ID"
@@ -657,38 +1361,40 @@ var swagger_default = {
657
1361
  },
658
1362
  upstreamId: {
659
1363
  type: "integer",
660
- description: "Upstream node ID"
1364
+ nullable: true,
1365
+ description: "Upstream node ID. `null` means this is the first node (head) after the trigger."
661
1366
  },
662
1367
  upstream: {
663
1368
  type: "object",
664
- description: "Upstream node",
1369
+ description: "Upstream node (association)",
665
1370
  $ref: "#/components/schemas/node"
666
1371
  },
667
1372
  downstreamId: {
668
1373
  type: "integer",
669
- description: "Downstream node ID in flow, not in sub-branches",
670
- $ref: "#/components/schemas/node"
1374
+ nullable: true,
1375
+ description: "Downstream node ID in the main chain (not counting sub-branches)"
671
1376
  },
672
1377
  downstream: {
673
1378
  type: "object",
674
- description: "Downstream node",
1379
+ description: "Downstream node (association)",
675
1380
  $ref: "#/components/schemas/node"
676
1381
  },
677
1382
  type: {
678
1383
  type: "string",
679
- description: "Node type"
1384
+ description: "Node type (e.g. `calculation`, `condition`, `query`, `create`, `update`, `destroy`)"
680
1385
  },
681
1386
  config: {
682
1387
  type: "object",
683
- description: "Configuration JSON object"
1388
+ description: "Node configuration JSON object. Structure depends on the node `type`."
684
1389
  },
685
1390
  branchIndex: {
686
1391
  type: "integer",
687
- description: "Non-null if the node is a branch node of upstream"
1392
+ nullable: true,
1393
+ description: "Branch index. Non-null when the node is the head of a branch from its upstream."
688
1394
  },
689
1395
  branches: {
690
1396
  type: "array",
691
- description: "Branch nodes under the node",
1397
+ description: "Branch head nodes of this node (association)",
692
1398
  items: {
693
1399
  $ref: "#/components/schemas/node"
694
1400
  }
@@ -697,7 +1403,7 @@ var swagger_default = {
697
1403
  },
698
1404
  execution: {
699
1405
  type: "object",
700
- description: "Execution record of workflow",
1406
+ description: "Workflow execution record",
701
1407
  properties: {
702
1408
  id: {
703
1409
  type: "integer",
@@ -705,23 +1411,38 @@ var swagger_default = {
705
1411
  },
706
1412
  key: {
707
1413
  type: "string",
708
- description: "Workflow key"
1414
+ description: "Workflow key (version group identifier)"
709
1415
  },
710
1416
  workflowId: {
711
1417
  type: "integer",
712
- description: "Workflow ID"
1418
+ description: "Workflow version ID"
713
1419
  },
714
1420
  context: {
715
1421
  type: "object",
716
- description: "Context data"
1422
+ description: "Trigger context data passed at the time of execution"
717
1423
  },
718
1424
  status: {
719
1425
  type: "integer",
720
- description: "Status of execution"
1426
+ description: [
1427
+ "Execution status code:",
1428
+ "- `null` : QUEUEING (waiting to start)",
1429
+ "- `0` : STARTED (running)",
1430
+ "- `1` : RESOLVED (completed successfully)",
1431
+ "- `-1` : FAILED",
1432
+ "- `-2` : ERROR",
1433
+ "- `-3` : ABORTED (forcibly cancelled)",
1434
+ "- `-4` : CANCELED",
1435
+ "- `-5` : REJECTED",
1436
+ "- `-6` : RETRY_NEEDED"
1437
+ ].join("\n")
1438
+ },
1439
+ output: {
1440
+ type: "object",
1441
+ description: "Output node results"
721
1442
  },
722
1443
  jobs: {
723
1444
  type: "array",
724
- description: "Results of executed nodes",
1445
+ description: 'Node job results (included when `appends: ["jobs"]`)',
725
1446
  items: {
726
1447
  $ref: "#/components/schemas/job"
727
1448
  }
@@ -730,7 +1451,7 @@ var swagger_default = {
730
1451
  },
731
1452
  job: {
732
1453
  type: "object",
733
- description: "Job record of exected node",
1454
+ description: "Node job execution record",
734
1455
  properties: {
735
1456
  id: {
736
1457
  type: "integer",
@@ -744,19 +1465,37 @@ var swagger_default = {
744
1465
  type: "integer",
745
1466
  description: "Node ID"
746
1467
  },
1468
+ nodeKey: {
1469
+ type: "string",
1470
+ description: "Node key (for cross-version reference)"
1471
+ },
747
1472
  status: {
748
1473
  type: "integer",
749
- description: "Status of job"
1474
+ description: [
1475
+ "Job status code:",
1476
+ "- `0` : PENDING (waiting, e.g. manual node)",
1477
+ "- `1` : RESOLVED (completed)",
1478
+ "- `-1` : FAILED",
1479
+ "- `-2` : ERROR",
1480
+ "- `-3` : ABORTED",
1481
+ "- `-4` : CANCELED",
1482
+ "- `-5` : REJECTED",
1483
+ "- `-6` : RETRY_NEEDED"
1484
+ ].join("\n")
750
1485
  },
751
1486
  result: {
752
1487
  type: "object",
753
- description: "Result data of job"
1488
+ description: "Result data of the job"
1489
+ },
1490
+ meta: {
1491
+ type: "object",
1492
+ description: "Metadata of the job"
754
1493
  }
755
1494
  }
756
1495
  },
757
1496
  user_job: {
758
1497
  type: "object",
759
- description: "User job",
1498
+ description: "User workflow task (an interactive task assigned to a specific user)",
760
1499
  properties: {
761
1500
  id: {
762
1501
  type: "integer",
@@ -776,15 +1515,15 @@ var swagger_default = {
776
1515
  },
777
1516
  userId: {
778
1517
  type: "integer",
779
- description: "User ID"
1518
+ description: "Assigned user ID"
780
1519
  },
781
1520
  status: {
782
1521
  type: "integer",
783
- description: "Status of job"
1522
+ description: "Task status (same enum as JOB_STATUS)"
784
1523
  },
785
1524
  result: {
786
1525
  type: "object",
787
- description: "Result data of job"
1526
+ description: "Task result data"
788
1527
  }
789
1528
  }
790
1529
  }