@solidxai/core 0.1.13-beta.12 → 0.1.13-beta.13
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/.claude/settings.local.json +16 -0
- package/CHANGELOG.md +570 -0
- package/CLAUDE.md +26 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +1 -1
- package/dist/services/chatter-message.service.d.ts +4 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +4 -1
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts +1 -2
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +2 -16
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/draft-publish-helper.service.d.ts +1 -0
- package/dist/services/draft-publish-helper.service.d.ts.map +1 -1
- package/dist/services/draft-publish-helper.service.js +38 -4
- package/dist/services/draft-publish-helper.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +62 -6
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +34 -3
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/theme/theme-registry.d.ts +14 -0
- package/dist/theme/theme-registry.d.ts.map +1 -0
- package/dist/theme/theme-registry.js +147 -0
- package/dist/theme/theme-registry.js.map +1 -0
- package/package.json +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +1 -1
- package/src/services/1.js +6 -0
- package/src/services/chatter-message.service.ts +22 -1
- package/src/services/crud-helper.service.ts +19 -16
- package/src/services/crud.service.ts +2 -1
- package/src/services/draft-publish-helper.service.ts +56 -4
- package/src/services/settings/default-settings-provider.service.ts +34 -3
- package/src/theme/theme-registry.ts +181 -0
- package/dist-tests/api/authenticate.spec.js +0 -119
- package/dist-tests/api/authenticate.spec.js.map +0 -1
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
- package/dist-tests/api/ping.spec.js +0 -21
- package/dist-tests/api/ping.spec.js.map +0 -1
- package/dist-tests/helpers/auth.js +0 -41
- package/dist-tests/helpers/auth.js.map +0 -1
- package/dist-tests/helpers/env.js +0 -11
- package/dist-tests/helpers/env.js.map +0 -1
- package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +0 -136
- package/docs/agent-builder/team-ready-note-agent-builder.md +0 -305
- package/docs/agent-hub-grooming.md +0 -301
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +0 -438
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +0 -146
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +0 -172
- package/docs/datasource-introspection-ddl-analysis.md +0 -326
- package/docs/datasource-introspection-implementation-plan.md +0 -306
- package/docs/grouping-enhancements.md +0 -89
- package/docs/java-spring/README.md +0 -3
- package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
- package/docs/module-package-import-handoff.md +0 -691
- package/docs/seed-changes.md +0 -65
- package/docs/test-data-workflow.md +0 -200
- package/docs/type-declaration-import-issue.md +0 -24
- package/docs/workflow/business-automation-example-notes.md +0 -309
- package/docs/workflow/control-flow-node-addition-sop.md +0 -324
- package/docs/workflow/data-engineering-pipeline-example-notes.md +0 -330
- package/docs/workflow/foreach-example-notes.md +0 -187
- package/docs/workflow/hello-world-example-notes.md +0 -271
- package/docs/workflow/kestra-concepts-plugins-blueprints.md +0 -315
- package/docs/workflow/loop-until-example-notes.md +0 -198
- package/docs/workflow/microservices-and-apis-example-notes.md +0 -264
- package/docs/workflow/samples.md +0 -25
- package/docs/workflow/what-is-kestra.md +0 -79
- package/docs/workflow/workflow-core-module-handoff-summary.md +0 -191
- package/docs/workflow/workflow-module-brd.md +0 -185
- package/docs/workflow/workflow-module-domain-model.md +0 -252
- package/docs/workflow/workflow-module-metadata-dsl.md +0 -302
- package/docs/workflow/workflow-module-technical-spec.md +0 -293
- package/docs/workflow/workflow-node-type-contracts.md +0 -635
- package/docs/workflow/workflow-node-ui-metadata-contract.md +0 -1262
- package/docs/workflow/workflow-solidx-model-field-spec.md +0 -284
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
# Kestra Concepts, Plugins, and Blueprints
|
|
2
|
-
|
|
3
|
-
This note summarizes the Kestra Academy pages from the `Concepts` section plus the `Plugins` and `Blueprints` lessons. The goal is to translate Kestra's mental model into design inputs for a reusable SolidX workflow engine and builder module.
|
|
4
|
-
|
|
5
|
-
## Flows
|
|
6
|
-
|
|
7
|
-
A flow is the top-level workflow container. It defines:
|
|
8
|
-
|
|
9
|
-
- a unique `id`
|
|
10
|
-
- a `namespace`
|
|
11
|
-
- the `tasks` that perform the work
|
|
12
|
-
|
|
13
|
-
Kestra treats the flow as the unit of orchestration. The flow holds both the tasks and the orchestration logic that determines how those tasks relate. Flows can be authored in YAML, through a no-code editor, or with AI assistance.
|
|
14
|
-
|
|
15
|
-
Important behavior:
|
|
16
|
-
|
|
17
|
-
- Every flow belongs to a namespace
|
|
18
|
-
- Namespaces act like hierarchical folders
|
|
19
|
-
- Flow `id` and `namespace` become permanent after save
|
|
20
|
-
|
|
21
|
-
### Design implication for us
|
|
22
|
-
|
|
23
|
-
We will need a first-class workflow definition aggregate with stable identity, logical grouping, versioning, and a representation that can support both code-based and visual editing.
|
|
24
|
-
|
|
25
|
-
## Tasks
|
|
26
|
-
|
|
27
|
-
Tasks are the individual executable steps in a flow. They perform discrete actions such as:
|
|
28
|
-
|
|
29
|
-
- calling an API
|
|
30
|
-
- running code
|
|
31
|
-
- querying a database
|
|
32
|
-
- sending a notification
|
|
33
|
-
|
|
34
|
-
Kestra highlights two broad task categories:
|
|
35
|
-
|
|
36
|
-
- Runnable tasks: do actual work
|
|
37
|
-
- Flowable tasks: control orchestration behavior
|
|
38
|
-
|
|
39
|
-
Every task has at least:
|
|
40
|
-
|
|
41
|
-
- `id`
|
|
42
|
-
- `type`
|
|
43
|
-
|
|
44
|
-
Task-specific properties then vary by plugin/task type.
|
|
45
|
-
|
|
46
|
-
### Design implication for us
|
|
47
|
-
|
|
48
|
-
Our model should distinguish between:
|
|
49
|
-
|
|
50
|
-
- step identity
|
|
51
|
-
- step type
|
|
52
|
-
- step configuration
|
|
53
|
-
- executable work steps versus control-flow steps
|
|
54
|
-
|
|
55
|
-
This is likely the start of a polymorphic node model in our domain.
|
|
56
|
-
|
|
57
|
-
## Inputs
|
|
58
|
-
|
|
59
|
-
Inputs parameterize a flow so it can be executed with different values without changing the definition. Kestra inputs have:
|
|
60
|
-
|
|
61
|
-
- `id`
|
|
62
|
-
- `type`
|
|
63
|
-
|
|
64
|
-
Common optional properties include:
|
|
65
|
-
|
|
66
|
-
- `defaults`
|
|
67
|
-
- `displayName`
|
|
68
|
-
- `required`
|
|
69
|
-
- `description`
|
|
70
|
-
|
|
71
|
-
Kestra supports multiple input types such as string, integer, select, JSON, file, and URI. Inputs are referenced via expressions like `{{ inputs.name }}`.
|
|
72
|
-
|
|
73
|
-
### Design implication for us
|
|
74
|
-
|
|
75
|
-
We need a typed workflow input model with validation, defaults, UI metadata, and runtime binding support. Inputs should be usable both at manual execution time and by automated triggers.
|
|
76
|
-
|
|
77
|
-
## Outputs
|
|
78
|
-
|
|
79
|
-
Outputs are runtime results produced by tasks. They are stored in the execution context and made available to downstream tasks. Outputs can be:
|
|
80
|
-
|
|
81
|
-
- simple values
|
|
82
|
-
- structured data
|
|
83
|
-
- files
|
|
84
|
-
|
|
85
|
-
They are referenced using expressions like `{{ outputs.task_id.output_value }}`.
|
|
86
|
-
|
|
87
|
-
Kestra also introduces the idea that an entire flow can expose outputs, not just tasks.
|
|
88
|
-
|
|
89
|
-
### Design implication for us
|
|
90
|
-
|
|
91
|
-
We need an execution context model that can store and resolve:
|
|
92
|
-
|
|
93
|
-
- per-step outputs
|
|
94
|
-
- flow-level outputs
|
|
95
|
-
- file or artifact references
|
|
96
|
-
|
|
97
|
-
This becomes a core part of runtime execution and expression resolution.
|
|
98
|
-
|
|
99
|
-
## Triggers
|
|
100
|
-
|
|
101
|
-
Triggers automate flow execution. Kestra describes them as the "when" of a workflow. Examples include:
|
|
102
|
-
|
|
103
|
-
- schedules
|
|
104
|
-
- polling
|
|
105
|
-
- realtime events
|
|
106
|
-
- webhooks
|
|
107
|
-
- flow completion triggers
|
|
108
|
-
|
|
109
|
-
Triggers have their own `id`, `type`, and type-specific configuration. They can also pass input values into a flow when they fire. A single flow can have multiple triggers.
|
|
110
|
-
|
|
111
|
-
### Design implication for us
|
|
112
|
-
|
|
113
|
-
We need a first-class trigger model that supports:
|
|
114
|
-
|
|
115
|
-
- multiple trigger instances per workflow
|
|
116
|
-
- trigger-specific configuration
|
|
117
|
-
- input injection
|
|
118
|
-
- manual and automated execution paths
|
|
119
|
-
|
|
120
|
-
This likely means triggers should be separate domain entities attached to a workflow definition rather than being embedded as anonymous config blobs only.
|
|
121
|
-
|
|
122
|
-
## Expressions
|
|
123
|
-
|
|
124
|
-
Expressions are the dynamic binding and transformation layer. Kestra uses `{{ }}` syntax and allows access to runtime context such as:
|
|
125
|
-
|
|
126
|
-
- `inputs`
|
|
127
|
-
- `outputs`
|
|
128
|
-
- `flow`
|
|
129
|
-
- `execution`
|
|
130
|
-
- `trigger`
|
|
131
|
-
|
|
132
|
-
Expressions can do more than variable lookup. They can:
|
|
133
|
-
|
|
134
|
-
- transform values
|
|
135
|
-
- parse JSON
|
|
136
|
-
- format dates
|
|
137
|
-
- perform calculations
|
|
138
|
-
|
|
139
|
-
### Design implication for us
|
|
140
|
-
|
|
141
|
-
We need to make an early architectural decision about the expression system:
|
|
142
|
-
|
|
143
|
-
- whether to design our own expression format
|
|
144
|
-
- whether to embed an existing engine
|
|
145
|
-
- what execution context objects are exposed
|
|
146
|
-
- how expressions are validated at design time versus resolved at runtime
|
|
147
|
-
|
|
148
|
-
This is a foundational concern because it affects inputs, outputs, conditions, triggers, and task configuration.
|
|
149
|
-
|
|
150
|
-
## Flowable Tasks
|
|
151
|
-
|
|
152
|
-
Flowable tasks control orchestration instead of doing business work directly. Kestra highlights patterns such as:
|
|
153
|
-
|
|
154
|
-
- conditional branching with `If` and `Switch`
|
|
155
|
-
- iteration with `ForEach`, `ForEachItem`, and `LoopUntil`
|
|
156
|
-
- parallel execution
|
|
157
|
-
- subflows for reuse
|
|
158
|
-
|
|
159
|
-
These tasks combine orchestration rules with expressions.
|
|
160
|
-
|
|
161
|
-
### Design implication for us
|
|
162
|
-
|
|
163
|
-
Our workflow graph cannot be modeled as only a flat list of steps. We will need support for:
|
|
164
|
-
|
|
165
|
-
- branching
|
|
166
|
-
- nesting
|
|
167
|
-
- loops
|
|
168
|
-
- fan-out / parallelism
|
|
169
|
-
- reusable subflow invocation
|
|
170
|
-
|
|
171
|
-
This pushes us toward a graph or tree-plus-edges model rather than a simple sequential pipeline model.
|
|
172
|
-
|
|
173
|
-
## Execution
|
|
174
|
-
|
|
175
|
-
An execution is a single run of a flow. Each execution contains task runs, and each task run has its own runtime behavior, outputs, logs, and status.
|
|
176
|
-
|
|
177
|
-
Kestra emphasizes:
|
|
178
|
-
|
|
179
|
-
- execution states such as created, running, success, failed
|
|
180
|
-
- observability through logs, metrics, outputs, topology, and timing views
|
|
181
|
-
- replaying failed task runs or entire executions
|
|
182
|
-
- revisions of flow definitions
|
|
183
|
-
|
|
184
|
-
### Design implication for us
|
|
185
|
-
|
|
186
|
-
We should model workflow definition and workflow execution separately. At minimum, our domain will likely need:
|
|
187
|
-
|
|
188
|
-
- workflow definitions
|
|
189
|
-
- workflow revisions
|
|
190
|
-
- workflow executions
|
|
191
|
-
- step executions
|
|
192
|
-
- execution state transitions
|
|
193
|
-
- logs / metrics / artifacts
|
|
194
|
-
- replay or rerun semantics
|
|
195
|
-
|
|
196
|
-
## Secrets
|
|
197
|
-
|
|
198
|
-
Secrets are sensitive values stored outside workflow definitions and referenced at runtime. Kestra exposes them through expressions via a `secret()` function and avoids leaking them into code, logs, and outputs.
|
|
199
|
-
|
|
200
|
-
### Design implication for us
|
|
201
|
-
|
|
202
|
-
We need a secret reference strategy, not just plain text fields. The module should support:
|
|
203
|
-
|
|
204
|
-
- secure secret references in workflow definitions
|
|
205
|
-
- runtime secret resolution
|
|
206
|
-
- masking in logs and UI
|
|
207
|
-
- separation between design-time config and sensitive runtime values
|
|
208
|
-
|
|
209
|
-
## Plugins
|
|
210
|
-
|
|
211
|
-
Plugins are the extension mechanism that powers tasks and triggers. In Kestra's framing, plugins are the integration and capability layer that connects workflows to:
|
|
212
|
-
|
|
213
|
-
- programming runtimes
|
|
214
|
-
- databases
|
|
215
|
-
- APIs
|
|
216
|
-
- cloud systems
|
|
217
|
-
- notification channels
|
|
218
|
-
|
|
219
|
-
Even "core" capabilities are still exposed as plugin-backed task or trigger types.
|
|
220
|
-
|
|
221
|
-
### Design implication for us
|
|
222
|
-
|
|
223
|
-
This is especially important for our module. We should not hard-code every possible step type into the core engine. We likely need:
|
|
224
|
-
|
|
225
|
-
- a reusable action/task type registry
|
|
226
|
-
- typed configuration schemas per task type
|
|
227
|
-
- trigger type registry
|
|
228
|
-
- optional packaging/distribution story for reusable step providers
|
|
229
|
-
|
|
230
|
-
In SolidX terms, this may become one of the primary extensibility points of the module.
|
|
231
|
-
|
|
232
|
-
## Blueprints
|
|
233
|
-
|
|
234
|
-
Blueprints are curated, ready-to-use example workflows. Kestra presents them as:
|
|
235
|
-
|
|
236
|
-
- working code
|
|
237
|
-
- documentation
|
|
238
|
-
- tags for discovery
|
|
239
|
-
|
|
240
|
-
They are meant to accelerate adoption by giving users validated examples that can be copied and adapted.
|
|
241
|
-
|
|
242
|
-
### Design implication for us
|
|
243
|
-
|
|
244
|
-
A reusable workflow builder module will benefit from a blueprint/template system from the start or at least early in the roadmap. Blueprints can help with:
|
|
245
|
-
|
|
246
|
-
- onboarding
|
|
247
|
-
- discoverability
|
|
248
|
-
- best-practice reuse
|
|
249
|
-
- sample implementations of step types and orchestration patterns
|
|
250
|
-
|
|
251
|
-
## Cross-Cutting Observations
|
|
252
|
-
|
|
253
|
-
Kestra's model repeatedly separates concerns in a very clean way:
|
|
254
|
-
|
|
255
|
-
- Definition versus execution
|
|
256
|
-
- Work steps versus control-flow steps
|
|
257
|
-
- Static configuration versus runtime context
|
|
258
|
-
- Secure references versus plain values
|
|
259
|
-
- Core engine versus plugin-provided capabilities
|
|
260
|
-
|
|
261
|
-
That separation is probably the biggest lesson for our design.
|
|
262
|
-
|
|
263
|
-
## Likely Domain Areas For Our SolidX Module
|
|
264
|
-
|
|
265
|
-
Based on these lessons, our reusable module will probably need domain models for at least:
|
|
266
|
-
|
|
267
|
-
- Workflow definition
|
|
268
|
-
- Workflow revision
|
|
269
|
-
- Workflow namespace or foldering concept
|
|
270
|
-
- Workflow input
|
|
271
|
-
- Workflow output
|
|
272
|
-
- Trigger
|
|
273
|
-
- Step / task
|
|
274
|
-
- Step type registry
|
|
275
|
-
- Step execution
|
|
276
|
-
- Workflow execution
|
|
277
|
-
- Execution logs and artifacts
|
|
278
|
-
- Secret reference
|
|
279
|
-
- Blueprint / template
|
|
280
|
-
|
|
281
|
-
## Metadata / DSL Implication
|
|
282
|
-
|
|
283
|
-
Kestra uses YAML as a human-readable workflow definition format. For our SolidX module, we should expect to define an equivalent metadata representation for workflows that can support:
|
|
284
|
-
|
|
285
|
-
- stable workflow identity
|
|
286
|
-
- typed nodes
|
|
287
|
-
- nested control-flow structures
|
|
288
|
-
- trigger definitions
|
|
289
|
-
- expressions
|
|
290
|
-
- reusable references
|
|
291
|
-
- versioning
|
|
292
|
-
|
|
293
|
-
That representation will need to work for both:
|
|
294
|
-
|
|
295
|
-
- a visual workflow builder
|
|
296
|
-
- a code or JSON/YAML style export/import story
|
|
297
|
-
|
|
298
|
-
## Sources
|
|
299
|
-
|
|
300
|
-
- [Flows](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404093-flows)
|
|
301
|
-
- [Tasks](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404094-tasks)
|
|
302
|
-
- [Inputs](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404096-inputs)
|
|
303
|
-
- [Outputs](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404097-outputs)
|
|
304
|
-
- [Triggers](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404103-triggers)
|
|
305
|
-
- [Expressions](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404099-expressions)
|
|
306
|
-
- [Flowable Tasks](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404106-flowable-tasks)
|
|
307
|
-
- [Execution](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404107-execution)
|
|
308
|
-
- [Secrets](https://academy.kestra.io/p/courses/kestra-fundamentals/3492614-concepts/11404115-secrets)
|
|
309
|
-
- [Plugins](https://academy.kestra.io/p/courses/kestra-fundamentals/3492618-plugins-blueprints/11437898-plugins)
|
|
310
|
-
- [Blueprints](https://academy.kestra.io/p/courses/kestra-fundamentals/3492618-plugins-blueprints/11437900-blueprints)
|
|
311
|
-
|
|
312
|
-
## Notes
|
|
313
|
-
|
|
314
|
-
- The extracted lesson text was pulled from the Academy pages directly.
|
|
315
|
-
- Some lessons included image-heavy examples, so the summary focuses on the textual teaching content plus explicit design implications for our module.
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# LoopUntil Example Notes
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
This document captures a reference workflow for `LoopUntil`. It complements the `ForEach` example by showing a different kind of loop: repeat-until-success rather than iterate-over-values.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Example Workflow YAML
|
|
10
|
-
|
|
11
|
-
```yaml
|
|
12
|
-
id: loop_until_health_check
|
|
13
|
-
namespace: company.team
|
|
14
|
-
|
|
15
|
-
tasks:
|
|
16
|
-
- id: loop
|
|
17
|
-
type: io.kestra.plugin.core.flow.LoopUntil
|
|
18
|
-
condition: "{{ outputs.healthCheck.code == 200 }}"
|
|
19
|
-
checkFrequency:
|
|
20
|
-
interval: PT30S
|
|
21
|
-
maxIterations: 50
|
|
22
|
-
tasks:
|
|
23
|
-
- id: healthCheck
|
|
24
|
-
type: io.kestra.plugin.core.http.Request
|
|
25
|
-
method: GET
|
|
26
|
-
uri: https://kestra.io/
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## What This Example Adds
|
|
32
|
-
|
|
33
|
-
This example is useful because it shows:
|
|
34
|
-
|
|
35
|
-
- condition-based looping
|
|
36
|
-
- repeated polling / health-check behavior
|
|
37
|
-
- loop frequency metadata
|
|
38
|
-
- max-iteration safeguards
|
|
39
|
-
- a loop container with a small loop body
|
|
40
|
-
|
|
41
|
-
It is the clearest reference for workflows that keep trying until a condition becomes true.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## High-Level Structure
|
|
46
|
-
|
|
47
|
-
```text
|
|
48
|
-
Start
|
|
49
|
-
|
|
|
50
|
-
v
|
|
51
|
-
loop
|
|
52
|
-
|
|
|
53
|
-
v
|
|
54
|
-
healthCheck
|
|
55
|
-
|
|
|
56
|
-
v
|
|
57
|
-
repeat until outputs.healthCheck.code == 200
|
|
58
|
-
|
|
|
59
|
-
v
|
|
60
|
-
End
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Conceptually:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
Workflow
|
|
67
|
-
└── loop
|
|
68
|
-
└── healthCheck
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Runtime interpretation:
|
|
72
|
-
|
|
73
|
-
```text
|
|
74
|
-
Repeat:
|
|
75
|
-
run healthCheck
|
|
76
|
-
Until:
|
|
77
|
-
outputs.healthCheck.code == 200
|
|
78
|
-
|
|
79
|
-
With:
|
|
80
|
-
interval = PT30S
|
|
81
|
-
maxIterations = 50
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Main Note
|
|
87
|
-
|
|
88
|
-
### Example With `LoopUntil`
|
|
89
|
-
|
|
90
|
-
This is the key purpose of the example.
|
|
91
|
-
|
|
92
|
-
It shows that not all loops are collection-based like `ForEach`.
|
|
93
|
-
|
|
94
|
-
`LoopUntil` is driven by:
|
|
95
|
-
|
|
96
|
-
- a stop condition
|
|
97
|
-
- a repeated body
|
|
98
|
-
- retry/check timing configuration
|
|
99
|
-
- a max-iteration limit
|
|
100
|
-
|
|
101
|
-
So the UI must distinguish between:
|
|
102
|
-
|
|
103
|
-
- looping over values
|
|
104
|
-
- looping until a condition is met
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Topology Notes
|
|
109
|
-
|
|
110
|
-
The screenshot suggests:
|
|
111
|
-
|
|
112
|
-
- `LoopUntil` is rendered as a grouped/container region
|
|
113
|
-
- the loop node appears at the top of that region
|
|
114
|
-
- the loop body task appears within the same grouped area
|
|
115
|
-
- the visual sequence remains vertical and directional
|
|
116
|
-
|
|
117
|
-
This is similar to `ForEach` structurally, but the semantics are different enough that the node metadata and docs must explain the difference clearly.
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Loop Semantics Notes
|
|
122
|
-
|
|
123
|
-
This example introduces loop control metadata that is especially important for docs and forms:
|
|
124
|
-
|
|
125
|
-
- `condition`
|
|
126
|
-
- `checkFrequency.interval`
|
|
127
|
-
- `checkFrequency.maxIterations`
|
|
128
|
-
|
|
129
|
-
That means the schema-driven editor should eventually support:
|
|
130
|
-
|
|
131
|
-
- expression-aware editing for the stop condition
|
|
132
|
-
- structured editing for timing/frequency settings
|
|
133
|
-
- clear validation for required loop settings
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Implications For SolidX Flow Modeling
|
|
138
|
-
|
|
139
|
-
This example implies the loop category should likely have meaningful subtypes:
|
|
140
|
-
|
|
141
|
-
- `ForEach`
|
|
142
|
-
- `LoopUntil`
|
|
143
|
-
|
|
144
|
-
Both may be rendered as loop containers, but their configuration UX differs:
|
|
145
|
-
|
|
146
|
-
- `ForEach` needs collection/value configuration
|
|
147
|
-
- `LoopUntil` needs condition and frequency configuration
|
|
148
|
-
|
|
149
|
-
So the generic metadata contract should preserve enough node-specific structure to power a richer modal form.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Editor Notes
|
|
154
|
-
|
|
155
|
-
This example fits the current editor direction well:
|
|
156
|
-
|
|
157
|
-
- code remains the source of truth
|
|
158
|
-
- flow visualizes the loop container and body
|
|
159
|
-
- node editing should be modal and schema-driven
|
|
160
|
-
- docs should explain loop semantics and available configuration
|
|
161
|
-
|
|
162
|
-
This is also a good candidate for future validation because it contains:
|
|
163
|
-
|
|
164
|
-
- expressions
|
|
165
|
-
- loop structure
|
|
166
|
-
- nested tasks
|
|
167
|
-
- timing configuration
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Future UX Notes
|
|
172
|
-
|
|
173
|
-
This example points to a few future needs:
|
|
174
|
-
|
|
175
|
-
- loop-type specific modal forms
|
|
176
|
-
- duration / interval input UX
|
|
177
|
-
- expression assistance for loop conditions
|
|
178
|
-
- better visualization of “repeat until” semantics in the docs panel
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## Screenshot References
|
|
183
|
-
|
|
184
|
-
This screenshot informed the notes above:
|
|
185
|
-
|
|
186
|
-
- `/var/folders/z_/h0rqj1693gs4cxm3k_vks86c0000gn/T/TemporaryItems/NSIRD_screencaptureui_hm7Us9/Screenshot 2026-07-10 at 17.18.11.png`
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## Recommended Follow-On Use
|
|
191
|
-
|
|
192
|
-
This example should be used as a reference for:
|
|
193
|
-
|
|
194
|
-
1. `LoopUntil` node rendering
|
|
195
|
-
2. condition-based loop semantics
|
|
196
|
-
3. interval / max-iteration configuration UX
|
|
197
|
-
4. differentiating loop subtypes in docs and forms
|
|
198
|
-
5. future expression-aware validation for looping constructs
|