@solidxai/core 0.1.13-beta.2 → 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/saved-filters.entity.js +3 -3
- package/dist/entities/saved-filters.entity.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/saved-filters.entity.ts +3 -3
- 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,324 @@
|
|
|
1
|
+
# Control Flow Node Addition SOP
|
|
2
|
+
|
|
3
|
+
This SOP describes the places that must be reviewed when adding a new workflow
|
|
4
|
+
control-flow node type. Control nodes are higher risk than task nodes because
|
|
5
|
+
they own child execution semantics and are interpreted by the runtime, topology
|
|
6
|
+
canvas, validation layer, expression autocomplete, execution logs, and metadata
|
|
7
|
+
sync.
|
|
8
|
+
|
|
9
|
+
Use this document when adding nodes such as `parallel`, `sequential`, `if`,
|
|
10
|
+
`switch`, `forEach`, `loopUntil`, retry groups, fan-out/fan-in controls, human
|
|
11
|
+
approval gates, or other nodes with child slots.
|
|
12
|
+
|
|
13
|
+
## Core Rule
|
|
14
|
+
|
|
15
|
+
A control node must define three contracts together:
|
|
16
|
+
|
|
17
|
+
- Runtime contract: how children execute and what gets written to
|
|
18
|
+
`context.outputs`.
|
|
19
|
+
- Authoring contract: which child slots exist and how they are represented in
|
|
20
|
+
YAML.
|
|
21
|
+
- Reference contract: how downstream nodes can refer to outputs produced by the
|
|
22
|
+
control node and its children.
|
|
23
|
+
|
|
24
|
+
Do not add a control node by only registering a provider class. If the node owns
|
|
25
|
+
children, every section below needs a deliberate yes/no decision.
|
|
26
|
+
|
|
27
|
+
## Backend Files To Review
|
|
28
|
+
|
|
29
|
+
- `src/services/workflow/nodes/<node>.node.ts`
|
|
30
|
+
Add the `WorkflowNodeProvider` metadata and the `WorkflowNodeHandler`
|
|
31
|
+
implementation.
|
|
32
|
+
|
|
33
|
+
- `src/services/workflow/workflow-runtime.service.ts`
|
|
34
|
+
Confirm `context.runNodes(...)` receives the correct context overrides:
|
|
35
|
+
`outputs`, `item`, `index`, `parentNodeId`, and `parentStepExecutionKey`.
|
|
36
|
+
|
|
37
|
+
- `src/services/workflow/workflow-expression.service.ts`
|
|
38
|
+
Confirm expressions can address the data shape exposed by the new control
|
|
39
|
+
node. Most additions should not require changes here if they use plain object
|
|
40
|
+
paths.
|
|
41
|
+
|
|
42
|
+
- `src/services/workflow/workflow-definition-validator.service.ts`
|
|
43
|
+
Confirm the YAML shape is accepted and invalid child-slot shapes are rejected.
|
|
44
|
+
|
|
45
|
+
- `src/types/workflow-dsl.types.ts`
|
|
46
|
+
Update comments and types when introducing a new child collection key,
|
|
47
|
+
execution context concept, or output convention.
|
|
48
|
+
|
|
49
|
+
- `src/services/workflow/workflow-node-registry.service.ts`
|
|
50
|
+
Confirm provider discovery/registration picks up the new node class.
|
|
51
|
+
|
|
52
|
+
## Frontend Files To Review
|
|
53
|
+
|
|
54
|
+
- `solid-core-ui/src/components/workflow/WorkflowFlowCanvas.tsx`
|
|
55
|
+
Confirm the topology visual editor can render the child slots, add-node
|
|
56
|
+
insertion affordances, branch labels, join lines, and nested layout.
|
|
57
|
+
|
|
58
|
+
- `solid-core-ui/src/components/workflow/WorkflowFlowCanvas.css`
|
|
59
|
+
Add styling only if the new control mode needs a distinct visual treatment.
|
|
60
|
+
|
|
61
|
+
- `solid-core-ui/src/components/workflow/WorkflowNodeSchemaEditor.tsx`
|
|
62
|
+
Confirm the node editor displays child slot summaries and runtime fields
|
|
63
|
+
correctly.
|
|
64
|
+
|
|
65
|
+
- `solid-core-ui/src/routes/pages/admin/core/WorkflowDefinitionEditorPage.tsx`
|
|
66
|
+
Review validation, node update/remove traversal, first-node selection,
|
|
67
|
+
expression suggestion collection, and any YAML normalization logic.
|
|
68
|
+
|
|
69
|
+
- `solid-core-ui/src/types/workflow-node.ts`
|
|
70
|
+
Update UI-facing metadata types when adding new slot layout modes, field
|
|
71
|
+
metadata, or output metadata.
|
|
72
|
+
|
|
73
|
+
## Provider Metadata Checklist
|
|
74
|
+
|
|
75
|
+
Every control node provider should define:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
@WorkflowNodeProvider({
|
|
79
|
+
type: 'newControlType',
|
|
80
|
+
kind: 'control',
|
|
81
|
+
category: 'control-flow',
|
|
82
|
+
label: 'New Control Type',
|
|
83
|
+
description: '...',
|
|
84
|
+
authoring: {
|
|
85
|
+
defaultConfiguration: {},
|
|
86
|
+
configurationFields: [],
|
|
87
|
+
childSlots: [
|
|
88
|
+
{
|
|
89
|
+
key: 'tasks',
|
|
90
|
+
label: 'Tasks',
|
|
91
|
+
kind: 'sequence',
|
|
92
|
+
layout: 'sequential',
|
|
93
|
+
required: true,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
outputs: [],
|
|
97
|
+
supportsName: true,
|
|
98
|
+
supportsDescription: true,
|
|
99
|
+
},
|
|
100
|
+
runtime: {
|
|
101
|
+
emitsLogs: true,
|
|
102
|
+
emitsArtifacts: false,
|
|
103
|
+
deterministicOutputs: false,
|
|
104
|
+
executionMode: 'task',
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The important fields are:
|
|
110
|
+
|
|
111
|
+
- `kind: 'control'`: tells UI and validators this node may own children.
|
|
112
|
+
- `authoring.childSlots`: tells topology which child collections exist.
|
|
113
|
+
- `childSlots[].key`: must match the YAML property used by the runtime.
|
|
114
|
+
- `childSlots[].kind`: use `sequence` for arrays and `case-collection` for
|
|
115
|
+
object-of-arrays.
|
|
116
|
+
- `childSlots[].layout`: use `sequential` or `parallel` unless a new layout mode
|
|
117
|
+
has been fully implemented in the canvas.
|
|
118
|
+
- `authoring.outputs`: describes the control node's output object for
|
|
119
|
+
expression autocomplete and docs.
|
|
120
|
+
|
|
121
|
+
## YAML Shape Contract
|
|
122
|
+
|
|
123
|
+
Prefer existing child keys unless the new control mode truly needs a new shape:
|
|
124
|
+
|
|
125
|
+
- `tasks`: generic ordered or parallel child sequence.
|
|
126
|
+
- `then`: truthy branch.
|
|
127
|
+
- `else`: falsey branch.
|
|
128
|
+
- `defaults`: fallback branch.
|
|
129
|
+
- `cases`: named object-of-arrays for switch-like controls.
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
- id: gate
|
|
135
|
+
kind: control
|
|
136
|
+
type: if
|
|
137
|
+
configuration:
|
|
138
|
+
condition: "{{ inputs.enabled }}"
|
|
139
|
+
then:
|
|
140
|
+
- id: success_log
|
|
141
|
+
kind: task
|
|
142
|
+
type: log.write
|
|
143
|
+
configuration:
|
|
144
|
+
message: Enabled
|
|
145
|
+
else:
|
|
146
|
+
- id: skip_log
|
|
147
|
+
kind: task
|
|
148
|
+
type: log.write
|
|
149
|
+
configuration:
|
|
150
|
+
message: Skipped
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
If a new child key is introduced, update all traversal helpers. At the time of
|
|
154
|
+
writing these include validation, find/update/remove node helpers, topology
|
|
155
|
+
layout, and expression suggestion collection.
|
|
156
|
+
|
|
157
|
+
## Runtime Semantics
|
|
158
|
+
|
|
159
|
+
Control handlers should execute children through `context.runNodes(...)`.
|
|
160
|
+
|
|
161
|
+
Sequential example:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
const outputs = {};
|
|
165
|
+
await context.runNodes(context.node.tasks ?? [], { outputs });
|
|
166
|
+
return { output: { outputs } };
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Parallel example:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const inheritedOutputs = context.outputs ?? {};
|
|
173
|
+
const outputs = { ...inheritedOutputs };
|
|
174
|
+
await context.runNodes([task], { outputs });
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Use inherited outputs when child nodes need to read values produced before the
|
|
178
|
+
control node. Return only the branch-specific outputs when the control node
|
|
179
|
+
should avoid promoting branch outputs globally.
|
|
180
|
+
|
|
181
|
+
Be explicit about these decisions:
|
|
182
|
+
|
|
183
|
+
- Are child outputs promoted into parent `context.outputs`?
|
|
184
|
+
- Are child outputs grouped under the control node output?
|
|
185
|
+
- Can sibling branches read each other's outputs?
|
|
186
|
+
- Can children read outputs produced before the control node?
|
|
187
|
+
- Does a failed child fail the whole workflow or become structured output?
|
|
188
|
+
- Does `onError: continue` behave at the child level, control level, or both?
|
|
189
|
+
|
|
190
|
+
## Output Reference Contract
|
|
191
|
+
|
|
192
|
+
Downstream expression examples must be documented in the provider metadata or
|
|
193
|
+
node docs.
|
|
194
|
+
|
|
195
|
+
For a task node:
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
{{ outputs.login.accessToken }}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
For a parallel node that groups branch outputs:
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
{{ outputs.parallel.tasks.0.outputs.get.data }}
|
|
205
|
+
{{ outputs.parallel.tasks.1.outputs.list.status }}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For a loop-like node, choose and document one stable shape, for example:
|
|
209
|
+
|
|
210
|
+
```yaml
|
|
211
|
+
{{ outputs.loop.items.0.outputs.transform.data }}
|
|
212
|
+
{{ outputs.loop.count }}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Avoid undocumented magic promotion such as making every branch child globally
|
|
216
|
+
available as `outputs.childId` unless collision behavior is also defined.
|
|
217
|
+
|
|
218
|
+
## Topology Canvas Checklist
|
|
219
|
+
|
|
220
|
+
Review `WorkflowFlowCanvas.tsx` whenever child-slot semantics change.
|
|
221
|
+
|
|
222
|
+
Confirm:
|
|
223
|
+
|
|
224
|
+
- The node is detected as a control node through `kind` or `childSlots`.
|
|
225
|
+
- Every child slot renders with the intended layout.
|
|
226
|
+
- Add-node buttons insert into the correct slot and index.
|
|
227
|
+
- Branch labels are readable and stable under nesting.
|
|
228
|
+
- Edges enter the control node, connect to children, and rejoin correctly.
|
|
229
|
+
- Empty slots still render an insertion target.
|
|
230
|
+
- Nested controls do not overlap on desktop or narrow widths.
|
|
231
|
+
- Delete/reorder operations preserve the YAML shape.
|
|
232
|
+
|
|
233
|
+
If adding a new `childSlots[].layout` value beyond `sequential` or `parallel`,
|
|
234
|
+
first update UI metadata types and canvas layout algorithms. Do not ship a new
|
|
235
|
+
layout string that the canvas silently treats as sequential.
|
|
236
|
+
|
|
237
|
+
## Expression Autocomplete Checklist
|
|
238
|
+
|
|
239
|
+
Review `WorkflowDefinitionEditorPage.tsx` expression suggestion logic whenever
|
|
240
|
+
runtime output semantics change.
|
|
241
|
+
|
|
242
|
+
Confirm:
|
|
243
|
+
|
|
244
|
+
- Inputs and variables remain available everywhere.
|
|
245
|
+
- A node can see outputs from definitely earlier nodes.
|
|
246
|
+
- A branch can see parent/prior outputs when runtime permits it.
|
|
247
|
+
- Sibling branch outputs are hidden when branches run concurrently.
|
|
248
|
+
- Downstream nodes see the grouped output shape of the control node.
|
|
249
|
+
- The suggestions match actual runtime output paths.
|
|
250
|
+
|
|
251
|
+
Expression autocomplete is advisory, but wrong suggestions are worse than
|
|
252
|
+
missing suggestions because they produce YAML that validates yet fails at
|
|
253
|
+
runtime.
|
|
254
|
+
|
|
255
|
+
## Validation Checklist
|
|
256
|
+
|
|
257
|
+
Validation should reject malformed control structures early:
|
|
258
|
+
|
|
259
|
+
- `tasks`, `then`, `else`, and `defaults` must be arrays when present.
|
|
260
|
+
- `cases` must be an object whose values are arrays.
|
|
261
|
+
- Required child slots must exist and satisfy `minItems` when enforced.
|
|
262
|
+
- Unsupported child keys should produce a clear message.
|
|
263
|
+
- Node ids must stay unique across nested children.
|
|
264
|
+
- Node `kind` must match registered provider metadata.
|
|
265
|
+
- Required configuration fields must still be validated inside control nodes.
|
|
266
|
+
|
|
267
|
+
## Execution History Checklist
|
|
268
|
+
|
|
269
|
+
Confirm execution detail screens make sense after a run:
|
|
270
|
+
|
|
271
|
+
- Parent control step has a useful output payload.
|
|
272
|
+
- Child steps have `parentNodeId` and `parentStepExecutionKey`.
|
|
273
|
+
- Logs emitted inside children appear under the correct step.
|
|
274
|
+
- Timeline order is understandable for parallel/concurrent branches.
|
|
275
|
+
- Failed child behavior is visible in step status and parent output.
|
|
276
|
+
|
|
277
|
+
## Metadata And Samples
|
|
278
|
+
|
|
279
|
+
When the new control mode is public, add or update sample YAML in the module
|
|
280
|
+
metadata that owns workflow samples. Include:
|
|
281
|
+
|
|
282
|
+
- Minimal happy-path sample.
|
|
283
|
+
- Nested control sample if nesting is expected.
|
|
284
|
+
- Example showing how a downstream node reads the control output.
|
|
285
|
+
- Example showing error behavior if the control has custom failure semantics.
|
|
286
|
+
|
|
287
|
+
If workflow definitions are stored through metadata sync, verify the generated
|
|
288
|
+
YAML and metadata JSON preserve the new child structure without normalization
|
|
289
|
+
loss.
|
|
290
|
+
|
|
291
|
+
## Testing Checklist
|
|
292
|
+
|
|
293
|
+
Run at least:
|
|
294
|
+
|
|
295
|
+
- Backend build: `npm run build` in `solid-core-module`.
|
|
296
|
+
- Frontend build: `npm run build` in `solid-core-ui`.
|
|
297
|
+
- Consuming app build when testing through an app package copy.
|
|
298
|
+
|
|
299
|
+
Manual workflow tests:
|
|
300
|
+
|
|
301
|
+
- Create a workflow with the new control node from topology.
|
|
302
|
+
- Add, edit, delete, and reorder child nodes.
|
|
303
|
+
- Save, reload, and verify YAML is unchanged except expected formatting.
|
|
304
|
+
- Execute happy path.
|
|
305
|
+
- Execute failure path.
|
|
306
|
+
- Inspect execution detail, logs, step output, and final output.
|
|
307
|
+
- Use `Ctrl+Space` in a downstream expression field and verify suggestions
|
|
308
|
+
match real output paths.
|
|
309
|
+
|
|
310
|
+
## Minimal Regression Review
|
|
311
|
+
|
|
312
|
+
Before merging, compare behavior against existing controls:
|
|
313
|
+
|
|
314
|
+
- `parallel`
|
|
315
|
+
- `sequential`
|
|
316
|
+
- `if`
|
|
317
|
+
- `switch`
|
|
318
|
+
- `forEach`
|
|
319
|
+
|
|
320
|
+
The new node should not require special cases in shared UI/runtime code unless
|
|
321
|
+
its semantics are genuinely different. Prefer expressing behavior through
|
|
322
|
+
provider metadata first, then add narrow code changes only where metadata cannot
|
|
323
|
+
describe the behavior.
|
|
324
|
+
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Data Engineering Pipeline Example Notes
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This document captures a concrete workflow example and the accompanying UI notes derived from the Kestra reference screens. It is intended to serve as a working design reference for the SolidX workflow-definition list view, detail view, and editor experience.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Example Workflow YAML
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
id: data-engineering-pipeline
|
|
13
|
+
namespace: tutorial
|
|
14
|
+
labels:
|
|
15
|
+
name: Data Engineering Pipeline
|
|
16
|
+
|
|
17
|
+
inputs:
|
|
18
|
+
- id: columns_to_keep
|
|
19
|
+
type: ARRAY
|
|
20
|
+
itemType: STRING
|
|
21
|
+
defaults:
|
|
22
|
+
- brand
|
|
23
|
+
- price
|
|
24
|
+
|
|
25
|
+
tasks:
|
|
26
|
+
- id: extract
|
|
27
|
+
type: io.kestra.plugin.core.http.Download
|
|
28
|
+
description: Download the raw products JSON data.
|
|
29
|
+
uri: https://dummyjson.com/products
|
|
30
|
+
|
|
31
|
+
- id: transform
|
|
32
|
+
type: io.kestra.plugin.scripts.python.Script
|
|
33
|
+
description: Filter the product fields and write a cleaned JSON file.
|
|
34
|
+
containerImage: python:3.11-alpine
|
|
35
|
+
inputFiles:
|
|
36
|
+
data.json: "{{ outputs.extract.uri }}"
|
|
37
|
+
outputFiles:
|
|
38
|
+
- "*.json"
|
|
39
|
+
script: |
|
|
40
|
+
import json
|
|
41
|
+
import os
|
|
42
|
+
|
|
43
|
+
with open("data.json", "r") as file:
|
|
44
|
+
data = json.load(file)
|
|
45
|
+
|
|
46
|
+
filtered_data = [
|
|
47
|
+
{column: product.get(column, "N/A") for column in {{ inputs.columns_to_keep }}}
|
|
48
|
+
for product in data["products"]
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
with open("products.json", "w") as file:
|
|
52
|
+
json.dump(filtered_data, file, indent=4)
|
|
53
|
+
|
|
54
|
+
- id: query
|
|
55
|
+
type: io.kestra.plugin.jdbc.duckdb.Queries
|
|
56
|
+
description: Aggregate the cleaned data with DuckDB and store the result.
|
|
57
|
+
inputFiles:
|
|
58
|
+
products.json: "{{ outputs.transform.outputFiles['products.json'] }}"
|
|
59
|
+
sql: |
|
|
60
|
+
INSTALL json;
|
|
61
|
+
LOAD json;
|
|
62
|
+
SELECT brand, round(avg(price), 2) as avg_price
|
|
63
|
+
FROM read_json_auto('{{ workingDir }}/products.json')
|
|
64
|
+
GROUP BY brand
|
|
65
|
+
ORDER BY avg_price DESC;
|
|
66
|
+
fetchType: STORE
|
|
67
|
+
|
|
68
|
+
description: |
|
|
69
|
+
**Use case:** Compact data engineering pipeline that filters product data and aggregates it by brand.
|
|
70
|
+
**Highlights:**
|
|
71
|
+
- Download product JSON from a public API.
|
|
72
|
+
- Run a Python transform that keeps only the requested columns and emits a cleaned file.
|
|
73
|
+
- Query the cleaned data with DuckDB to compute average prices per brand and store the result for download in the UI.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## What This Example Represents
|
|
79
|
+
|
|
80
|
+
This workflow is a good V1 reference because it is:
|
|
81
|
+
|
|
82
|
+
- Simple enough to understand quickly.
|
|
83
|
+
- Sequential, so it maps well to the current implicit-edge model.
|
|
84
|
+
- Realistic, because it uses HTTP download, transformation, and data querying.
|
|
85
|
+
- Rich enough to exercise inputs, outputs, descriptions, code editing, and topology rendering.
|
|
86
|
+
|
|
87
|
+
The visual topology implied by this workflow is:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
Start
|
|
91
|
+
|
|
|
92
|
+
v
|
|
93
|
+
extract
|
|
94
|
+
|
|
|
95
|
+
v
|
|
96
|
+
transform
|
|
97
|
+
|
|
|
98
|
+
v
|
|
99
|
+
query
|
|
100
|
+
|
|
|
101
|
+
v
|
|
102
|
+
End
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Detail Page Notes
|
|
108
|
+
|
|
109
|
+
The reference detail experience suggests a workflow page shaped around tabs, not a single long form.
|
|
110
|
+
|
|
111
|
+
### Tabs Observed
|
|
112
|
+
|
|
113
|
+
- `Overview`
|
|
114
|
+
- `Topology`
|
|
115
|
+
- `Executions`
|
|
116
|
+
- `Edit`
|
|
117
|
+
- `Revisions`
|
|
118
|
+
- `Triggers`
|
|
119
|
+
- `Logs`
|
|
120
|
+
- `Metrics`
|
|
121
|
+
- `Dependencies`
|
|
122
|
+
- `Concurrency`
|
|
123
|
+
- `Audit Logs`
|
|
124
|
+
|
|
125
|
+
### SolidX Interpretation
|
|
126
|
+
|
|
127
|
+
For SolidX workflow-definition UX, the current recommended prioritization is:
|
|
128
|
+
|
|
129
|
+
- Keep: `Overview`
|
|
130
|
+
- Keep: `Topology`
|
|
131
|
+
- Keep: `Executions`
|
|
132
|
+
- Keep: `Edit`
|
|
133
|
+
- Keep: `Triggers`
|
|
134
|
+
- Keep: `Logs`
|
|
135
|
+
- Keep: `Metrics`
|
|
136
|
+
- Ignore for now: `Revisions`
|
|
137
|
+
- Ignore for now: `Concurrency`
|
|
138
|
+
- Ignore for now: `Audit Logs`
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Overview Notes
|
|
143
|
+
|
|
144
|
+
The overview page should change meaningfully once executions exist.
|
|
145
|
+
|
|
146
|
+
### Before Executions
|
|
147
|
+
|
|
148
|
+
The page can show an empty-state hero with a primary call to action:
|
|
149
|
+
|
|
150
|
+
- execute workflow
|
|
151
|
+
- guide the user toward the first run
|
|
152
|
+
|
|
153
|
+
### After Executions
|
|
154
|
+
|
|
155
|
+
The page can evolve into a summary dashboard showing:
|
|
156
|
+
|
|
157
|
+
- success ratio
|
|
158
|
+
- failed ratio
|
|
159
|
+
- in-progress count
|
|
160
|
+
- pending count
|
|
161
|
+
- total executions
|
|
162
|
+
- execution trend / chart
|
|
163
|
+
- description panel
|
|
164
|
+
|
|
165
|
+
This means the overview page should not be treated as static documentation. It should become an operational summary once runtime data exists.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Topology Notes
|
|
170
|
+
|
|
171
|
+
Topology is read-only in the reference detail page.
|
|
172
|
+
|
|
173
|
+
Recommended SolidX interpretation:
|
|
174
|
+
|
|
175
|
+
- `Topology` tab should be a clean read-only visualization.
|
|
176
|
+
- It should render the workflow structure without edit affordances.
|
|
177
|
+
- It can reuse the same layout logic as the editor flow view, but without mutation controls.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Executions Notes
|
|
182
|
+
|
|
183
|
+
The `Executions` tab should present a list of all executions for the workflow.
|
|
184
|
+
|
|
185
|
+
Important characteristics from the reference:
|
|
186
|
+
|
|
187
|
+
- list-based presentation
|
|
188
|
+
- filtering/search support
|
|
189
|
+
- empty state when no executions exist
|
|
190
|
+
|
|
191
|
+
For SolidX:
|
|
192
|
+
|
|
193
|
+
- use existing retrieve APIs
|
|
194
|
+
- support server-side pagination, sorting, and search where possible
|
|
195
|
+
- keep the visuals close to SolidX list/table patterns
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Edit Tab Notes
|
|
200
|
+
|
|
201
|
+
This is the most important area for the current UI work.
|
|
202
|
+
|
|
203
|
+
### Desired Structure
|
|
204
|
+
|
|
205
|
+
- `Edit` is a top-level detail tab.
|
|
206
|
+
- Inside `Edit`, only `Code` and `Flow` should be primary editing surfaces.
|
|
207
|
+
- `Docs` should open in a side panel, not as a main third panel in the base layout.
|
|
208
|
+
|
|
209
|
+
### Editor Layout
|
|
210
|
+
|
|
211
|
+
- left: code editor
|
|
212
|
+
- right: flow editor
|
|
213
|
+
- docs: contextual side panel that opens on demand
|
|
214
|
+
|
|
215
|
+
### Editing Mode
|
|
216
|
+
|
|
217
|
+
- flow uses React Flow
|
|
218
|
+
- modal editing for nodes
|
|
219
|
+
- docs are contextual to the selected node type
|
|
220
|
+
- save remains manual
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Flow Canvas Notes
|
|
225
|
+
|
|
226
|
+
The reference behavior to preserve:
|
|
227
|
+
|
|
228
|
+
- `+` insertion controls between nodes
|
|
229
|
+
- per-node actions:
|
|
230
|
+
- edit
|
|
231
|
+
- delete
|
|
232
|
+
- view docs
|
|
233
|
+
- directional flow should be visible
|
|
234
|
+
- zoom in / zoom out controls should exist
|
|
235
|
+
- users may drag nodes to rearrange the graph visually
|
|
236
|
+
- dragging is for visual arrangement only, not for defining semantic connections via drag-and-drop wiring
|
|
237
|
+
|
|
238
|
+
### Important Modeling Note
|
|
239
|
+
|
|
240
|
+
Workflow structure is still governed by the workflow DSL contract.
|
|
241
|
+
|
|
242
|
+
That means:
|
|
243
|
+
|
|
244
|
+
- node order remains driven by workflow structure
|
|
245
|
+
- edges are implicit from the DSL
|
|
246
|
+
- the canvas is a visual/editor representation of the workflow, not the source of truth for execution semantics
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Triggers Notes
|
|
251
|
+
|
|
252
|
+
Triggers are wanted, but not the first editing priority.
|
|
253
|
+
|
|
254
|
+
Current note:
|
|
255
|
+
|
|
256
|
+
- keep a `Triggers` tab in the long-term detail experience
|
|
257
|
+
- rendering and editing of triggers can come after the core editor is stabilized
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Logs Notes
|
|
262
|
+
|
|
263
|
+
Logs are wanted.
|
|
264
|
+
|
|
265
|
+
Recommended direction:
|
|
266
|
+
|
|
267
|
+
- separate `Logs` tab
|
|
268
|
+
- searchable / filterable runtime log list
|
|
269
|
+
- use workflow or execution context to scope logs
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Metrics Notes
|
|
274
|
+
|
|
275
|
+
Metrics are wanted, but depend on runtime persistence.
|
|
276
|
+
|
|
277
|
+
Important note:
|
|
278
|
+
|
|
279
|
+
- metrics are only meaningful once we persist them into backing tables or another queryable runtime store
|
|
280
|
+
|
|
281
|
+
So for now:
|
|
282
|
+
|
|
283
|
+
- keep `Metrics` in the design vocabulary
|
|
284
|
+
- treat it as a pending feature unless the persistence model is implemented
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Pending Feature Notes
|
|
289
|
+
|
|
290
|
+
The following are intentionally deferred or partially deferred:
|
|
291
|
+
|
|
292
|
+
- metrics persistence and reporting
|
|
293
|
+
- trigger authoring experience
|
|
294
|
+
- richer overview analytics
|
|
295
|
+
- revisions
|
|
296
|
+
- concurrency controls
|
|
297
|
+
- audit-log specific workflow views
|
|
298
|
+
- blueprints for this area as part of a later phase
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Screenshot References
|
|
303
|
+
|
|
304
|
+
These screenshots informed the notes above:
|
|
305
|
+
|
|
306
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.58.43.png`
|
|
307
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.58.48.png`
|
|
308
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.58.53.png`
|
|
309
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.58.59.png`
|
|
310
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.59.07.png`
|
|
311
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.59.16.png`
|
|
312
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.59.22.png`
|
|
313
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 16.59.28.png`
|
|
314
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 17.01.42.png`
|
|
315
|
+
- `/Users/harishpatel/Desktop/Screenshot 2026-07-10 at 17.01.47.png`
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Recommended Next UI Build Order
|
|
320
|
+
|
|
321
|
+
Based on this example, the clean next implementation sequence is:
|
|
322
|
+
|
|
323
|
+
1. Finish the bespoke workflow-definition list view.
|
|
324
|
+
2. Tighten the workflow-definition detail shell with tabs.
|
|
325
|
+
3. Refine the `Edit` tab into:
|
|
326
|
+
- left code editor
|
|
327
|
+
- right React Flow editor
|
|
328
|
+
- contextual docs side panel
|
|
329
|
+
4. Add modal-based node configuration using schema-driven forms.
|
|
330
|
+
5. Add runtime tabs for executions, logs, and later metrics.
|