@solidxai/core 0.1.13-beta.3 → 0.1.13-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/seed.command.d.ts +2 -0
- package/dist/commands/seed.command.d.ts.map +1 -1
- package/dist/commands/seed.command.js +21 -0
- package/dist/commands/seed.command.js.map +1 -1
- package/dist/entities/workflow-trigger-execution.entity.js +1 -1
- package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +44 -27
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +80 -67
- package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
- package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
- package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/for-each.node.js +114 -5
- package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
- package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/if.node.js +7 -0
- package/dist/services/workflow/nodes/if.node.js.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.js +2 -0
- package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
- package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
- package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/loop-until.node.js +281 -0
- package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
- package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/parallel.node.js +7 -0
- package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.js +7 -0
- package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
- package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/switch.node.js +7 -0
- package/dist/services/workflow/nodes/switch.node.js.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
- package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
- package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-expression.service.js +5 -0
- package/dist/services/workflow/workflow-expression.service.js.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.js +7 -0
- package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
- package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.js +197 -32
- package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +4 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/types/workflow-dsl.types.d.ts +14 -0
- package/dist/types/workflow-dsl.types.d.ts.map +1 -1
- package/dist/types/workflow-dsl.types.js.map +1 -1
- package/dist-tests/api/authenticate.spec.js +119 -0
- package/dist-tests/api/authenticate.spec.js.map +1 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
- package/dist-tests/api/ping.spec.js +21 -0
- package/dist-tests/api/ping.spec.js.map +1 -0
- package/dist-tests/helpers/auth.js +41 -0
- package/dist-tests/helpers/auth.js.map +1 -0
- package/dist-tests/helpers/env.js +11 -0
- package/dist-tests/helpers/env.js.map +1 -0
- package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +136 -0
- package/docs/agent-builder/team-ready-note-agent-builder.md +305 -0
- package/docs/agent-hub-grooming.md +301 -0
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
- package/docs/datasource-introspection-ddl-analysis.md +326 -0
- package/docs/datasource-introspection-implementation-plan.md +306 -0
- package/docs/grouping-enhancements.md +89 -0
- package/docs/java-spring/README.md +3 -0
- package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
- package/docs/module-package-import-handoff.md +691 -0
- package/docs/seed-changes.md +65 -0
- package/docs/test-data-workflow.md +200 -0
- package/docs/type-declaration-import-issue.md +24 -0
- package/docs/workflow/business-automation-example-notes.md +309 -0
- package/docs/workflow/control-flow-node-addition-sop.md +324 -0
- package/docs/workflow/data-engineering-pipeline-example-notes.md +330 -0
- package/docs/workflow/foreach-example-notes.md +187 -0
- package/docs/workflow/hello-world-example-notes.md +271 -0
- package/docs/workflow/kestra-concepts-plugins-blueprints.md +315 -0
- package/docs/workflow/loop-until-example-notes.md +198 -0
- package/docs/workflow/microservices-and-apis-example-notes.md +264 -0
- package/docs/workflow/samples.md +25 -0
- package/docs/workflow/what-is-kestra.md +79 -0
- package/docs/workflow/workflow-core-module-handoff-summary.md +191 -0
- package/docs/workflow/workflow-module-brd.md +185 -0
- package/docs/workflow/workflow-module-domain-model.md +252 -0
- package/docs/workflow/workflow-module-metadata-dsl.md +302 -0
- package/docs/workflow/workflow-module-technical-spec.md +293 -0
- package/docs/workflow/workflow-node-type-contracts.md +635 -0
- package/docs/workflow/workflow-node-ui-metadata-contract.md +1262 -0
- package/docs/workflow/workflow-solidx-model-field-spec.md +284 -0
- package/package.json +1 -1
- package/src/commands/seed.command.ts +19 -0
- package/src/entities/workflow-trigger-execution.entity.ts +1 -1
- package/src/index.ts +2 -0
- package/src/interfaces.ts +1 -0
- package/src/seeders/module-metadata-seeder.service.ts +50 -36
- package/src/seeders/seed-data/solid-core-metadata.json +80 -67
- package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
- package/src/services/workflow/nodes/for-each.node.ts +140 -6
- package/src/services/workflow/nodes/if.node.ts +7 -0
- package/src/services/workflow/nodes/log-write.node.ts +2 -0
- package/src/services/workflow/nodes/loop-until.node.ts +343 -0
- package/src/services/workflow/nodes/parallel.node.ts +7 -0
- package/src/services/workflow/nodes/sequential.node.ts +7 -0
- package/src/services/workflow/nodes/switch.node.ts +7 -0
- package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
- package/src/services/workflow/workflow-expression.service.ts +5 -0
- package/src/services/workflow/workflow-node-registry.service.ts +11 -0
- package/src/services/workflow/workflow-runtime.service.ts +274 -39
- package/src/solid-core.module.ts +4 -0
- package/src/types/workflow-dsl.types.ts +43 -0
- package/.claude/settings.local.json +0 -16
- package/CLAUDE.md +0 -26
- package/src/services/1.js +0 -6
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Workflow Builder Metadata / DSL Shape
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This document captures the current YAML representation for workflows in the `workflow-builder` module.
|
|
6
|
+
|
|
7
|
+
The design goals are:
|
|
8
|
+
|
|
9
|
+
- human-shareable
|
|
10
|
+
- seedable
|
|
11
|
+
- import/export friendly
|
|
12
|
+
- expressive enough for a visual builder
|
|
13
|
+
- structured enough for validation
|
|
14
|
+
|
|
15
|
+
## Design Principles
|
|
16
|
+
|
|
17
|
+
- YAML is the canonical persisted format in the `workflowDefinition.definitionYaml` field
|
|
18
|
+
- The YAML must parse into a structured object with a top-level `nodes` array
|
|
19
|
+
- Metadata, inputs, variables, nodes, and triggers should be explicit sections where needed
|
|
20
|
+
- The format must support both runnable steps and control-flow nodes
|
|
21
|
+
- The format must support future extensibility
|
|
22
|
+
|
|
23
|
+
## Proposed Top-Level Shape
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
version: "1.0"
|
|
27
|
+
description: Checks service health and notifies on failure
|
|
28
|
+
inputs:
|
|
29
|
+
uri:
|
|
30
|
+
type: uri
|
|
31
|
+
required: true
|
|
32
|
+
defaultValue: https://kestra.io
|
|
33
|
+
variables: {}
|
|
34
|
+
triggers: []
|
|
35
|
+
nodes: []
|
|
36
|
+
metadata:
|
|
37
|
+
namespace: ops.monitoring
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Top-Level Sections
|
|
41
|
+
|
|
42
|
+
### `version`
|
|
43
|
+
|
|
44
|
+
Optional version of the workflow DSL/schema.
|
|
45
|
+
|
|
46
|
+
### `description`
|
|
47
|
+
|
|
48
|
+
Optional workflow description.
|
|
49
|
+
|
|
50
|
+
### `inputs`
|
|
51
|
+
|
|
52
|
+
Optional map of workflow input definitions or input defaults.
|
|
53
|
+
|
|
54
|
+
### `variables`
|
|
55
|
+
|
|
56
|
+
Optional map of workflow variables. Runtime request variables can override these values.
|
|
57
|
+
|
|
58
|
+
### `triggers`
|
|
59
|
+
|
|
60
|
+
Optional array of trigger definitions.
|
|
61
|
+
|
|
62
|
+
### `nodes`
|
|
63
|
+
|
|
64
|
+
Required ordered array of workflow node definitions.
|
|
65
|
+
|
|
66
|
+
### `metadata`
|
|
67
|
+
|
|
68
|
+
Optional object for authoring, grouping, seed, or UI metadata that does not belong to runtime state.
|
|
69
|
+
|
|
70
|
+
## Inputs Shape
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
inputs:
|
|
74
|
+
uri:
|
|
75
|
+
type: uri
|
|
76
|
+
displayName: Target URI
|
|
77
|
+
required: true
|
|
78
|
+
defaultValue: https://kestra.io
|
|
79
|
+
description: Endpoint to check
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Trigger Shape
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
triggers:
|
|
86
|
+
- id: dailySchedule
|
|
87
|
+
type: schedule
|
|
88
|
+
disabled: false
|
|
89
|
+
configuration:
|
|
90
|
+
cron: "0 9 * * *"
|
|
91
|
+
metadata:
|
|
92
|
+
inputOverrides:
|
|
93
|
+
uri: https://kestra.io/docs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Node Shape
|
|
97
|
+
|
|
98
|
+
All workflow steps should be represented as nodes.
|
|
99
|
+
|
|
100
|
+
Suggested base shape:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
id: makeRequest
|
|
104
|
+
kind: task
|
|
105
|
+
type: http.request
|
|
106
|
+
name: Make Request
|
|
107
|
+
description: Calls the configured endpoint
|
|
108
|
+
disabled: false
|
|
109
|
+
configuration:
|
|
110
|
+
uri: "{{ inputs.uri }}"
|
|
111
|
+
metadata: {}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Node Kinds
|
|
115
|
+
|
|
116
|
+
Initial node kinds:
|
|
117
|
+
|
|
118
|
+
- `task`
|
|
119
|
+
- `control`
|
|
120
|
+
- `subflow`
|
|
121
|
+
|
|
122
|
+
The agreed rule is:
|
|
123
|
+
|
|
124
|
+
- `kind` is the broad behavior category
|
|
125
|
+
- `type` is the concrete implementation
|
|
126
|
+
|
|
127
|
+
Agreed v1 node type catalog:
|
|
128
|
+
|
|
129
|
+
- `log.write`
|
|
130
|
+
- `http.request`
|
|
131
|
+
- `if`
|
|
132
|
+
- `forEach`
|
|
133
|
+
- `parallel`
|
|
134
|
+
|
|
135
|
+
Deferred node types:
|
|
136
|
+
|
|
137
|
+
- `switch`
|
|
138
|
+
- `loopUntil`
|
|
139
|
+
- `forEachItem`
|
|
140
|
+
- `subflow`
|
|
141
|
+
|
|
142
|
+
## Control-Flow Shape
|
|
143
|
+
|
|
144
|
+
V1 sequencing follows Kestra-style ordered arrays with nested child arrays. We are not using a freeform graph model in v1.
|
|
145
|
+
|
|
146
|
+
Example `if` node:
|
|
147
|
+
|
|
148
|
+
```yaml
|
|
149
|
+
id: checkStatus
|
|
150
|
+
kind: control
|
|
151
|
+
type: if
|
|
152
|
+
configuration:
|
|
153
|
+
condition: "{{ outputs.makeRequest.statusCode == 200 }}"
|
|
154
|
+
then:
|
|
155
|
+
- id: logSuccess
|
|
156
|
+
kind: task
|
|
157
|
+
type: log.write
|
|
158
|
+
configuration:
|
|
159
|
+
message: Request successful
|
|
160
|
+
else:
|
|
161
|
+
- id: notifyFailure
|
|
162
|
+
kind: task
|
|
163
|
+
type: notification.slack
|
|
164
|
+
configuration:
|
|
165
|
+
message: Request failed
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Example `forEach` node:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
id: forEachCustomer
|
|
172
|
+
kind: control
|
|
173
|
+
type: forEach
|
|
174
|
+
configuration:
|
|
175
|
+
values: "{{ inputs.customerIds }}"
|
|
176
|
+
children:
|
|
177
|
+
- id: processCustomer
|
|
178
|
+
kind: task
|
|
179
|
+
type: custom.processCustomer
|
|
180
|
+
configuration:
|
|
181
|
+
customerId: "{{ step.value }}"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Example `parallel` node:
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
id: runChecks
|
|
188
|
+
kind: control
|
|
189
|
+
type: parallel
|
|
190
|
+
configuration: {}
|
|
191
|
+
branches:
|
|
192
|
+
- id: checkDocs
|
|
193
|
+
nodes:
|
|
194
|
+
- id: requestDocs
|
|
195
|
+
kind: task
|
|
196
|
+
type: http.request
|
|
197
|
+
configuration:
|
|
198
|
+
uri: https://kestra.io/docs
|
|
199
|
+
- id: checkPlugins
|
|
200
|
+
nodes:
|
|
201
|
+
- id: requestPlugins
|
|
202
|
+
kind: task
|
|
203
|
+
type: http.request
|
|
204
|
+
configuration:
|
|
205
|
+
uri: https://kestra.io/plugins
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## V1 Node Type Configuration
|
|
209
|
+
|
|
210
|
+
Detailed node contracts are captured in `docs/workflow-node-type-contracts.md`.
|
|
211
|
+
|
|
212
|
+
### `log.write`
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
id: logStatus
|
|
216
|
+
kind: task
|
|
217
|
+
type: log.write
|
|
218
|
+
configuration:
|
|
219
|
+
message: "Status Code: {{ outputs.makeRequest.statusCode }}"
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### `http.request`
|
|
223
|
+
|
|
224
|
+
The HTTP node should use `uri`, matching the Kestra convention.
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
id: makeRequest
|
|
228
|
+
kind: task
|
|
229
|
+
type: http.request
|
|
230
|
+
configuration:
|
|
231
|
+
method: GET
|
|
232
|
+
uri: "{{ inputs.uri }}"
|
|
233
|
+
headers: {}
|
|
234
|
+
body: null
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Outputs Shape
|
|
238
|
+
|
|
239
|
+
The current runtime returns the accumulated node outputs as the execution output payload. A future explicit flow-level outputs section can be added when the runtime starts evaluating named output expressions.
|
|
240
|
+
|
|
241
|
+
## Example Workflow
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
version: "1.0"
|
|
245
|
+
description: Checks a URI and logs the result
|
|
246
|
+
inputs:
|
|
247
|
+
uri:
|
|
248
|
+
type: uri
|
|
249
|
+
required: true
|
|
250
|
+
defaultValue: https://kestra.io
|
|
251
|
+
triggers:
|
|
252
|
+
- id: dailySchedule
|
|
253
|
+
type: schedule
|
|
254
|
+
configuration:
|
|
255
|
+
cron: "0 9 * * *"
|
|
256
|
+
nodes:
|
|
257
|
+
- id: makeRequest
|
|
258
|
+
kind: task
|
|
259
|
+
type: http.request
|
|
260
|
+
configuration:
|
|
261
|
+
method: GET
|
|
262
|
+
uri: "{{ inputs.uri }}"
|
|
263
|
+
- id: logStatus
|
|
264
|
+
kind: task
|
|
265
|
+
type: log.write
|
|
266
|
+
configuration:
|
|
267
|
+
message: "Status Code: {{ outputs.makeRequest.statusCode }}"
|
|
268
|
+
metadata:
|
|
269
|
+
key: daily-health-check
|
|
270
|
+
displayName: Daily Health Check
|
|
271
|
+
namespace: ops.monitoring
|
|
272
|
+
definitionVersion: 0.1.0
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Seeding Metadata
|
|
276
|
+
|
|
277
|
+
For portable and seeded workflows, we should likely support optional metadata such as:
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
metadata:
|
|
281
|
+
seed:
|
|
282
|
+
sourceModule: workflow-builder
|
|
283
|
+
seedKey: daily-health-check
|
|
284
|
+
seedVersion: 1.0.0
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
This should live under top-level `metadata` unless the runtime grows a first-class seed section.
|
|
288
|
+
|
|
289
|
+
## Snapshot Guidance
|
|
290
|
+
|
|
291
|
+
At execution time, the system should preserve the exact YAML definition snapshot used for the run, along with:
|
|
292
|
+
|
|
293
|
+
- `definitionVersion`
|
|
294
|
+
- `version`
|
|
295
|
+
- checksum
|
|
296
|
+
|
|
297
|
+
## Open DSL Questions
|
|
298
|
+
|
|
299
|
+
- Should `nodes` stay as an ordered array with nesting, or should we move to explicit edges later?
|
|
300
|
+
- Should `namespace` be a simple string path in the DSL?
|
|
301
|
+
- Should task configuration schemas be JSON Schema based from day one?
|
|
302
|
+
- How should secret references be encoded inside configuration values?
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Workflow Builder Technical Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`workflow-builder` will be implemented as a reusable SolidX module with:
|
|
6
|
+
|
|
7
|
+
- backend module code in `solid-api`
|
|
8
|
+
- frontend module code in `solid-ui`
|
|
9
|
+
- module metadata for menus, actions, and views
|
|
10
|
+
- YAML-based workflow definitions persisted and executed by the module
|
|
11
|
+
|
|
12
|
+
## Technical Principles
|
|
13
|
+
|
|
14
|
+
- Separate definition-time models from runtime execution models
|
|
15
|
+
- Store workflows as canonical YAML containing a structured DSL, not arbitrary opaque text
|
|
16
|
+
- Keep the engine extensible via registries for task and trigger types
|
|
17
|
+
- Preserve immutable execution-time snapshots
|
|
18
|
+
- Design for future revision support without requiring full revision UX in v1
|
|
19
|
+
|
|
20
|
+
## Proposed Architecture
|
|
21
|
+
|
|
22
|
+
### 1. Definition Layer
|
|
23
|
+
|
|
24
|
+
Responsible for:
|
|
25
|
+
|
|
26
|
+
- workflow CRUD
|
|
27
|
+
- validation of workflow YAML
|
|
28
|
+
- seed/import/export
|
|
29
|
+
- blueprint/template management
|
|
30
|
+
- registration of task and trigger types
|
|
31
|
+
|
|
32
|
+
### 2. Runtime Layer
|
|
33
|
+
|
|
34
|
+
Responsible for:
|
|
35
|
+
|
|
36
|
+
- execution creation
|
|
37
|
+
- context hydration
|
|
38
|
+
- expression resolution
|
|
39
|
+
- step scheduling / traversal
|
|
40
|
+
- step execution
|
|
41
|
+
- state persistence
|
|
42
|
+
- logs, outputs, and artifacts
|
|
43
|
+
|
|
44
|
+
### 3. Authoring Layer
|
|
45
|
+
|
|
46
|
+
Responsible for:
|
|
47
|
+
|
|
48
|
+
- workflow editing UI
|
|
49
|
+
- typed configuration UI for tasks/triggers
|
|
50
|
+
- validation feedback
|
|
51
|
+
- topology / graph visualization over time
|
|
52
|
+
|
|
53
|
+
## Backend Concerns
|
|
54
|
+
|
|
55
|
+
### Definition Services
|
|
56
|
+
|
|
57
|
+
Likely services:
|
|
58
|
+
|
|
59
|
+
- `WorkflowDefinitionService`
|
|
60
|
+
- `WorkflowValidationService`
|
|
61
|
+
- `WorkflowSeedService`
|
|
62
|
+
- `WorkflowBlueprintService`
|
|
63
|
+
- `WorkflowRegistryService`
|
|
64
|
+
|
|
65
|
+
### Runtime Services
|
|
66
|
+
|
|
67
|
+
Likely services:
|
|
68
|
+
|
|
69
|
+
- `WorkflowExecutionService`
|
|
70
|
+
- `WorkflowContextService`
|
|
71
|
+
- `ExpressionEvaluationService`
|
|
72
|
+
- `WorkflowTraversalService`
|
|
73
|
+
- `TaskExecutionService`
|
|
74
|
+
- `TriggerDispatchService`
|
|
75
|
+
|
|
76
|
+
### Registries
|
|
77
|
+
|
|
78
|
+
The system should use registries instead of hard-coded switch blocks for every capability:
|
|
79
|
+
|
|
80
|
+
- task type registry
|
|
81
|
+
- trigger type registry
|
|
82
|
+
- expression function registry later if needed
|
|
83
|
+
|
|
84
|
+
For node execution, registry entries should eventually expose:
|
|
85
|
+
|
|
86
|
+
- type id
|
|
87
|
+
- kind
|
|
88
|
+
- category
|
|
89
|
+
- configuration schema
|
|
90
|
+
- UI schema
|
|
91
|
+
- runtime handler
|
|
92
|
+
- output schema
|
|
93
|
+
- documentation metadata
|
|
94
|
+
|
|
95
|
+
## Frontend Concerns
|
|
96
|
+
|
|
97
|
+
### Admin Surfaces
|
|
98
|
+
|
|
99
|
+
Likely UI areas:
|
|
100
|
+
|
|
101
|
+
- workflow list
|
|
102
|
+
- workflow editor
|
|
103
|
+
- execution list
|
|
104
|
+
- execution detail
|
|
105
|
+
- blueprint gallery
|
|
106
|
+
- task/trigger type config panels
|
|
107
|
+
|
|
108
|
+
### Authoring Modes
|
|
109
|
+
|
|
110
|
+
Recommended phased approach:
|
|
111
|
+
|
|
112
|
+
- V1: schema-driven form/editor experience
|
|
113
|
+
- V1.x: structured YAML editor + validation
|
|
114
|
+
- Later: canvas/topology builder with drag-drop
|
|
115
|
+
|
|
116
|
+
## Execution Model
|
|
117
|
+
|
|
118
|
+
At runtime, an execution should:
|
|
119
|
+
|
|
120
|
+
1. Resolve the published workflow definition
|
|
121
|
+
2. Persist an immutable definition snapshot or checksum reference
|
|
122
|
+
3. Merge manual or trigger-provided inputs
|
|
123
|
+
4. Build an execution context
|
|
124
|
+
5. Traverse nodes according to orchestration rules
|
|
125
|
+
6. Execute runnable steps
|
|
126
|
+
7. Persist step outputs, logs, and states
|
|
127
|
+
8. Finalize flow outputs and execution status
|
|
128
|
+
|
|
129
|
+
V1 traversal model:
|
|
130
|
+
|
|
131
|
+
- top-level workflow nodes are executed as an ordered array
|
|
132
|
+
- control-flow nodes own nested child arrays such as `then`, `else`, `children`, or `branches`
|
|
133
|
+
- we defer full graph/edge traversal until a later phase
|
|
134
|
+
|
|
135
|
+
V1 node type catalog:
|
|
136
|
+
|
|
137
|
+
- `log.write`
|
|
138
|
+
- `http.request`
|
|
139
|
+
- `if`
|
|
140
|
+
- `forEach`
|
|
141
|
+
- `parallel`
|
|
142
|
+
|
|
143
|
+
Deferred node types:
|
|
144
|
+
|
|
145
|
+
- `switch`
|
|
146
|
+
- `loopUntil`
|
|
147
|
+
- `forEachItem`
|
|
148
|
+
- `subflow`
|
|
149
|
+
- database/query tasks
|
|
150
|
+
- notification tasks beyond logging
|
|
151
|
+
|
|
152
|
+
## State Model
|
|
153
|
+
|
|
154
|
+
Suggested initial execution states:
|
|
155
|
+
|
|
156
|
+
- `created`
|
|
157
|
+
- `running`
|
|
158
|
+
- `success`
|
|
159
|
+
- `failed`
|
|
160
|
+
- `cancelled`
|
|
161
|
+
|
|
162
|
+
Suggested step states:
|
|
163
|
+
|
|
164
|
+
- `pending`
|
|
165
|
+
- `running`
|
|
166
|
+
- `success`
|
|
167
|
+
- `failed`
|
|
168
|
+
- `skipped`
|
|
169
|
+
|
|
170
|
+
## Snapshot vs Revisions
|
|
171
|
+
|
|
172
|
+
V1 recommendation:
|
|
173
|
+
|
|
174
|
+
- store the current workflow definition
|
|
175
|
+
- store a version string and/or checksum
|
|
176
|
+
- store the exact definition snapshot used by each execution
|
|
177
|
+
|
|
178
|
+
Defer until later:
|
|
179
|
+
|
|
180
|
+
- full revision browsing
|
|
181
|
+
- rollback UX
|
|
182
|
+
- diff tooling
|
|
183
|
+
|
|
184
|
+
## Trigger Strategy
|
|
185
|
+
|
|
186
|
+
V1 can support a limited trigger set such as:
|
|
187
|
+
|
|
188
|
+
- manual
|
|
189
|
+
- schedule
|
|
190
|
+
- webhook
|
|
191
|
+
|
|
192
|
+
The trigger model should still be extensible enough to support:
|
|
193
|
+
|
|
194
|
+
- polling
|
|
195
|
+
- event-based triggers
|
|
196
|
+
- flow-completion triggers
|
|
197
|
+
|
|
198
|
+
## Expression Strategy
|
|
199
|
+
|
|
200
|
+
We need one engine-wide expression approach. The chosen solution should support:
|
|
201
|
+
|
|
202
|
+
- context access
|
|
203
|
+
- boolean conditions
|
|
204
|
+
- string interpolation
|
|
205
|
+
- light transformations
|
|
206
|
+
- safe evaluation
|
|
207
|
+
|
|
208
|
+
Minimum context objects:
|
|
209
|
+
|
|
210
|
+
- `inputs`
|
|
211
|
+
- `outputs`
|
|
212
|
+
- `workflow`
|
|
213
|
+
- `execution`
|
|
214
|
+
- `trigger`
|
|
215
|
+
- `step` or `taskrun` equivalent where relevant
|
|
216
|
+
|
|
217
|
+
Recommended DSL syntax:
|
|
218
|
+
|
|
219
|
+
- `{{ inputs.uri }}`
|
|
220
|
+
- `{{ outputs.makeRequest.statusCode }}`
|
|
221
|
+
- `{{ outputs.makeRequest.statusCode == 200 }}`
|
|
222
|
+
- `{{ step.value }}`
|
|
223
|
+
|
|
224
|
+
V1 should support string interpolation and expression-only evaluation. Expression evaluation must be safe and constrained; workflow definitions must not be able to execute arbitrary JavaScript or access process, filesystem, network, or module APIs through expressions.
|
|
225
|
+
|
|
226
|
+
The expression engine should be hidden behind `ExpressionEvaluationService` so we can change implementation without changing the workflow DSL.
|
|
227
|
+
|
|
228
|
+
## Node Provider Pluggability
|
|
229
|
+
|
|
230
|
+
Workflow node types should follow the existing SolidX provider pattern used by selection providers, computed field providers, dashboard widget data providers, settings providers, and communication providers.
|
|
231
|
+
|
|
232
|
+
Recommended pattern:
|
|
233
|
+
|
|
234
|
+
- define a `WorkflowNodeTypeProvider` interface
|
|
235
|
+
- define a `@WorkflowNodeTypeProvider()` decorator
|
|
236
|
+
- implement node providers as Nest injectable classes
|
|
237
|
+
- discover decorated providers during application bootstrap
|
|
238
|
+
- register discovered providers into a `WorkflowNodeTypeRegistry`
|
|
239
|
+
- resolve providers by `node.type` at validation and execution time
|
|
240
|
+
|
|
241
|
+
This keeps node availability tied to currently imported SolidX/Nest modules. A consuming app or distributed module can make new workflow nodes available by importing the module that provides decorated node providers.
|
|
242
|
+
|
|
243
|
+
## Secret Strategy
|
|
244
|
+
|
|
245
|
+
Definitions should store secret references, not secret values. Resolution should happen only at runtime via a secret provider abstraction.
|
|
246
|
+
|
|
247
|
+
Recommended abstraction:
|
|
248
|
+
|
|
249
|
+
- `SecretReference`
|
|
250
|
+
- `SecretResolver`
|
|
251
|
+
|
|
252
|
+
## Seeding and Portability
|
|
253
|
+
|
|
254
|
+
Workflow definitions should be portable assets. A seeded workflow should carry metadata such as:
|
|
255
|
+
|
|
256
|
+
- source module
|
|
257
|
+
- seed key
|
|
258
|
+
- seed version
|
|
259
|
+
- definition version
|
|
260
|
+
|
|
261
|
+
## Suggested Implementation Phases
|
|
262
|
+
|
|
263
|
+
### Phase 1
|
|
264
|
+
|
|
265
|
+
- domain models
|
|
266
|
+
- JSON schema/validator for workflow definition
|
|
267
|
+
- definition CRUD
|
|
268
|
+
- manual execution
|
|
269
|
+
- basic runnable task execution for `log.write` and `http.request`
|
|
270
|
+
- registry-driven node type definitions
|
|
271
|
+
- control-flow execution for `if`, `forEach`, and `parallel`
|
|
272
|
+
- execution persistence
|
|
273
|
+
|
|
274
|
+
### Phase 2
|
|
275
|
+
|
|
276
|
+
- triggers
|
|
277
|
+
- control-flow tasks
|
|
278
|
+
- secret references
|
|
279
|
+
- blueprint support
|
|
280
|
+
|
|
281
|
+
### Phase 3
|
|
282
|
+
|
|
283
|
+
- richer editor UX
|
|
284
|
+
- broader plugin/task ecosystem
|
|
285
|
+
- replay/retry semantics
|
|
286
|
+
- fuller revision model
|
|
287
|
+
|
|
288
|
+
## Open Technical Questions
|
|
289
|
+
|
|
290
|
+
- Should the workflow DSL schema be internal-first or externally published from day one?
|
|
291
|
+
- Should execution snapshots store the full JSON body or a normalized linked artifact?
|
|
292
|
+
- What expression engine best fits NestJS + SolidX constraints?
|
|
293
|
+
- How should file/artifact outputs be stored and referenced?
|