eventmodeler 0.4.6 → 0.5.0
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/api/index.d.ts +3 -0
- package/dist/api/index.js +3 -0
- package/dist/eventmodeler.js +3 -2
- package/dist/index.js +58 -13
- package/dist/slices/guide/guides/codegen.d.ts +5 -0
- package/dist/slices/guide/guides/codegen.js +339 -0
- package/dist/slices/guide/guides/connect-slices.d.ts +5 -0
- package/dist/slices/guide/guides/connect-slices.js +202 -0
- package/dist/slices/guide/guides/create-slices.d.ts +5 -0
- package/dist/slices/guide/guides/create-slices.js +303 -0
- package/dist/slices/guide/guides/explore.d.ts +5 -0
- package/dist/slices/guide/guides/explore.js +251 -0
- package/dist/slices/guide/guides/information-flow.d.ts +5 -0
- package/dist/slices/guide/guides/information-flow.js +318 -0
- package/dist/slices/guide/guides/scenarios.d.ts +5 -0
- package/dist/slices/guide/guides/scenarios.js +269 -0
- package/dist/slices/guide/index.d.ts +1 -0
- package/dist/slices/guide/index.js +40 -0
- package/dist/slices/open-app/index.js +1 -1
- package/package.json +5 -10
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'connect-slices',
|
|
3
|
+
description: 'Connect slices with flows to show how data moves through the system',
|
|
4
|
+
};
|
|
5
|
+
export const content = `
|
|
6
|
+
# Connecting Slices
|
|
7
|
+
|
|
8
|
+
After creating slices, you need to connect them with flows to show how data moves through the system. This creates the complete picture of your event model.
|
|
9
|
+
|
|
10
|
+
## The Data Flow Pattern
|
|
11
|
+
|
|
12
|
+
In event modeling, data flows in a specific pattern:
|
|
13
|
+
|
|
14
|
+
\`\`\`
|
|
15
|
+
[State-Change Slice] [State-View Slice] [Next Slice]
|
|
16
|
+
|
|
17
|
+
Screen ReadModel Screen
|
|
18
|
+
| ^ | ^
|
|
19
|
+
v | v |
|
|
20
|
+
Command | - - - - - - - - - - - - - +
|
|
21
|
+
| | OR
|
|
22
|
+
v | Processor
|
|
23
|
+
Event - - - - - - - - - - - - - - - + ^
|
|
24
|
+
|
|
|
25
|
+
+ - - - - - - - - - - -+
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
**Key flows:**
|
|
29
|
+
1. **Event → ReadModel**: Events project their data into read models
|
|
30
|
+
2. **ReadModel → Screen**: Read models provide data to screens (for user viewing)
|
|
31
|
+
3. **ReadModel → Processor**: Read models provide data to processors (for automation)
|
|
32
|
+
|
|
33
|
+
Within-slice flows (Screen→Command, Command→Event, Processor→Command) are created automatically when you create a slice.
|
|
34
|
+
|
|
35
|
+
## Command Syntax
|
|
36
|
+
|
|
37
|
+
\`\`\`bash
|
|
38
|
+
eventmodeler create flow --from "<source>" --to "<target>"
|
|
39
|
+
\`\`\`
|
|
40
|
+
|
|
41
|
+
## Valid Flow Combinations
|
|
42
|
+
|
|
43
|
+
| Source | Target | Use Case |
|
|
44
|
+
|--------|--------|----------|
|
|
45
|
+
| Event | ReadModel | Project event data into a view |
|
|
46
|
+
| ReadModel | Screen | Provide data for user display |
|
|
47
|
+
| ReadModel | Processor | Provide data for automation logic |
|
|
48
|
+
|
|
49
|
+
## Workflow: Connecting a Complete Model
|
|
50
|
+
|
|
51
|
+
### 1. Create Your Slices First
|
|
52
|
+
|
|
53
|
+
\`\`\`bash
|
|
54
|
+
# User places an order
|
|
55
|
+
eventmodeler create state-change-slice --xml '<state-change-slice name="Place Order">
|
|
56
|
+
<screen name="Checkout">...</screen>
|
|
57
|
+
<command name="PlaceOrder">...</command>
|
|
58
|
+
<event name="OrderPlaced">...</event>
|
|
59
|
+
</state-change-slice>'
|
|
60
|
+
|
|
61
|
+
# View for order status
|
|
62
|
+
eventmodeler create state-view-slice --xml '<state-view-slice name="View Order Status" after="Place Order">
|
|
63
|
+
<read-model name="OrderStatus">...</read-model>
|
|
64
|
+
</state-view-slice>'
|
|
65
|
+
|
|
66
|
+
# System automatically fulfills order (includes its own read model)
|
|
67
|
+
eventmodeler create automation-slice --xml '<automation-slice name="Auto Fulfill" after="View Order Status">
|
|
68
|
+
<read-model name="OrderReadyToFulfill">
|
|
69
|
+
<field name="orderId" type="UUID"/>
|
|
70
|
+
<field name="isPaid" type="Boolean"/>
|
|
71
|
+
</read-model>
|
|
72
|
+
<processor name="Fulfillment Processor"/>
|
|
73
|
+
<command name="FulfillOrder">...</command>
|
|
74
|
+
<event name="OrderFulfilled">...</event>
|
|
75
|
+
</automation-slice>'
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
### 2. Connect Events to Read Models
|
|
79
|
+
|
|
80
|
+
Events project their data into read models:
|
|
81
|
+
|
|
82
|
+
\`\`\`bash
|
|
83
|
+
# OrderPlaced feeds into OrderStatus view
|
|
84
|
+
eventmodeler create flow --from "OrderPlaced" --to "OrderStatus"
|
|
85
|
+
|
|
86
|
+
# OrderFulfilled also updates OrderStatus view
|
|
87
|
+
eventmodeler create flow --from "OrderFulfilled" --to "OrderStatus"
|
|
88
|
+
\`\`\`
|
|
89
|
+
|
|
90
|
+
### 3. Connect Events to Automation Read Models
|
|
91
|
+
|
|
92
|
+
Automation slices have their own internal read model. Connect external events to feed it:
|
|
93
|
+
|
|
94
|
+
\`\`\`bash
|
|
95
|
+
# OrderPlaced feeds the automation's read model
|
|
96
|
+
eventmodeler create flow --from "OrderPlaced" --to "OrderReadyToFulfill"
|
|
97
|
+
|
|
98
|
+
# PaymentReceived also feeds the automation's read model
|
|
99
|
+
eventmodeler create flow --from "PaymentReceived" --to "OrderReadyToFulfill"
|
|
100
|
+
\`\`\`
|
|
101
|
+
|
|
102
|
+
Note: The flow from ReadModel → Processor is internal to the automation slice and created automatically.
|
|
103
|
+
|
|
104
|
+
### 4. Connect Read Models to Screens
|
|
105
|
+
|
|
106
|
+
State-view read models provide data to screens:
|
|
107
|
+
|
|
108
|
+
\`\`\`bash
|
|
109
|
+
# OrderStatus provides data to a screen in another slice
|
|
110
|
+
eventmodeler create flow --from "OrderStatus" --to "Order Details Screen"
|
|
111
|
+
\`\`\`
|
|
112
|
+
|
|
113
|
+
### 5. Set Up Field Mappings
|
|
114
|
+
|
|
115
|
+
After creating flows, map the fields:
|
|
116
|
+
|
|
117
|
+
\`\`\`bash
|
|
118
|
+
eventmodeler map fields --flow "OrderPlaced→OrderStatus" --xml '
|
|
119
|
+
<mapping from="orderId" to="orderId"/>
|
|
120
|
+
<mapping from="customerId" to="customerId"/>
|
|
121
|
+
<mapping from="placedAt" to="placedAt"/>
|
|
122
|
+
'
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
### 6. Verify Completeness
|
|
126
|
+
|
|
127
|
+
Check that all flows have proper field mappings:
|
|
128
|
+
|
|
129
|
+
\`\`\`bash
|
|
130
|
+
eventmodeler show model-completeness
|
|
131
|
+
eventmodeler show completeness "OrderStatus"
|
|
132
|
+
\`\`\`
|
|
133
|
+
|
|
134
|
+
## Handling Duplicate Names with IDs
|
|
135
|
+
|
|
136
|
+
When multiple elements share the same name (e.g., linked copies of events or read models), use element IDs with the \`id:\` prefix. This works with every command that accepts an element name — not just flows. See \`eventmodeler guide explore\` for the full details.
|
|
137
|
+
|
|
138
|
+
\`\`\`bash
|
|
139
|
+
# Find element IDs via list commands
|
|
140
|
+
eventmodeler list events
|
|
141
|
+
# <event id="abc12345-..." name="OrderPlaced" fields="4"/>
|
|
142
|
+
# <event id="def67890-..." name="OrderPlaced" fields="4"/> <!-- linked copy -->
|
|
143
|
+
|
|
144
|
+
# Use ID prefix (first 8 chars is usually enough)
|
|
145
|
+
eventmodeler create flow --from "id:abc12345" --to "OrderStatus"
|
|
146
|
+
eventmodeler map fields --flow "id:abc12345→OrderStatus" --xml '
|
|
147
|
+
<mapping from="orderId" to="orderId"/>
|
|
148
|
+
'
|
|
149
|
+
\`\`\`
|
|
150
|
+
|
|
151
|
+
The CLI will tell you when names are ambiguous and show the IDs to choose from.
|
|
152
|
+
|
|
153
|
+
## Common Patterns
|
|
154
|
+
|
|
155
|
+
### Pattern 1: Event Sourced View
|
|
156
|
+
Multiple events feed into one read model:
|
|
157
|
+
|
|
158
|
+
\`\`\`bash
|
|
159
|
+
eventmodeler create flow --from "OrderPlaced" --to "OrderSummary"
|
|
160
|
+
eventmodeler create flow --from "OrderShipped" --to "OrderSummary"
|
|
161
|
+
eventmodeler create flow --from "OrderDelivered" --to "OrderSummary"
|
|
162
|
+
\`\`\`
|
|
163
|
+
|
|
164
|
+
### Pattern 2: Automation Triggered by Events
|
|
165
|
+
Events feed an automation slice's internal read model:
|
|
166
|
+
|
|
167
|
+
\`\`\`bash
|
|
168
|
+
eventmodeler create flow --from "OrderPlaced" --to "OrderReadyForShipment"
|
|
169
|
+
eventmodeler create flow --from "PaymentReceived" --to "OrderReadyForShipment"
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
### Pattern 3: User Dashboard
|
|
173
|
+
A read model feeds a screen for user viewing:
|
|
174
|
+
|
|
175
|
+
\`\`\`bash
|
|
176
|
+
eventmodeler create flow --from "UserDashboard" --to "Dashboard Screen"
|
|
177
|
+
\`\`\`
|
|
178
|
+
|
|
179
|
+
## Error Handling
|
|
180
|
+
|
|
181
|
+
The CLI prevents invalid flows:
|
|
182
|
+
|
|
183
|
+
\`\`\`bash
|
|
184
|
+
# This will error - can't go directly from Event to Screen
|
|
185
|
+
eventmodeler create flow --from "OrderPlaced" --to "Checkout Screen"
|
|
186
|
+
# Error: Cannot create flow directly from Event to Screen.
|
|
187
|
+
# Events flow to ReadModels, which then flow to Screens.
|
|
188
|
+
|
|
189
|
+
# This will error - can't go from ReadModel to ReadModel
|
|
190
|
+
eventmodeler create flow --from "OrderStatus" --to "CustomerProfile"
|
|
191
|
+
# Error: Cannot create flow from ReadModel to ReadModel.
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
## Best Practices
|
|
195
|
+
|
|
196
|
+
1. **Create all slices first** - Easier to see the full picture before connecting
|
|
197
|
+
2. **Connect events to read models** - Every event should feed at least one read model
|
|
198
|
+
3. **Think about what triggers what** - Automation slices need data from read models
|
|
199
|
+
4. **Map fields after creating flows** - Use \`map fields\` to complete the data flow
|
|
200
|
+
5. **Verify completeness** - Run \`show model-completeness\` to find missing mappings
|
|
201
|
+
6. **Use IDs for duplicates** - When names aren't unique, use \`id:\` prefix with element IDs
|
|
202
|
+
`;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const meta: {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const content = "\n# Creating Slices\n\nThere are three slice types in an event model. Each represents a different pattern of data flow.\n\n---\n\n## State-Change Slices\n\nA state-change slice represents a **user-initiated action** that changes system state:\n\n```\nScreen \u2192 Command \u2192 Event\n```\n\n- **Screen**: The UI where the user initiates the action\n- **Command**: The intent/request to change state\n- **Event**: The fact that state changed\n\n### When to Use\n\nUse state-change slices when:\n- A user performs an action (clicks a button, submits a form)\n- That action changes the state of an entity\n- Examples: \"Place Order\", \"Cancel Subscription\", \"Update Profile\", \"Add Item to Cart\"\n\n### Command Syntax\n\n```bash\neventmodeler create state-change-slice --xml '<state-change-slice name=\"Slice Name\" [after=\"Other Slice\"]>\n <screen name=\"Screen Name\">\n <field name=\"fieldName\" type=\"Type\"/>\n </screen>\n <command name=\"CommandName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </command>\n <event name=\"EventName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </event>\n</state-change-slice>'\n```\n\n### Example: Place Order Slice\n\n```bash\neventmodeler create state-change-slice --xml '<state-change-slice name=\"Place Order\">\n <screen name=\"Checkout Screen\">\n <field name=\"customerId\" type=\"UUID\"/>\n <field name=\"items\" type=\"String\" isUserInput=\"true\"/>\n <field name=\"shippingAddress\" type=\"String\" isUserInput=\"true\"/>\n </screen>\n <command name=\"PlaceOrder\">\n <field name=\"customerId\" type=\"UUID\"/>\n <field name=\"items\" type=\"String\"/>\n <field name=\"shippingAddress\" type=\"String\"/>\n </command>\n <event name=\"OrderPlaced\">\n <field name=\"orderId\" type=\"UUID\" isGenerated=\"true\"/>\n <field name=\"customerId\" type=\"UUID\"/>\n <field name=\"items\" type=\"String\"/>\n <field name=\"shippingAddress\" type=\"String\"/>\n <field name=\"placedAt\" type=\"DateTime\" isGenerated=\"true\"/>\n </event>\n</state-change-slice>'\n```\n\n### Automatic Behavior\n\n1. **Positioning**: Places slice at end, or use `after=\"Slice Name\"` or `before=\"Slice Name\"`\n2. **Field mappings**: Automatically inferred by matching field names between Screen \u2192 Command and Command \u2192 Event\n3. **Flows**: Automatically creates Screen\u2192Command and Command\u2192Event flows\n\n---\n\n## Automation Slices\n\nAn automation slice represents a **system-initiated action**:\n\n```\nReadModel \u2192 Processor \u2192 Command \u2192 Event\n```\n\n- **ReadModel**: The state/data the processor needs to make decisions\n- **Processor**: The system component that decides when and how to act\n- **Command**: The intent/request to change state\n- **Event**: The fact that state changed\n\n### When to Use\n\nUse automation slices when:\n- The system automatically responds to events\n- No direct user interaction triggers the action\n- Examples: \"Auto-assign Reviewer\", \"Send Reminder Email\", \"Calculate Shipping\", \"Process Payment\"\n\n### Command Syntax\n\n```bash\neventmodeler create automation-slice --xml '<automation-slice name=\"Slice Name\" [after=\"Other Slice\"]>\n <read-model name=\"ReadModelName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </read-model>\n <processor name=\"Processor Name\"/>\n <command name=\"CommandName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </command>\n <event name=\"EventName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </event>\n</automation-slice>'\n```\n\n### Example: Auto-Fulfill Order\n\n```bash\neventmodeler create automation-slice --xml '<automation-slice name=\"Auto Fulfill Order\" after=\"Place Order\">\n <read-model name=\"OrderReadyForFulfillment\">\n <field name=\"orderId\" type=\"UUID\"/>\n <field name=\"isPaid\" type=\"Boolean\"/>\n <field name=\"shippingAddress\" type=\"String\"/>\n </read-model>\n <processor name=\"Order Fulfillment Processor\"/>\n <command name=\"FulfillOrder\">\n <field name=\"orderId\" type=\"UUID\"/>\n <field name=\"warehouseId\" type=\"UUID\" isGenerated=\"true\"/>\n </command>\n <event name=\"OrderFulfilled\">\n <field name=\"orderId\" type=\"UUID\"/>\n <field name=\"warehouseId\" type=\"UUID\"/>\n <field name=\"fulfilledAt\" type=\"DateTime\" isGenerated=\"true\"/>\n </event>\n</automation-slice>'\n```\n\n### Automatic Behavior\n\n1. **Positioning**: Places slice at end, or use `after=\"Slice Name\"` or `before=\"Slice Name\"`\n2. **Field mappings**: Automatically inferred by matching field names: ReadModel \u2192 Command, Command \u2192 Event\n3. **Flows**: Automatically creates ReadModel \u2192 Processor, Processor \u2192 Command, Command \u2192 Event\n\n### Connecting Trigger Events\n\nAfter creating the automation slice, connect external events to its read model:\n\n```bash\neventmodeler create flow --from \"OrderPlaced\" --to \"OrderReadyForFulfillment\"\neventmodeler create flow --from \"PaymentReceived\" --to \"OrderReadyForFulfillment\"\n```\n\n### Automation vs State-View Read Models\n\n| Automation ReadModel | State-View ReadModel |\n|---------------------|---------------------|\n| Inside automation slice | Standalone slice |\n| Feeds a Processor | Feeds a Screen |\n| \"What the processor needs\" | \"What the user sees\" |\n| Created with automation-slice | Created with state-view-slice |\n\n---\n\n## State-View Slices\n\nA state-view slice represents a **read model** - a projection of event data for querying:\n\n```\nRead Model (fed by events)\n```\n\n### When to Use\n\nUse state-view slices when:\n- You need to display data to users\n- A processor needs to query current state\n- You want to aggregate data from multiple events\n- Examples: \"Order Summary\", \"User Dashboard\", \"Inventory Levels\", \"Account Balance\"\n\n### Command Syntax\n\n```bash\neventmodeler create state-view-slice --xml '<state-view-slice name=\"Slice Name\" [after=\"Other Slice\"]>\n <read-model name=\"ReadModelName\">\n <field name=\"fieldName\" type=\"Type\"/>\n </read-model>\n</state-view-slice>'\n```\n\n### Example: Order Summary View\n\n```bash\neventmodeler create state-view-slice --xml '<state-view-slice name=\"View Order Summary\" after=\"Place Order\">\n <read-model name=\"OrderSummary\">\n <field name=\"orderId\" type=\"UUID\"/>\n <field name=\"customerId\" type=\"UUID\"/>\n <field name=\"customerName\" type=\"String\"/>\n <field name=\"status\" type=\"String\"/>\n <field name=\"totalAmount\" type=\"Decimal\"/>\n <field name=\"itemCount\" type=\"Int\"/>\n <field name=\"placedAt\" type=\"DateTime\"/>\n <field name=\"lastUpdatedAt\" type=\"DateTime\"/>\n </read-model>\n</state-view-slice>'\n```\n\n### Connecting Events After Creation\n\nThe `create state-view-slice` command only creates the read model. To complete the picture:\n\n1. Create flows from events: `eventmodeler create flow --from \"EventName\" --to \"ReadModelName\"`\n2. Map fields: `eventmodeler map fields --flow \"EventName\u2192ReadModelName\" --xml '...'`\n3. Verify: `eventmodeler show completeness \"ReadModelName\"`\n\n---\n\n## Field Types\n\n`UUID`, `String`, `Int`, `Long`, `Double`, `Decimal`, `Boolean`, `Date`, `DateTime`, `Custom`\n\n## Field Attributes\n\n- `isOptional=\"true\"` - Field may not have a value\n- `isGenerated=\"true\"` - System-generated (e.g., IDs, timestamps), not from user input\n- `isUserInput=\"true\"` - Entered by the user on the screen\n- `isList=\"true\"` - Field is a list/array of the specified type\n\n## Working with Lists and Custom Types\n\n**List of primitives** - use `isList=\"true\"` with any valid type:\n```xml\n<field name=\"tags\" type=\"String\" isList=\"true\"/>\n<field name=\"quantities\" type=\"Int\" isList=\"true\"/>\n```\n\n### Custom Types (Nested Objects)\n\n**CRITICAL: Custom fields MUST contain subfields.** The `type=\"Custom\"` indicates a nested object structure, and the nested `<field>` elements define its properties. A Custom field without subfields is invalid and creates an empty, useless type.\n\n**Custom type with nested fields:**\n```xml\n<field name=\"address\" type=\"Custom\">\n <field name=\"street\" type=\"String\"/>\n <field name=\"city\" type=\"String\"/>\n <field name=\"postalCode\" type=\"String\"/>\n</field>\n```\n\n**List of custom objects** - combine `type=\"Custom\"` with `isList=\"true\"`:\n```xml\n<field name=\"lineItems\" type=\"Custom\" isList=\"true\">\n <field name=\"productId\" type=\"UUID\"/>\n <field name=\"quantity\" type=\"Int\"/>\n <field name=\"unitPrice\" type=\"Decimal\"/>\n</field>\n```\n\n**Nested custom types** - subfields can themselves be Custom types:\n```xml\n<field name=\"customer\" type=\"Custom\">\n <field name=\"customerId\" type=\"UUID\"/>\n <field name=\"name\" type=\"String\"/>\n <field name=\"billingAddress\" type=\"Custom\">\n <field name=\"street\" type=\"String\"/>\n <field name=\"city\" type=\"String\"/>\n <field name=\"country\" type=\"String\"/>\n </field>\n</field>\n```\n\n## Common Mistakes\n\n- **Creating empty Custom fields**: Custom fields MUST have subfields that define their structure.\n - Wrong: `<field name=\"address\" type=\"Custom\"/>`\n - Right: `<field name=\"address\" type=\"Custom\"><field name=\"street\" type=\"String\"/>...</field>`\n\n- **Using \"List\" as a field type**: \"List\" is not a valid type. Use `isList=\"true\"` with a valid type instead.\n - Wrong: `<field name=\"items\" type=\"List\"/>`\n - Right: `<field name=\"items\" type=\"String\" isList=\"true\"/>`\n\n- **Using wrong attribute names**: Always use camelCase attributes.\n - Wrong: `optional=\"true\"`, `generated=\"true\"`, `list=\"true\"`, `user-input=\"true\"`\n - Right: `isOptional=\"true\"`, `isGenerated=\"true\"`, `isList=\"true\"`, `isUserInput=\"true\"`\n\n## Workflow\n\n1. **Understand the action** - What is the user/system trying to do?\n2. **Design the fields** - What information flows through this slice?\n3. **Propose before creating** - Get approval on the design first\n4. **Create the slice** - Run the command\n5. **Verify** - `eventmodeler show slice \"<name>\"`\n6. **Connect** - Create flows to/from other slices as needed\n\n## Best Practices\n\n1. **Get approval first** - Propose the design before creating\n2. **Use meaningful names** - Slice name should describe the action (\"Place Order\" not \"Order Slice\")\n3. **Include generated fields** - Events should have IDs and timestamps\n4. **Match field names** - Same names enable automatic mapping\n5. **Consider what's user input vs system data** - Mark appropriately\n6. **Name automation read models for their purpose** - \"OrderReadyForFulfillment\" not \"OrderData\"\n7. **Name processors descriptively** - \"Order Fulfillment Processor\" not just \"Processor\"\n";
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'create-slices',
|
|
3
|
+
description: 'Create state-change, automation, and state-view slices with fields and flows',
|
|
4
|
+
};
|
|
5
|
+
export const content = `
|
|
6
|
+
# Creating Slices
|
|
7
|
+
|
|
8
|
+
There are three slice types in an event model. Each represents a different pattern of data flow.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## State-Change Slices
|
|
13
|
+
|
|
14
|
+
A state-change slice represents a **user-initiated action** that changes system state:
|
|
15
|
+
|
|
16
|
+
\`\`\`
|
|
17
|
+
Screen → Command → Event
|
|
18
|
+
\`\`\`
|
|
19
|
+
|
|
20
|
+
- **Screen**: The UI where the user initiates the action
|
|
21
|
+
- **Command**: The intent/request to change state
|
|
22
|
+
- **Event**: The fact that state changed
|
|
23
|
+
|
|
24
|
+
### When to Use
|
|
25
|
+
|
|
26
|
+
Use state-change slices when:
|
|
27
|
+
- A user performs an action (clicks a button, submits a form)
|
|
28
|
+
- That action changes the state of an entity
|
|
29
|
+
- Examples: "Place Order", "Cancel Subscription", "Update Profile", "Add Item to Cart"
|
|
30
|
+
|
|
31
|
+
### Command Syntax
|
|
32
|
+
|
|
33
|
+
\`\`\`bash
|
|
34
|
+
eventmodeler create state-change-slice --xml '<state-change-slice name="Slice Name" [after="Other Slice"]>
|
|
35
|
+
<screen name="Screen Name">
|
|
36
|
+
<field name="fieldName" type="Type"/>
|
|
37
|
+
</screen>
|
|
38
|
+
<command name="CommandName">
|
|
39
|
+
<field name="fieldName" type="Type"/>
|
|
40
|
+
</command>
|
|
41
|
+
<event name="EventName">
|
|
42
|
+
<field name="fieldName" type="Type"/>
|
|
43
|
+
</event>
|
|
44
|
+
</state-change-slice>'
|
|
45
|
+
\`\`\`
|
|
46
|
+
|
|
47
|
+
### Example: Place Order Slice
|
|
48
|
+
|
|
49
|
+
\`\`\`bash
|
|
50
|
+
eventmodeler create state-change-slice --xml '<state-change-slice name="Place Order">
|
|
51
|
+
<screen name="Checkout Screen">
|
|
52
|
+
<field name="customerId" type="UUID"/>
|
|
53
|
+
<field name="items" type="String" isUserInput="true"/>
|
|
54
|
+
<field name="shippingAddress" type="String" isUserInput="true"/>
|
|
55
|
+
</screen>
|
|
56
|
+
<command name="PlaceOrder">
|
|
57
|
+
<field name="customerId" type="UUID"/>
|
|
58
|
+
<field name="items" type="String"/>
|
|
59
|
+
<field name="shippingAddress" type="String"/>
|
|
60
|
+
</command>
|
|
61
|
+
<event name="OrderPlaced">
|
|
62
|
+
<field name="orderId" type="UUID" isGenerated="true"/>
|
|
63
|
+
<field name="customerId" type="UUID"/>
|
|
64
|
+
<field name="items" type="String"/>
|
|
65
|
+
<field name="shippingAddress" type="String"/>
|
|
66
|
+
<field name="placedAt" type="DateTime" isGenerated="true"/>
|
|
67
|
+
</event>
|
|
68
|
+
</state-change-slice>'
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
### Automatic Behavior
|
|
72
|
+
|
|
73
|
+
1. **Positioning**: Places slice at end, or use \`after="Slice Name"\` or \`before="Slice Name"\`
|
|
74
|
+
2. **Field mappings**: Automatically inferred by matching field names between Screen → Command and Command → Event
|
|
75
|
+
3. **Flows**: Automatically creates Screen→Command and Command→Event flows
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Automation Slices
|
|
80
|
+
|
|
81
|
+
An automation slice represents a **system-initiated action**:
|
|
82
|
+
|
|
83
|
+
\`\`\`
|
|
84
|
+
ReadModel → Processor → Command → Event
|
|
85
|
+
\`\`\`
|
|
86
|
+
|
|
87
|
+
- **ReadModel**: The state/data the processor needs to make decisions
|
|
88
|
+
- **Processor**: The system component that decides when and how to act
|
|
89
|
+
- **Command**: The intent/request to change state
|
|
90
|
+
- **Event**: The fact that state changed
|
|
91
|
+
|
|
92
|
+
### When to Use
|
|
93
|
+
|
|
94
|
+
Use automation slices when:
|
|
95
|
+
- The system automatically responds to events
|
|
96
|
+
- No direct user interaction triggers the action
|
|
97
|
+
- Examples: "Auto-assign Reviewer", "Send Reminder Email", "Calculate Shipping", "Process Payment"
|
|
98
|
+
|
|
99
|
+
### Command Syntax
|
|
100
|
+
|
|
101
|
+
\`\`\`bash
|
|
102
|
+
eventmodeler create automation-slice --xml '<automation-slice name="Slice Name" [after="Other Slice"]>
|
|
103
|
+
<read-model name="ReadModelName">
|
|
104
|
+
<field name="fieldName" type="Type"/>
|
|
105
|
+
</read-model>
|
|
106
|
+
<processor name="Processor Name"/>
|
|
107
|
+
<command name="CommandName">
|
|
108
|
+
<field name="fieldName" type="Type"/>
|
|
109
|
+
</command>
|
|
110
|
+
<event name="EventName">
|
|
111
|
+
<field name="fieldName" type="Type"/>
|
|
112
|
+
</event>
|
|
113
|
+
</automation-slice>'
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
### Example: Auto-Fulfill Order
|
|
117
|
+
|
|
118
|
+
\`\`\`bash
|
|
119
|
+
eventmodeler create automation-slice --xml '<automation-slice name="Auto Fulfill Order" after="Place Order">
|
|
120
|
+
<read-model name="OrderReadyForFulfillment">
|
|
121
|
+
<field name="orderId" type="UUID"/>
|
|
122
|
+
<field name="isPaid" type="Boolean"/>
|
|
123
|
+
<field name="shippingAddress" type="String"/>
|
|
124
|
+
</read-model>
|
|
125
|
+
<processor name="Order Fulfillment Processor"/>
|
|
126
|
+
<command name="FulfillOrder">
|
|
127
|
+
<field name="orderId" type="UUID"/>
|
|
128
|
+
<field name="warehouseId" type="UUID" isGenerated="true"/>
|
|
129
|
+
</command>
|
|
130
|
+
<event name="OrderFulfilled">
|
|
131
|
+
<field name="orderId" type="UUID"/>
|
|
132
|
+
<field name="warehouseId" type="UUID"/>
|
|
133
|
+
<field name="fulfilledAt" type="DateTime" isGenerated="true"/>
|
|
134
|
+
</event>
|
|
135
|
+
</automation-slice>'
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
### Automatic Behavior
|
|
139
|
+
|
|
140
|
+
1. **Positioning**: Places slice at end, or use \`after="Slice Name"\` or \`before="Slice Name"\`
|
|
141
|
+
2. **Field mappings**: Automatically inferred by matching field names: ReadModel → Command, Command → Event
|
|
142
|
+
3. **Flows**: Automatically creates ReadModel → Processor, Processor → Command, Command → Event
|
|
143
|
+
|
|
144
|
+
### Connecting Trigger Events
|
|
145
|
+
|
|
146
|
+
After creating the automation slice, connect external events to its read model:
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
eventmodeler create flow --from "OrderPlaced" --to "OrderReadyForFulfillment"
|
|
150
|
+
eventmodeler create flow --from "PaymentReceived" --to "OrderReadyForFulfillment"
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
### Automation vs State-View Read Models
|
|
154
|
+
|
|
155
|
+
| Automation ReadModel | State-View ReadModel |
|
|
156
|
+
|---------------------|---------------------|
|
|
157
|
+
| Inside automation slice | Standalone slice |
|
|
158
|
+
| Feeds a Processor | Feeds a Screen |
|
|
159
|
+
| "What the processor needs" | "What the user sees" |
|
|
160
|
+
| Created with automation-slice | Created with state-view-slice |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## State-View Slices
|
|
165
|
+
|
|
166
|
+
A state-view slice represents a **read model** - a projection of event data for querying:
|
|
167
|
+
|
|
168
|
+
\`\`\`
|
|
169
|
+
Read Model (fed by events)
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
### When to Use
|
|
173
|
+
|
|
174
|
+
Use state-view slices when:
|
|
175
|
+
- You need to display data to users
|
|
176
|
+
- A processor needs to query current state
|
|
177
|
+
- You want to aggregate data from multiple events
|
|
178
|
+
- Examples: "Order Summary", "User Dashboard", "Inventory Levels", "Account Balance"
|
|
179
|
+
|
|
180
|
+
### Command Syntax
|
|
181
|
+
|
|
182
|
+
\`\`\`bash
|
|
183
|
+
eventmodeler create state-view-slice --xml '<state-view-slice name="Slice Name" [after="Other Slice"]>
|
|
184
|
+
<read-model name="ReadModelName">
|
|
185
|
+
<field name="fieldName" type="Type"/>
|
|
186
|
+
</read-model>
|
|
187
|
+
</state-view-slice>'
|
|
188
|
+
\`\`\`
|
|
189
|
+
|
|
190
|
+
### Example: Order Summary View
|
|
191
|
+
|
|
192
|
+
\`\`\`bash
|
|
193
|
+
eventmodeler create state-view-slice --xml '<state-view-slice name="View Order Summary" after="Place Order">
|
|
194
|
+
<read-model name="OrderSummary">
|
|
195
|
+
<field name="orderId" type="UUID"/>
|
|
196
|
+
<field name="customerId" type="UUID"/>
|
|
197
|
+
<field name="customerName" type="String"/>
|
|
198
|
+
<field name="status" type="String"/>
|
|
199
|
+
<field name="totalAmount" type="Decimal"/>
|
|
200
|
+
<field name="itemCount" type="Int"/>
|
|
201
|
+
<field name="placedAt" type="DateTime"/>
|
|
202
|
+
<field name="lastUpdatedAt" type="DateTime"/>
|
|
203
|
+
</read-model>
|
|
204
|
+
</state-view-slice>'
|
|
205
|
+
\`\`\`
|
|
206
|
+
|
|
207
|
+
### Connecting Events After Creation
|
|
208
|
+
|
|
209
|
+
The \`create state-view-slice\` command only creates the read model. To complete the picture:
|
|
210
|
+
|
|
211
|
+
1. Create flows from events: \`eventmodeler create flow --from "EventName" --to "ReadModelName"\`
|
|
212
|
+
2. Map fields: \`eventmodeler map fields --flow "EventName→ReadModelName" --xml '...'\`
|
|
213
|
+
3. Verify: \`eventmodeler show completeness "ReadModelName"\`
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Field Types
|
|
218
|
+
|
|
219
|
+
\`UUID\`, \`String\`, \`Int\`, \`Long\`, \`Double\`, \`Decimal\`, \`Boolean\`, \`Date\`, \`DateTime\`, \`Custom\`
|
|
220
|
+
|
|
221
|
+
## Field Attributes
|
|
222
|
+
|
|
223
|
+
- \`isOptional="true"\` - Field may not have a value
|
|
224
|
+
- \`isGenerated="true"\` - System-generated (e.g., IDs, timestamps), not from user input
|
|
225
|
+
- \`isUserInput="true"\` - Entered by the user on the screen
|
|
226
|
+
- \`isList="true"\` - Field is a list/array of the specified type
|
|
227
|
+
|
|
228
|
+
## Working with Lists and Custom Types
|
|
229
|
+
|
|
230
|
+
**List of primitives** - use \`isList="true"\` with any valid type:
|
|
231
|
+
\`\`\`xml
|
|
232
|
+
<field name="tags" type="String" isList="true"/>
|
|
233
|
+
<field name="quantities" type="Int" isList="true"/>
|
|
234
|
+
\`\`\`
|
|
235
|
+
|
|
236
|
+
### Custom Types (Nested Objects)
|
|
237
|
+
|
|
238
|
+
**CRITICAL: Custom fields MUST contain subfields.** The \`type="Custom"\` indicates a nested object structure, and the nested \`<field>\` elements define its properties. A Custom field without subfields is invalid and creates an empty, useless type.
|
|
239
|
+
|
|
240
|
+
**Custom type with nested fields:**
|
|
241
|
+
\`\`\`xml
|
|
242
|
+
<field name="address" type="Custom">
|
|
243
|
+
<field name="street" type="String"/>
|
|
244
|
+
<field name="city" type="String"/>
|
|
245
|
+
<field name="postalCode" type="String"/>
|
|
246
|
+
</field>
|
|
247
|
+
\`\`\`
|
|
248
|
+
|
|
249
|
+
**List of custom objects** - combine \`type="Custom"\` with \`isList="true"\`:
|
|
250
|
+
\`\`\`xml
|
|
251
|
+
<field name="lineItems" type="Custom" isList="true">
|
|
252
|
+
<field name="productId" type="UUID"/>
|
|
253
|
+
<field name="quantity" type="Int"/>
|
|
254
|
+
<field name="unitPrice" type="Decimal"/>
|
|
255
|
+
</field>
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
**Nested custom types** - subfields can themselves be Custom types:
|
|
259
|
+
\`\`\`xml
|
|
260
|
+
<field name="customer" type="Custom">
|
|
261
|
+
<field name="customerId" type="UUID"/>
|
|
262
|
+
<field name="name" type="String"/>
|
|
263
|
+
<field name="billingAddress" type="Custom">
|
|
264
|
+
<field name="street" type="String"/>
|
|
265
|
+
<field name="city" type="String"/>
|
|
266
|
+
<field name="country" type="String"/>
|
|
267
|
+
</field>
|
|
268
|
+
</field>
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
## Common Mistakes
|
|
272
|
+
|
|
273
|
+
- **Creating empty Custom fields**: Custom fields MUST have subfields that define their structure.
|
|
274
|
+
- Wrong: \`<field name="address" type="Custom"/>\`
|
|
275
|
+
- Right: \`<field name="address" type="Custom"><field name="street" type="String"/>...</field>\`
|
|
276
|
+
|
|
277
|
+
- **Using "List" as a field type**: "List" is not a valid type. Use \`isList="true"\` with a valid type instead.
|
|
278
|
+
- Wrong: \`<field name="items" type="List"/>\`
|
|
279
|
+
- Right: \`<field name="items" type="String" isList="true"/>\`
|
|
280
|
+
|
|
281
|
+
- **Using wrong attribute names**: Always use camelCase attributes.
|
|
282
|
+
- Wrong: \`optional="true"\`, \`generated="true"\`, \`list="true"\`, \`user-input="true"\`
|
|
283
|
+
- Right: \`isOptional="true"\`, \`isGenerated="true"\`, \`isList="true"\`, \`isUserInput="true"\`
|
|
284
|
+
|
|
285
|
+
## Workflow
|
|
286
|
+
|
|
287
|
+
1. **Understand the action** - What is the user/system trying to do?
|
|
288
|
+
2. **Design the fields** - What information flows through this slice?
|
|
289
|
+
3. **Propose before creating** - Get approval on the design first
|
|
290
|
+
4. **Create the slice** - Run the command
|
|
291
|
+
5. **Verify** - \`eventmodeler show slice "<name>"\`
|
|
292
|
+
6. **Connect** - Create flows to/from other slices as needed
|
|
293
|
+
|
|
294
|
+
## Best Practices
|
|
295
|
+
|
|
296
|
+
1. **Get approval first** - Propose the design before creating
|
|
297
|
+
2. **Use meaningful names** - Slice name should describe the action ("Place Order" not "Order Slice")
|
|
298
|
+
3. **Include generated fields** - Events should have IDs and timestamps
|
|
299
|
+
4. **Match field names** - Same names enable automatic mapping
|
|
300
|
+
5. **Consider what's user input vs system data** - Mark appropriately
|
|
301
|
+
6. **Name automation read models for their purpose** - "OrderReadyForFulfillment" not "OrderData"
|
|
302
|
+
7. **Name processors descriptively** - "Order Fulfillment Processor" not just "Processor"
|
|
303
|
+
`;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const meta: {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const content = "\n# Exploring Event Models with the CLI\n\nThe `eventmodeler` CLI lets you query and explore event models linked to your project.\n\n## Getting an Overview\n\n**Start here** to understand the model:\n\n```bash\neventmodeler summary\n```\nShows statistics: total slices, events, commands, read models, etc.\n\n```bash\neventmodeler list slices\n```\nLists all slices with their status (created, in-progress, blocked, done). Slices represent vertical features.\n\n```bash\neventmodeler list slices --chapter \"<name>\"\n```\nLists only slices within a specific chapter.\n\n```bash\neventmodeler list chapters\n```\nLists chapters - timeline sections that group slices.\n\n## Listing Elements\n\n```bash\neventmodeler list events # All events in the model\neventmodeler list commands # All commands in the model\neventmodeler list readmodels # All read models\neventmodeler list screens # All screens\neventmodeler list processors # All processors\neventmodeler list scenarios # All scenarios\neventmodeler list aggregates # All aggregates (event groupings)\neventmodeler list actors # All actors (user/system roles)\n```\n\nAll `list` commands support `--format xml|json`.\n\n## Searching\n\n```bash\neventmodeler search \"<term>\"\n```\nSearches across all entity names: slices, events, commands, read models, aggregates, and actors.\n\n## Drilling Into Details\n\n### Show a Slice\n```bash\neventmodeler show slice \"<name>\"\n```\nReturns XML with:\n- All components in the slice (screens, commands, events, read-models, processors)\n- **Inline flow annotations** on each component showing `<flows-from>` and `<flows-to>` connections\n- Fields on each component with types and attributes\n- Information flow (which components connect to which)\n- **Inbound flows**: External elements flowing INTO this slice (with field mappings)\n- **Outbound flows**: Elements in this slice flowing OUT to other slices (with field mappings)\n- Scenarios (Given-When-Then test cases)\n\nThe inbound/outbound flows show cross-slice dependencies - crucial for understanding how a slice integrates with the rest of the system.\n\n**Scenarios are key** - they define the slice's behavior and give it context. A slice's scenarios show:\n- **Given**: What events have already occurred (the starting state)\n- **When**: What command is being executed with what field values\n- **Then**: The expected outcome - either:\n - Events that should be produced\n - An error that should occur\n - A read model assertion (expected state)\n\nExample scenario in slice output:\n```xml\n<scenarios>\n <scenario name=\"Successfully place order\">\n <given>\n <event type=\"CustomerRegistered\">customerId: \"123\"</event>\n </given>\n <when>\n <command type=\"PlaceOrder\">customerId: \"123\", items: [...]</command>\n </when>\n <then>\n <event type=\"OrderPlaced\">orderId: \"456\", customerId: \"123\"</event>\n </then>\n </scenario>\n <scenario name=\"Cannot place order without items\">\n <when>\n <command type=\"PlaceOrder\">customerId: \"123\", items: []</command>\n </when>\n <then>\n <error type=\"ValidationError\">Order must contain at least one item</error>\n </then>\n </scenario>\n</scenarios>\n```\n\nReading scenarios helps understand:\n- What preconditions the slice expects\n- What inputs the command accepts\n- What the happy path looks like\n- What error cases are handled\n\n### Show an Event or Command\n```bash\neventmodeler show event \"<name>\"\neventmodeler show command \"<name>\"\n```\nReturns XML with the element's fields and connections.\n\n### Show Read Models, Screens, and Processors\n```bash\neventmodeler show readmodel \"<name>\"\neventmodeler show screen \"<name>\"\neventmodeler show processor \"<name>\"\n```\nUse these for detailed flow context:\n- `show readmodel`: fields, source events, and who consumes it\n- `show screen`: fields, source read models, and triggered commands\n- `show processor`: fields, source read models, and triggered commands\n\n### Show Aggregate and Scenario\n```bash\neventmodeler show aggregate \"<name>\"\neventmodeler show scenario \"<name>\"\n```\n- `show aggregate`: aggregate ID configuration and contained events\n- `show scenario`: complete Given-When-Then with field values\n\n### Show a Chapter\n```bash\neventmodeler show chapter \"<name>\"\n```\nShows the chapter with:\n- All slices within the chapter\n- **Flow graph**: How slices connect to each other (which events flow to which read models, etc.) with field mappings\n- **External dependencies**:\n - Inbound: Flows from outside the chapter into slices within it\n - Outbound: Flows from slices in this chapter to elements outside it\n\nUse `show chapter` to understand the relationships between slices in a feature area. Use `list slices --chapter` for a simple list without flow details.\n\n### Show an Actor\n```bash\neventmodeler show actor \"<name>\"\n```\nShows the actor and lists all screens associated with it.\n\n## Managing Slice Status\n\nSlices have a status that tracks their progress: `created`, `in-progress`, `blocked`, `done`.\n\n```bash\n# Mark a slice as in progress\neventmodeler mark \"Place Order\" in-progress\n\n# Mark a slice as done\neventmodeler mark \"Place Order\" done\n\n# Mark a slice as blocked\neventmodeler mark \"Place Order\" blocked\n\n# Reset to created\neventmodeler mark \"Place Order\" created\n```\n\nUse `list slices` to see current statuses.\n\n## Checking Information Completeness\n\nInformation completeness tracks whether fields flow correctly between connected elements.\n\n### Check a Specific Element\n```bash\neventmodeler show completeness \"<name>\"\n```\nAuto-detects the element type (command, event, read model, screen, or processor) and shows:\n- Incoming flows to that element\n- Which fields are satisfied (have a source)\n- Which fields are unsatisfied (missing a source)\n\n### Check the Entire Model\n```bash\neventmodeler show model-completeness\n```\nProject-wide view of all information flows:\n- Summary: complete count, incomplete count, total\n- Lists all incomplete flows with their unsatisfied fields\n\n### Check Aggregate ID Fields\n```bash\neventmodeler show aggregate-completeness \"<aggregate-name>\"\n```\nChecks if all events in an aggregate have the aggregate's ID field.\n\n## Using Element IDs Instead of Names\n\nEvery command that accepts an element name also accepts an element ID with the `id:` prefix. This works everywhere: `show`, `add field`, `remove field`, `update field`, `add scenario`, `remove scenario`, `create flow`, `remove flow`, `map fields`, `mark`, `codegen`, and `search`.\n\n```bash\n# Use a full UUID\neventmodeler show event \"id:abc12345-1234-5678-9abc-def012345678\"\n\n# Or just a unique prefix (first 8 chars is usually enough)\neventmodeler show event \"id:abc12345\"\n\n# Works with any command\neventmodeler add field \"id:abc12345\" --xml '<field name=\"status\" type=\"String\"/>'\neventmodeler update field \"id:abc12345\" --field \"status\" --optional true\neventmodeler create flow --from \"id:abc12345\" --to \"OrderSummary\"\n```\n\nThis is essential when multiple elements share the same name (e.g., linked copies). The CLI will tell you when names are ambiguous and show the IDs to use. Find element IDs via `list` commands:\n\n```bash\neventmodeler list events # shows id=\"...\" for each event\neventmodeler list commands # shows id=\"...\" for each command\n```\n\n## Exploration Strategy\n\nWhen exploring an unfamiliar event model:\n\n1. **Get the big picture**: `eventmodeler summary` \u2192 understand scale\n2. **See the features**: `eventmodeler list slices` \u2192 what does this system do?\n3. **Understand organization**: `eventmodeler list chapters` \u2192 how is it structured over time?\n4. **Dive into a slice**: `eventmodeler show slice \"<name>\"` \u2192 how does one feature work?\n5. **Read the scenarios**: They tell you what the slice actually does, its preconditions, and edge cases\n6. **Search for specifics**: `eventmodeler search \"<term>\"` \u2192 find related elements\n\nWhen checking model health:\n1. **Overall completeness**: `eventmodeler show model-completeness` \u2192 any broken flows?\n2. **Specific element**: `eventmodeler show completeness \"<name>\"` \u2192 what's missing here?\n3. **Aggregate consistency**: `eventmodeler show aggregate-completeness \"<name>\"` \u2192 ID fields present?\n\nWhen looking for something specific:\n- Know the feature name? \u2192 `show slice`\n- Know an event name? \u2192 `show event` or `search`\n- Know a read model/screen/processor name? \u2192 `show readmodel` / `show screen` / `show processor`\n- Need scenario details? \u2192 `list scenarios` then `show scenario`\n- Want all events? \u2192 `list events`\n- Checking data flow? \u2192 `show completeness` or `show model-completeness`\n";
|