@eventmodelers/cli 0.0.1

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 (220) hide show
  1. package/README.md +175 -0
  2. package/cli.js +676 -0
  3. package/package.json +35 -0
  4. package/shared/build-kit/code-export.mjs +560 -0
  5. package/shared/build-kit/lib/ollama-agent.js +147 -0
  6. package/shared/build-kit/package.json +11 -0
  7. package/shared/build-kit/ralph-ollama.js +39 -0
  8. package/shared/build-kit/realtime-agent.js +18 -0
  9. package/stacks/axon/templates/.claude/skills/build-automation/SKILL.md +407 -0
  10. package/stacks/axon/templates/.claude/skills/build-automation/references/feature-flag-patterns.md +114 -0
  11. package/stacks/axon/templates/.claude/skills/build-automation-workflow/SKILL.md +496 -0
  12. package/stacks/axon/templates/.claude/skills/build-automation-workflow/references/axon-workflow-api.md +279 -0
  13. package/stacks/axon/templates/.claude/skills/build-automation-workflow/references/feature-flag-patterns.md +114 -0
  14. package/stacks/axon/templates/.claude/skills/build-state-change/SKILL.md +396 -0
  15. package/stacks/axon/templates/.claude/skills/build-state-change/references/axon-test-fixture-patterns.md +162 -0
  16. package/stacks/axon/templates/.claude/skills/build-state-change/references/feature-flag-patterns.md +56 -0
  17. package/stacks/axon/templates/.claude/skills/build-state-change/references/rest-api-patterns.md +115 -0
  18. package/stacks/axon/templates/.claude/skills/build-state-view/SKILL.md +282 -0
  19. package/stacks/axon/templates/.claude/skills/connect/SKILL.md +178 -0
  20. package/stacks/axon/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +611 -0
  21. package/stacks/axon/templates/.claude/skills/load-slice/SKILL.md +141 -0
  22. package/stacks/axon/templates/.claude/skills/update-slice-status/SKILL.md +105 -0
  23. package/stacks/axon/templates/build-kit/lib/AGENT.md +47 -0
  24. package/stacks/axon/templates/build-kit/lib/agent.sh +20 -0
  25. package/stacks/axon/templates/build-kit/lib/backend-prompt.md +158 -0
  26. package/stacks/axon/templates/build-kit/lib/prompt.md +126 -0
  27. package/stacks/axon/templates/build-kit/lib/ralph.js +369 -0
  28. package/stacks/axon/templates/build-kit/ralph-claude.js +44 -0
  29. package/stacks/axon/templates/build-kit/ralph.sh +98 -0
  30. package/stacks/axon/templates/root/.env.example +5 -0
  31. package/stacks/axon/templates/root/CLAUDE.md +60 -0
  32. package/stacks/axon/templates/root/README.md +44 -0
  33. package/stacks/axon/templates/root/docker-compose.yml +64 -0
  34. package/stacks/axon/templates/root/mvnw +259 -0
  35. package/stacks/axon/templates/root/mvnw.cmd +149 -0
  36. package/stacks/axon/templates/root/pom.xml +125 -0
  37. package/stacks/axon/templates/root/src/main/java/io/axoniq/quickstart/QuickstartApplication.java +128 -0
  38. package/stacks/axon/templates/root/src/main/java/io/axoniq/quickstart/config/WebConfig.java +155 -0
  39. package/stacks/axon/templates/root/src/main/resources/application.properties +2 -0
  40. package/stacks/axon/templates/root/src/main/resources/static/bg-body.png +0 -0
  41. package/stacks/axon/templates/root/src/main/resources/static/bg-header.png +0 -0
  42. package/stacks/axon/templates/root/src/main/resources/static/index.html +596 -0
  43. package/stacks/cratis-csharp/templates/.claude/skills/_shared/cratis-conventions.md +251 -0
  44. package/stacks/cratis-csharp/templates/.claude/skills/build-automation/SKILL.md +99 -0
  45. package/stacks/cratis-csharp/templates/.claude/skills/build-automation/references/patterns.md +115 -0
  46. package/stacks/cratis-csharp/templates/.claude/skills/build-state-change/SKILL.md +163 -0
  47. package/stacks/cratis-csharp/templates/.claude/skills/build-state-change/references/patterns.md +234 -0
  48. package/stacks/cratis-csharp/templates/.claude/skills/build-state-view/SKILL.md +120 -0
  49. package/stacks/cratis-csharp/templates/.claude/skills/build-state-view/references/patterns.md +166 -0
  50. package/stacks/cratis-csharp/templates/.claude/skills/connect/SKILL.md +169 -0
  51. package/stacks/cratis-csharp/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +609 -0
  52. package/stacks/cratis-csharp/templates/.claude/skills/load-slice/SKILL.md +141 -0
  53. package/stacks/cratis-csharp/templates/.claude/skills/update-slice-status/SKILL.md +105 -0
  54. package/stacks/cratis-csharp/templates/build-kit/lib/AGENT.md +58 -0
  55. package/stacks/cratis-csharp/templates/build-kit/lib/agent.sh +20 -0
  56. package/stacks/cratis-csharp/templates/build-kit/lib/backend-prompt.md +129 -0
  57. package/stacks/cratis-csharp/templates/build-kit/lib/prompt.md +124 -0
  58. package/stacks/cratis-csharp/templates/build-kit/lib/ralph.js +302 -0
  59. package/stacks/cratis-csharp/templates/build-kit/ralph-claude.js +37 -0
  60. package/stacks/cratis-csharp/templates/build-kit/ralph.sh +98 -0
  61. package/stacks/cratis-csharp/templates/root/.frontend/index.css +29 -0
  62. package/stacks/cratis-csharp/templates/root/.frontend/index.html +17 -0
  63. package/stacks/cratis-csharp/templates/root/.frontend/main.tsx +18 -0
  64. package/stacks/cratis-csharp/templates/root/.frontend/tsconfig.json +42 -0
  65. package/stacks/cratis-csharp/templates/root/.frontend/tsconfig.node.json +11 -0
  66. package/stacks/cratis-csharp/templates/root/.frontend/vite.config.ts +56 -0
  67. package/stacks/cratis-csharp/templates/root/App.tsx +23 -0
  68. package/stacks/cratis-csharp/templates/root/CLAUDE.md +62 -0
  69. package/stacks/cratis-csharp/templates/root/CratisApp.csproj +25 -0
  70. package/stacks/cratis-csharp/templates/root/CratisApp.sln +18 -0
  71. package/stacks/cratis-csharp/templates/root/GlobalUsings.cs +3 -0
  72. package/stacks/cratis-csharp/templates/root/Home.tsx +102 -0
  73. package/stacks/cratis-csharp/templates/root/Program.cs +26 -0
  74. package/stacks/cratis-csharp/templates/root/README.md +192 -0
  75. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/AllListings.ts +47 -0
  76. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/Listing.cs +11 -0
  77. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/Listing.ts +12 -0
  78. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/ListingDataTable.tsx +17 -0
  79. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/index.ts +1 -0
  80. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/Register.ts +51 -0
  81. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/RegisterDialog.tsx +18 -0
  82. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/Registration.cs +27 -0
  83. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/index.ts +1 -0
  84. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/SomeFeature.tsx +22 -0
  85. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/SomeName.cs +3 -0
  86. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/index.ts +1 -0
  87. package/stacks/cratis-csharp/templates/root/appsettings.Development.json +9 -0
  88. package/stacks/cratis-csharp/templates/root/appsettings.json +26 -0
  89. package/stacks/cratis-csharp/templates/root/docker-compose.yml +23 -0
  90. package/stacks/cratis-csharp/templates/root/package.json +33 -0
  91. package/stacks/cratis-csharp/templates/root/tsconfig.json +3 -0
  92. package/stacks/modeling-kit/templates/.claude/settings.local.json +13 -0
  93. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +215 -0
  94. package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +176 -0
  95. package/stacks/modeling-kit/templates/.claude/skills/connect/SKILL.md +182 -0
  96. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +383 -0
  97. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +465 -0
  98. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +587 -0
  99. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/facilitating-event-modeling-workshops.md +626 -0
  100. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +542 -0
  101. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +497 -0
  102. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +783 -0
  103. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +604 -0
  104. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +699 -0
  105. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +674 -0
  106. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +231 -0
  107. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +150 -0
  108. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +329 -0
  109. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +204 -0
  110. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +352 -0
  111. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/project-planning-with-event-modeling.md +341 -0
  112. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +153 -0
  113. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +136 -0
  114. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +78 -0
  115. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +85 -0
  116. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +655 -0
  117. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +479 -0
  118. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +234 -0
  119. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +353 -0
  120. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +200 -0
  121. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +94 -0
  122. package/stacks/modeling-kit/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +441 -0
  123. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +290 -0
  124. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +212 -0
  125. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +123 -0
  126. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +353 -0
  127. package/stacks/modeling-kit/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  128. package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +134 -0
  129. package/stacks/modeling-kit/templates/kit/lib/agent.sh +20 -0
  130. package/stacks/modeling-kit/templates/kit/lib/ollama-agent.js +147 -0
  131. package/stacks/modeling-kit/templates/kit/lib/ralph.js +286 -0
  132. package/stacks/modeling-kit/templates/kit/package.json +12 -0
  133. package/stacks/modeling-kit/templates/kit/ralph-claude.js +50 -0
  134. package/stacks/modeling-kit/templates/kit/ralph-ollama.js +38 -0
  135. package/stacks/modeling-kit/templates/kit/ralph.sh +61 -0
  136. package/stacks/modeling-kit/templates/kit/realtime-agent.js +18 -0
  137. package/stacks/modeling-kit/templates/root/CLAUDE.md +56 -0
  138. package/stacks/node/templates/.claude/skills/build-automation/SKILL.md +266 -0
  139. package/stacks/node/templates/.claude/skills/build-state-change/SKILL.md +344 -0
  140. package/stacks/node/templates/.claude/skills/build-state-view/SKILL.md +412 -0
  141. package/stacks/node/templates/.claude/skills/connect/SKILL.md +178 -0
  142. package/stacks/node/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +628 -0
  143. package/stacks/node/templates/.claude/skills/load-slice/SKILL.md +143 -0
  144. package/stacks/node/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  145. package/stacks/node/templates/build-kit/README.md +86 -0
  146. package/stacks/node/templates/build-kit/lib/AGENT.md +47 -0
  147. package/stacks/node/templates/build-kit/lib/agent.sh +20 -0
  148. package/stacks/node/templates/build-kit/lib/backend-prompt.md +152 -0
  149. package/stacks/node/templates/build-kit/lib/prompt.md +122 -0
  150. package/stacks/node/templates/build-kit/lib/ralph.js +369 -0
  151. package/stacks/node/templates/build-kit/ralph-claude.js +44 -0
  152. package/stacks/node/templates/build-kit/ralph.sh +98 -0
  153. package/stacks/node/templates/root/.env.example +15 -0
  154. package/stacks/node/templates/root/CLAUDE.md +60 -0
  155. package/stacks/node/templates/root/docker-compose.yml +15 -0
  156. package/stacks/node/templates/root/flyway.conf +17 -0
  157. package/stacks/node/templates/root/migrations/V1__schema.sql.example +12 -0
  158. package/stacks/node/templates/root/package.json +50 -0
  159. package/stacks/node/templates/root/server.ts +130 -0
  160. package/stacks/node/templates/root/setup-env.sh +53 -0
  161. package/stacks/node/templates/root/src/common/assertions.ts +6 -0
  162. package/stacks/node/templates/root/src/common/db.ts +32 -0
  163. package/stacks/node/templates/root/src/common/loadPostgresEventstore.ts +23 -0
  164. package/stacks/node/templates/root/src/common/parseEndpoint.ts +51 -0
  165. package/stacks/node/templates/root/src/common/processorDlq.ts +28 -0
  166. package/stacks/node/templates/root/src/common/realtimeBroadcast.ts +12 -0
  167. package/stacks/node/templates/root/src/common/replay.ts +16 -0
  168. package/stacks/node/templates/root/src/common/routes.ts +19 -0
  169. package/stacks/node/templates/root/src/common/testHelpers.ts +44 -0
  170. package/stacks/node/templates/root/src/swagger.ts +34 -0
  171. package/stacks/node/templates/root/src/util/assertions.ts +6 -0
  172. package/stacks/node/templates/root/src/util/hash.ts +9 -0
  173. package/stacks/node/templates/root/src/util/sanitize.ts +23 -0
  174. package/stacks/node/templates/root/tsconfig.json +32 -0
  175. package/stacks/node/templates/root/vercel.json +8 -0
  176. package/stacks/supabase/templates/.claude/skills/build-automation/SKILL.md +266 -0
  177. package/stacks/supabase/templates/.claude/skills/build-state-change/SKILL.md +344 -0
  178. package/stacks/supabase/templates/.claude/skills/build-state-view/SKILL.md +390 -0
  179. package/stacks/supabase/templates/.claude/skills/build-webhook/SKILL.md +303 -0
  180. package/stacks/supabase/templates/.claude/skills/connect/SKILL.md +178 -0
  181. package/stacks/supabase/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +628 -0
  182. package/stacks/supabase/templates/.claude/skills/load-slice/SKILL.md +143 -0
  183. package/stacks/supabase/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  184. package/stacks/supabase/templates/build-kit/README.md +86 -0
  185. package/stacks/supabase/templates/build-kit/lib/AGENT.md +47 -0
  186. package/stacks/supabase/templates/build-kit/lib/agent.sh +20 -0
  187. package/stacks/supabase/templates/build-kit/lib/backend-prompt.md +152 -0
  188. package/stacks/supabase/templates/build-kit/lib/prompt.md +123 -0
  189. package/stacks/supabase/templates/build-kit/lib/ralph.js +369 -0
  190. package/stacks/supabase/templates/build-kit/ralph-claude.js +44 -0
  191. package/stacks/supabase/templates/build-kit/ralph.sh +98 -0
  192. package/stacks/supabase/templates/root/.env.example +22 -0
  193. package/stacks/supabase/templates/root/CLAUDE.md +61 -0
  194. package/stacks/supabase/templates/root/flyway.conf +17 -0
  195. package/stacks/supabase/templates/root/package.json +52 -0
  196. package/stacks/supabase/templates/root/server.ts +177 -0
  197. package/stacks/supabase/templates/root/setup-env.sh +53 -0
  198. package/stacks/supabase/templates/root/src/common/assertions.ts +6 -0
  199. package/stacks/supabase/templates/root/src/common/db.ts +32 -0
  200. package/stacks/supabase/templates/root/src/common/loadPostgresEventstore.ts +23 -0
  201. package/stacks/supabase/templates/root/src/common/parseEndpoint.ts +51 -0
  202. package/stacks/supabase/templates/root/src/common/processorDlq.ts +28 -0
  203. package/stacks/supabase/templates/root/src/common/realtimeBroadcast.ts +19 -0
  204. package/stacks/supabase/templates/root/src/common/replay.ts +16 -0
  205. package/stacks/supabase/templates/root/src/common/routes.ts +23 -0
  206. package/stacks/supabase/templates/root/src/common/testHelpers.ts +54 -0
  207. package/stacks/supabase/templates/root/src/supabase/README.md +141 -0
  208. package/stacks/supabase/templates/root/src/supabase/api.ts +56 -0
  209. package/stacks/supabase/templates/root/src/supabase/requireOrgaAdmin.ts +32 -0
  210. package/stacks/supabase/templates/root/src/supabase/requireSysUser.ts +40 -0
  211. package/stacks/supabase/templates/root/src/supabase/requireUser.ts +72 -0
  212. package/stacks/supabase/templates/root/src/swagger.ts +34 -0
  213. package/stacks/supabase/templates/root/src/util/assertions.ts +6 -0
  214. package/stacks/supabase/templates/root/src/util/hash.ts +9 -0
  215. package/stacks/supabase/templates/root/src/util/sanitize.ts +23 -0
  216. package/stacks/supabase/templates/root/supabase/config.toml +295 -0
  217. package/stacks/supabase/templates/root/supabase/migrations/V1__schema.sql.example +12 -0
  218. package/stacks/supabase/templates/root/supabase/seed.sql +1 -0
  219. package/stacks/supabase/templates/root/tsconfig.json +32 -0
  220. package/stacks/supabase/templates/root/vercel.json +8 -0
@@ -0,0 +1,279 @@
1
+ # Axon Framework 5 — Workflow API Reference
2
+
3
+ > Preview feature — APIs may change. Source: https://docs.axoniq.io/axon-framework-reference/development/workflows/
4
+
5
+ ---
6
+
7
+ ## `@Workflow` annotation
8
+
9
+ ```java
10
+ @Workflow(
11
+ idProperty = "orderId", // field on trigger event used as workflow instance ID
12
+ startOnEventClass = OrderPlacedEvent.class, // event that starts a new instance
13
+ workflowNamespace = "io.myapp.orders" // namespace for internal event names
14
+ )
15
+ public void execute(SimpleWorkflowContext ctx) { ... }
16
+ ```
17
+
18
+ Alternative: start by event name string (useful for sub-workflows started via `EventSink`):
19
+
20
+ ```java
21
+ @Workflow(
22
+ idProperty = "childWorkflowId",
23
+ startOnEventName = "io.myapp.StartPaymentProcess",
24
+ workflowNamespace = "io.myapp.payments"
25
+ )
26
+ public void execute(SimpleWorkflowContext ctx) { ... }
27
+ ```
28
+
29
+ ---
30
+
31
+ ## `SimpleWorkflowContext` — core API
32
+
33
+ ### Data access
34
+
35
+ ```java
36
+ ctx.workflowId() // String — the workflow instance ID
37
+ ctx.workflowPayload() // Map<String,Object> — durable payload (snapshot of trigger event + updates)
38
+ ```
39
+
40
+ ### Execution steps
41
+
42
+ ```java
43
+ // Blocking: dispatches action and waits for completion. Throws StepFailedException on failure.
44
+ ctx.awaitExecute(
45
+ stepName, // String — unique name within this workflow instance
46
+ payload, // Map<String,Object> — data passed to the handler
47
+ handler // BiFunction<ProcessingContext, Map<String,Object>, Map<String,Object>>
48
+ );
49
+
50
+ // Non-blocking: dispatches action, returns handle immediately
51
+ WorkflowStepResult result = ctx.execute(
52
+ stepName,
53
+ payload,
54
+ handler,
55
+ Duration.ofSeconds(30), // step timeout
56
+ defaults() // WorkflowStepOptions
57
+ );
58
+ ```
59
+
60
+ ### Event suspension
61
+
62
+ ```java
63
+ // Wait until event arrives or timeout fires. Returns WorkflowStepResult.
64
+ WorkflowStepResult r = ctx.waitForEvent(
65
+ stepName,
66
+ SomeEvent.class,
67
+ Duration.ofDays(3)
68
+ );
69
+ r.timeout() // true if timeout fired before event arrived
70
+ r.await() // blocks until completed (call after !timeout() check)
71
+ r.result() // Optional<T> — the event payload
72
+
73
+ // With association predicate (match specific event by payload field)
74
+ ctx.awaitEvent(
75
+ stepName,
76
+ SomeEvent.class,
77
+ associate(payloadProperty("orderId"), equalsTo(ctx.workflowId())),
78
+ Duration.ofMinutes(30)
79
+ );
80
+ ```
81
+
82
+ ### Timer
83
+
84
+ ```java
85
+ // Durable sleep — survives restarts, recalculates remaining delay on resume
86
+ ctx.sleep(stepName, Duration.ofHours(24));
87
+ ```
88
+
89
+ ### Orchestration combinators
90
+
91
+ ```java
92
+ // Fan-in: wait until ALL matching. Returns a guard with matched/unmatched.
93
+ var guard = ctx.allMatch(WorkflowStepResult::isCompleted, step1, step2, step3);
94
+ guard.success() // true if all matched
95
+ guard.matched() // list of steps that matched
96
+ guard.unmatched() // list of steps that did not match
97
+
98
+ // Scatter-gather: wait until ANY matching. Returns the first matching result.
99
+ var fastest = ctx.anyMatch(WorkflowStepResult::isCompleted, step1, step2, step3);
100
+ fastest.await()
101
+ fastest.matched().getFirst() // the winning step
102
+ ```
103
+
104
+ ### State mutation
105
+
106
+ ```java
107
+ // Persist new data to the durable payload (survives restarts)
108
+ ctx.setPayload(stepName, payload("count", newCount).getValues());
109
+ ```
110
+
111
+ ### Termination
112
+
113
+ ```java
114
+ ctx.fail(new RuntimeException("reason")) // FAILED terminal state
115
+ ctx.cancel() // CANCELLED terminal state
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Workflow states
121
+
122
+ | State | Trigger |
123
+ |---|---|
124
+ | `STARTED` | Workflow instance created |
125
+ | `COMPLETED` | `execute()` method returned normally |
126
+ | `FAILED` | `ctx.fail()` called, or unhandled exception |
127
+ | `CANCELLED` | `ctx.cancel()` called, or external cancellation |
128
+ | `TIMED_OUT` | Overall workflow timeout exceeded |
129
+
130
+ ---
131
+
132
+ ## Lifecycle listeners
133
+
134
+ ```java
135
+ @OnSuccess public void onSuccess(SimpleWorkflowContext ctx) { ... }
136
+ @OnFailure public void onFailure(SimpleWorkflowContext ctx) { ... }
137
+ @OnCancellation public void onCancelled(SimpleWorkflowContext ctx) { ... }
138
+ @OnTimeout public void onTimeout(SimpleWorkflowContext ctx) { ... }
139
+ ```
140
+
141
+ Or programmatically via `.registerWorkflowStatusChangeListener(WorkflowStatus.COMPLETED, (status, ctx) -> {...})`.
142
+
143
+ ---
144
+
145
+ ## `WorkflowModule` configuration
146
+
147
+ ```java
148
+ WorkflowModule
149
+ .usingContext(SimpleWorkflowContext.class)
150
+ .workflowContextFactory(c -> new SimpleWorkflowContextFactory())
151
+ .workflowExecutionFactory(c -> new DSLAdoptingExecutionFactory<>(SimpleWorkflowContext.class))
152
+ .definitions(d -> d
153
+ // Annotation-based (reads @Workflow from the instance)
154
+ .autodetected(c -> new MyWorkflow(), SimpleWorkflowContext.class)
155
+
156
+ // Declarative (explicit name + trigger)
157
+ .declarative(c -> workflow::execute)
158
+ .workflowName("OrderFulfillment")
159
+ .on(EventConditions.fromType(OrderPlacedEvent.class))
160
+ .customized((c, w) -> w
161
+ .eventNameCustomizer(namespace("io.myapp.orders"))
162
+ .workflowIdProvider(fromPayloadAttribute(c, "orderId"))
163
+ .registerWorkflowStatusChangeListener(WorkflowStatus.COMPLETED,
164
+ (status, ctx) -> logger.info("Done: {}", ctx.workflowId()))
165
+ )
166
+ );
167
+ ```
168
+
169
+ ### Start condition with predicate
170
+
171
+ ```java
172
+ .on(EventConditions.fromType(
173
+ OrderPlacedEvent.class,
174
+ associate(payloadProperty("type"), equalsTo("priority")) // only start for priority orders
175
+ ))
176
+ ```
177
+
178
+ ### Workflow ID providers
179
+
180
+ ```java
181
+ fromPayloadAttribute(c, "orderId") // extract "orderId" field as-is
182
+ fromPayloadAttribute(c, "orderId", id -> "o-" + id) // with transformation
183
+ // default: MessageWorkflowIdProvider — uses the event message's native ID
184
+ ```
185
+
186
+ ### Custom context (domain-specific DSL)
187
+
188
+ ```java
189
+ public class ApprovalWorkflowContext extends SimpleWorkflowContext {
190
+ public ApprovalWorkflowContext(String workflowId, Map<String, Object> payload,
191
+ ProcessingContext pc, WorkflowConfiguration<?> cfg) {
192
+ super(workflowId, payload, pc, cfg);
193
+ }
194
+
195
+ public boolean requestApproval(String approver, Duration deadline) {
196
+ awaitExecute("requestApproval",
197
+ payload("approver", approver, "requestId", workflowId()).getValues(),
198
+ ApprovalService::sendRequest);
199
+ var decision = awaitEvent("awaitDecision", ApprovalDecisionEvent.class, deadline);
200
+ return "approved".equals(decision.result().map(ApprovalDecisionEvent::outcome).orElse(""));
201
+ }
202
+ }
203
+
204
+ // Factory
205
+ public class ApprovalContextFactory implements WorkflowContextFactory<ApprovalWorkflowContext> {
206
+ @Override
207
+ public ApprovalWorkflowContext createContext(Map<String, Object> payload, String workflowId,
208
+ ProcessingContext pc, WorkflowConfiguration<?> cfg) {
209
+ return new ApprovalWorkflowContext(workflowId, payload, pc, cfg);
210
+ }
211
+ }
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Metadata keys propagated by the engine
217
+
218
+ | Key | Value |
219
+ |---|---|
220
+ | `workflowId` | Workflow instance ID |
221
+ | `stepName` | Name of the currently executing step |
222
+ | `stepType` | Type of step (execute, event, sleep, etc.) |
223
+ | `workflowStatus` | Current workflow status |
224
+
225
+ ---
226
+
227
+ ## Sub-workflow pattern
228
+
229
+ ```java
230
+ // Parent: publish trigger event for child via EventSink (no workflow metadata)
231
+ ctx.awaitExecute("startChild",
232
+ payload("childId", "child-" + ctx.workflowId(), "orderId", ctx.workflowId()).getValues(),
233
+ (pc, p) -> {
234
+ var trigger = new StartChildWorkflow((String) p.get("childId"), (String) p.get("orderId"));
235
+ eventSink.publish(null, new GenericEventMessage<>(
236
+ messageTypeResolver.resolveOrThrow(trigger), trigger));
237
+ return Map.of();
238
+ });
239
+
240
+ // Parent: wait for child completion event, matched by orderId
241
+ ctx.awaitEvent("awaitChild",
242
+ ChildWorkflowCompleted.class,
243
+ associate(payloadProperty("orderId"), equalsTo(ctx.workflowId())),
244
+ Duration.ofMinutes(30));
245
+ ```
246
+
247
+ Child workflow:
248
+ ```java
249
+ @Workflow(idProperty = "childId",
250
+ startOnEventName = "io.myapp.StartChildWorkflow",
251
+ workflowNamespace = "io.myapp.child")
252
+ public void execute(SimpleWorkflowContext ctx) {
253
+ // ... do work ...
254
+ // Signal parent via EventSink
255
+ ctx.awaitExecute("notifyParent", ctx.workflowPayload(),
256
+ (pc, p) -> {
257
+ var done = new ChildWorkflowCompleted(
258
+ (String) p.get("orderId"), (String) p.get("childId"));
259
+ eventSink.publish(null, new GenericEventMessage<>(
260
+ messageTypeResolver.resolveOrThrow(done), done));
261
+ return Map.of();
262
+ });
263
+ }
264
+ ```
265
+
266
+ ---
267
+
268
+ ## `payload(...)` helper
269
+
270
+ ```java
271
+ payload("key1", value1, "key2", value2).getValues() // returns Map<String, Object>
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Testing
277
+
278
+ Use `AbstractDeclarativeTestBase` from the AF5 workflow test module for integration tests.
279
+ For unit tests, mock `SimpleWorkflowContext` with Mockito and verify step call order.
@@ -0,0 +1,114 @@
1
+ # Feature Flag Patterns
2
+
3
+ How to conditionally enable/disable individual slice components. Examples use a generic `Ordering` bounded context.
4
+
5
+ ---
6
+
7
+ ## Option 1: Spring Boot `@ConditionalOnProperty` (default)
8
+
9
+ Add `@ConditionalOnProperty` to every conditionally-loaded component in the slice. Update config files
10
+ and Spring metadata so the IDE auto-completes property keys.
11
+
12
+ ### Annotation on slice components
13
+
14
+ ```java
15
+ // Entity
16
+ @ConditionalOnProperty(prefix = "slices.ordering", name = "write.placeorder.enabled")
17
+ @EventSourced(tagKey = EventTags.ORDER_ID)
18
+ class PlaceOrderEntity { ... }
19
+
20
+ // Handler
21
+ @ConditionalOnProperty(prefix = "slices.ordering", name = "write.placeorder.enabled")
22
+ @Component
23
+ public class PlaceOrderHandler { ... }
24
+
25
+ // REST controller (if applicable)
26
+ @ConditionalOnProperty(prefix = "slices.ordering", name = "write.placeorder.enabled")
27
+ @RestController
28
+ public class PlaceOrderRestController { ... }
29
+ ```
30
+
31
+ For the **Explicit Registration pattern**, put `@ConditionalOnProperty` on the `@Configuration` class only:
32
+
33
+ ```java
34
+ @ConditionalOnProperty(prefix = "slices.ordering", name = "write.placeorder.enabled")
35
+ @Configuration
36
+ class PlaceOrderWriteSliceConfig { ... }
37
+ ```
38
+
39
+ ### `application.properties` (main — enable by default)
40
+
41
+ ```properties
42
+ slices.ordering.write.placeorder.enabled=true
43
+ slices.ordering.read.getorders.enabled=true
44
+ slices.ordering.automation.notifycustomeronorder.enabled=true
45
+ ```
46
+
47
+ ### `application.properties` (test — disable by default, opt-in per test)
48
+
49
+ ```properties
50
+ slices.ordering.write.placeorder.enabled=false
51
+ slices.ordering.read.getorders.enabled=false
52
+ slices.ordering.automation.notifycustomeronorder.enabled=false
53
+ ```
54
+
55
+ ### Opt-in in a specific test class
56
+
57
+ ```java
58
+ @TestPropertySource(properties = {"slices.ordering.write.placeorder.enabled=true"})
59
+ @SpringBootTest
60
+ class PlaceOrderTest { ... }
61
+ ```
62
+
63
+ ### `META-INF/additional-spring-configuration-metadata.json`
64
+
65
+ Register each property so IDEs auto-complete and validate it:
66
+
67
+ ```json
68
+ {
69
+ "properties": [
70
+ {
71
+ "name": "slices.ordering.write.placeorder.enabled",
72
+ "type": "java.lang.Boolean",
73
+ "description": "Enable/disable the PlaceOrder write slice in the Ordering bounded context."
74
+ },
75
+ {
76
+ "name": "slices.ordering.read.getorders.enabled",
77
+ "type": "java.lang.Boolean",
78
+ "description": "Enable/disable the GetOrders read slice in the Ordering bounded context."
79
+ }
80
+ ]
81
+ }
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Option 2: Spring Profile (`@Profile`)
87
+
88
+ Enable/disable components by activating a named Spring profile. Simpler for "all or nothing" rollouts,
89
+ less granular than `@ConditionalOnProperty`.
90
+
91
+ ```java
92
+ @Profile("ordering-write")
93
+ @Component
94
+ public class PlaceOrderHandler { ... }
95
+ ```
96
+
97
+ Activate in tests via `@ActiveProfiles("ordering-write")` or `spring.profiles.active=ordering-write`.
98
+
99
+ ---
100
+
101
+ ## Option 3: No feature flags
102
+
103
+ If the project ships all slices unconditionally, omit `@ConditionalOnProperty` entirely. Applicable when:
104
+ - The project is small and startup time is not a concern
105
+ - There is no partial-rollout requirement
106
+ - Feature branches are the rollout mechanism
107
+
108
+ ---
109
+
110
+ ## Convention recommendation
111
+
112
+ - Use `@ConditionalOnProperty` for new projects: zero extra dependencies, IDE-friendly, test-friendly.
113
+ - Disable all slices by default in the test properties; opt-in per test class via `@TestPropertySource`.
114
+ - Always enable BOTH the slice under test AND its dependencies (e.g., the automation AND the target write slice).