@nebulit/embuilder 0.1.39
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/README.md +254 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +138 -0
- package/package.json +49 -0
- package/templates/.claude/hooks/QUICKSTART.md +256 -0
- package/templates/.claude/hooks/README.md +533 -0
- package/templates/.claude/hooks/analyze-commit.sh +22 -0
- package/templates/.claude/hooks/analyze-commit.ts +518 -0
- package/templates/.claude/hooks/analyzers/README.md +198 -0
- package/templates/.claude/hooks/analyzers/code-quality-checker.ts +154 -0
- package/templates/.claude/hooks/analyzers/code-quality.md +54 -0
- package/templates/.claude/hooks/analyzers/commit-blocker-example.ts.disabled +110 -0
- package/templates/.claude/hooks/analyzers/commit-policy.md +49 -0
- package/templates/.claude/hooks/analyzers/event-model-validator.md +49 -0
- package/templates/.claude/hooks/analyzers/event-model-validator.ts +169 -0
- package/templates/.claude/hooks/analyzers/example-logger.ts +70 -0
- package/templates/.claude/hooks/analyzers/slice-scope-validator.md +81 -0
- package/templates/.claude/hooks/check-review-result.sh +47 -0
- package/templates/.claude/hooks/prepare-review.sh +34 -0
- package/templates/.claude/hooks/review-agent-prompt.md +42 -0
- package/templates/.claude/hooks/run-review-agent.sh +124 -0
- package/templates/.claude/settings.local.json +37 -0
- package/templates/.claude/skills/help/README.md +84 -0
- package/templates/.claude/skills/help/SKILL.md +393 -0
- package/templates/.claude/skills/help/templates/demo-config.json +6753 -0
- package/templates/.claude/skills/sample-slices/SKILL.md +8 -0
- package/templates/.claude/skills/sample-slices/templates/.slices/Library/addbook/code-slice.json +124 -0
- package/templates/.claude/skills/sample-slices/templates/.slices/Library/addbook/slice.json +255 -0
- package/templates/.claude/skills/sample-slices/templates/.slices/Library/availablebooks/slice.json +107 -0
- package/templates/.claude/skills/sample-slices/templates/.slices/index.json +20 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/additem/slice.json +979 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/archiveitem/slice.json +529 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/cartitems/slice.json +1072 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/cartwithproducts/slice.json +394 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/changedprices/slice.json +88 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/changeinventory/slice.json +264 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/changeprice/slice.json +308 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/clearcart/slice.json +358 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/inventories/slice.json +203 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/publishcart/slice.json +876 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/removeitem/slice.json +560 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/submitcart/slice.json +708 -0
- package/templates/.claude/skills/sample-slices/templates/Cart/submittedcartdata/slice.json +399 -0
- package/templates/.claude/skills/sample-slices/templates/index.json +108 -0
- package/templates/.claude/skills/slice-automation/SKILL.md +49 -0
- package/templates/.claude/skills/slice-state-change/SKILL.md +369 -0
- package/templates/.claude/skills/slice-state-change/templates/AddLocation/AddLocation.test.ts.sample +76 -0
- package/templates/.claude/skills/slice-state-change/templates/AddLocation/AddLocationCommand.ts.sample +84 -0
- package/templates/.claude/skills/slice-state-change/templates/AddLocation/routes.ts.sample +73 -0
- package/templates/.claude/skills/slice-state-change/templates/README.md +46 -0
- package/templates/.claude/skills/slice-state-view/SKILL.md +336 -0
- package/templates/.claude/skills/slice-state-view/templates/Locations/Locations.test.ts.sample +84 -0
- package/templates/.claude/skills/slice-state-view/templates/Locations/LocationsProjection.ts.sample +50 -0
- package/templates/.claude/skills/slice-state-view/templates/Locations/routes.ts.sample +46 -0
- package/templates/.claude/skills/slice-state-view/templates/README.md +109 -0
- package/templates/.claude/skills/slice-state-view/templates/Tables/Tables.test.ts.sample +104 -0
- package/templates/.claude/skills/slice-state-view/templates/Tables/TablesProjection.ts.sample +59 -0
- package/templates/.claude/skills/slice-state-view/templates/Tables/routes.ts.sample +46 -0
- package/templates/.claude/skills/slice-state-view/templates/V2__tables.sql +7 -0
- package/templates/.claude/skills/slice-state-view/templates/V8__locations.sql +7 -0
- package/templates/.claude/skills/test-analyzer/SKILL.md +373 -0
- package/templates/.claude/skills/test-analyzer/examples/specification-format.md +143 -0
- package/templates/.claude/skills/test-analyzer/examples/state-change-example.md +111 -0
- package/templates/.claude/skills/test-analyzer/examples/state-view-example.md +122 -0
- package/templates/AGENTS.md +110 -0
- package/templates/Claude.md +58 -0
- package/templates/README.md +178 -0
- package/templates/backend/.env +9 -0
- package/templates/backend/BACKEND_AUTH_SETUP.md +183 -0
- package/templates/backend/SWAGGER.md +213 -0
- package/templates/backend/eslint.config.mjs +31 -0
- package/templates/backend/flyway.conf +17 -0
- package/templates/backend/package.json +44 -0
- package/templates/backend/prd.json.example +64 -0
- package/templates/backend/public/assets/images/banner.png +0 -0
- package/templates/backend/public/assets/logo.png +0 -0
- package/templates/backend/public/file.svg +4 -0
- package/templates/backend/public/globe.svg +12 -0
- package/templates/backend/public/next.svg +6 -0
- package/templates/backend/public/vercel.svg +3 -0
- package/templates/backend/public/window.svg +5 -0
- package/templates/backend/server.ts +129 -0
- package/templates/backend/setup-env.sh +50 -0
- package/templates/backend/src/common/assertions.ts +6 -0
- package/templates/backend/src/common/db.ts +1 -0
- package/templates/backend/src/common/loadPostgresEventstore.ts +16 -0
- package/templates/backend/src/common/parseEndpoint.ts +51 -0
- package/templates/backend/src/common/replay.ts +9 -0
- package/templates/backend/src/common/routes.ts +19 -0
- package/templates/backend/src/common/testHelpers.ts +53 -0
- package/templates/backend/src/core/readmodel.ts +28 -0
- package/templates/backend/src/core/types.ts +26 -0
- package/templates/backend/src/process/process.ts +53 -0
- package/templates/backend/src/supabase/LoginHandler.ts +36 -0
- package/templates/backend/src/supabase/ProtectedPageProps.ts +21 -0
- package/templates/backend/src/supabase/README.md +171 -0
- package/templates/backend/src/supabase/api.ts +63 -0
- package/templates/backend/src/supabase/authMiddleware.ts +53 -0
- package/templates/backend/src/supabase/component.ts +12 -0
- package/templates/backend/src/supabase/requireUser.ts +72 -0
- package/templates/backend/src/supabase/serverProps.ts +25 -0
- package/templates/backend/src/supabase/staticProps.ts +10 -0
- package/templates/backend/src/swagger.ts +34 -0
- package/templates/backend/src/util/assertions.ts +6 -0
- package/templates/backend/supabase/config.toml +295 -0
- package/templates/backend/supabase/migrations/20260121155918593_catalogentries.sql.sample +23 -0
- package/templates/backend/supabase/seed.sql +1 -0
- package/templates/backend/tsconfig.json +31 -0
- package/templates/frontend/.env.development +3 -0
- package/templates/frontend/AGENTS.md +7 -0
- package/templates/frontend/README.md +73 -0
- package/templates/frontend/components.json +20 -0
- package/templates/frontend/eslint.config.js +26 -0
- package/templates/frontend/index.html +18 -0
- package/templates/frontend/package-lock.json +8347 -0
- package/templates/frontend/package.json +94 -0
- package/templates/frontend/postcss.config.js +6 -0
- package/templates/frontend/public/favicon.ico +0 -0
- package/templates/frontend/public/logo.png +0 -0
- package/templates/frontend/public/placeholder.svg +1 -0
- package/templates/frontend/public/robots.txt +14 -0
- package/templates/frontend/src/App.css +42 -0
- package/templates/frontend/src/App.tsx +47 -0
- package/templates/frontend/src/components/NavLink.tsx +28 -0
- package/templates/frontend/src/components/ProtectedRoute.tsx +24 -0
- package/templates/frontend/src/components/calendar/Calendar.tsx +302 -0
- package/templates/frontend/src/components/layout/DashboardLayout.tsx +21 -0
- package/templates/frontend/src/components/layout/Header.tsx +45 -0
- package/templates/frontend/src/components/layout/Sidebar.tsx +82 -0
- package/templates/frontend/src/components/tables/ReservationTemplates.tsx +189 -0
- package/templates/frontend/src/components/ui/accordion.tsx +52 -0
- package/templates/frontend/src/components/ui/alert-dialog.tsx +104 -0
- package/templates/frontend/src/components/ui/alert.tsx +43 -0
- package/templates/frontend/src/components/ui/aspect-ratio.tsx +5 -0
- package/templates/frontend/src/components/ui/avatar.tsx +38 -0
- package/templates/frontend/src/components/ui/badge.tsx +29 -0
- package/templates/frontend/src/components/ui/breadcrumb.tsx +90 -0
- package/templates/frontend/src/components/ui/button.tsx +47 -0
- package/templates/frontend/src/components/ui/calendar.tsx +54 -0
- package/templates/frontend/src/components/ui/card.tsx +43 -0
- package/templates/frontend/src/components/ui/carousel.tsx +224 -0
- package/templates/frontend/src/components/ui/chart.tsx +303 -0
- package/templates/frontend/src/components/ui/checkbox.tsx +26 -0
- package/templates/frontend/src/components/ui/collapsible.tsx +9 -0
- package/templates/frontend/src/components/ui/command.tsx +132 -0
- package/templates/frontend/src/components/ui/context-menu.tsx +178 -0
- package/templates/frontend/src/components/ui/dialog.tsx +95 -0
- package/templates/frontend/src/components/ui/drawer.tsx +87 -0
- package/templates/frontend/src/components/ui/dropdown-menu.tsx +179 -0
- package/templates/frontend/src/components/ui/form.tsx +129 -0
- package/templates/frontend/src/components/ui/hover-card.tsx +27 -0
- package/templates/frontend/src/components/ui/input-otp.tsx +61 -0
- package/templates/frontend/src/components/ui/input.tsx +22 -0
- package/templates/frontend/src/components/ui/label.tsx +17 -0
- package/templates/frontend/src/components/ui/menubar.tsx +207 -0
- package/templates/frontend/src/components/ui/navigation-menu.tsx +120 -0
- package/templates/frontend/src/components/ui/pagination.tsx +81 -0
- package/templates/frontend/src/components/ui/popover.tsx +29 -0
- package/templates/frontend/src/components/ui/progress.tsx +23 -0
- package/templates/frontend/src/components/ui/radio-group.tsx +36 -0
- package/templates/frontend/src/components/ui/resizable.tsx +37 -0
- package/templates/frontend/src/components/ui/scroll-area.tsx +38 -0
- package/templates/frontend/src/components/ui/select.tsx +143 -0
- package/templates/frontend/src/components/ui/separator.tsx +20 -0
- package/templates/frontend/src/components/ui/sheet.tsx +107 -0
- package/templates/frontend/src/components/ui/sidebar.tsx +637 -0
- package/templates/frontend/src/components/ui/skeleton.tsx +7 -0
- package/templates/frontend/src/components/ui/slider.tsx +23 -0
- package/templates/frontend/src/components/ui/sonner.tsx +27 -0
- package/templates/frontend/src/components/ui/stat-card.tsx +44 -0
- package/templates/frontend/src/components/ui/switch.tsx +27 -0
- package/templates/frontend/src/components/ui/table.tsx +72 -0
- package/templates/frontend/src/components/ui/tabs.tsx +53 -0
- package/templates/frontend/src/components/ui/textarea.tsx +21 -0
- package/templates/frontend/src/components/ui/toast.tsx +111 -0
- package/templates/frontend/src/components/ui/toaster.tsx +24 -0
- package/templates/frontend/src/components/ui/toggle-group.tsx +49 -0
- package/templates/frontend/src/components/ui/toggle.tsx +37 -0
- package/templates/frontend/src/components/ui/tooltip.tsx +28 -0
- package/templates/frontend/src/components/ui/use-toast.ts +3 -0
- package/templates/frontend/src/contexts/AuthContext.tsx +94 -0
- package/templates/frontend/src/contexts/RefreshContext.tsx +236 -0
- package/templates/frontend/src/hooks/api/index.ts +2 -0
- package/templates/frontend/src/hooks/api/useLocations.ts +15 -0
- package/templates/frontend/src/hooks/use-mobile.tsx +19 -0
- package/templates/frontend/src/hooks/use-toast.ts +186 -0
- package/templates/frontend/src/hooks/useApiContext.ts +11 -0
- package/templates/frontend/src/index.css +118 -0
- package/templates/frontend/src/integrations/supabase/client.ts +9 -0
- package/templates/frontend/src/lib/api-client.ts +136 -0
- package/templates/frontend/src/lib/api.ts +1028 -0
- package/templates/frontend/src/lib/utils.ts +6 -0
- package/templates/frontend/src/main.tsx +5 -0
- package/templates/frontend/src/pages/Auth.tsx +408 -0
- package/templates/frontend/src/pages/Dashboard.tsx +168 -0
- package/templates/frontend/src/pages/Menus.tsx +224 -0
- package/templates/frontend/src/pages/NotFound.tsx +24 -0
- package/templates/frontend/src/pages/Register.tsx +285 -0
- package/templates/frontend/src/test/example.test.ts +0 -0
- package/templates/frontend/src/test/setup.ts +15 -0
- package/templates/frontend/src/types/index.ts +8 -0
- package/templates/frontend/src/vite-env.d.ts +1 -0
- package/templates/frontend/tailwind.config.ts +101 -0
- package/templates/frontend/tsconfig.app.json +31 -0
- package/templates/frontend/tsconfig.json +16 -0
- package/templates/frontend/tsconfig.node.json +22 -0
- package/templates/frontend/vite.config.ts +21 -0
- package/templates/frontend/vitest.config.ts +16 -0
- package/templates/init.sh +1 -0
- package/templates/prompt.md +139 -0
- package/templates/ralph.sh +120 -0
- package/templates/server.mjs +505 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: help
|
|
3
|
+
description: Step-by-step guide for getting started with event-driven development
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Event-Driven Development - Getting Started Guide
|
|
7
|
+
|
|
8
|
+
Welcome! This guide will walk you through the complete workflow from installation to running your first event-driven application.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
This framework helps you build event-sourced applications using event modeling. The workflow is:
|
|
13
|
+
|
|
14
|
+
1. Install the tooling (already done if you can run this skill!)
|
|
15
|
+
2. Model your domain in an event modeling tool (like Miro)
|
|
16
|
+
3. Export your model as config.json
|
|
17
|
+
4. Generate skeleton application
|
|
18
|
+
5. Run your application
|
|
19
|
+
|
|
20
|
+
Let me guide you through each step:
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 1: Installation
|
|
25
|
+
|
|
26
|
+
If you're reading this, congratulations - the skills are already installed and working!
|
|
27
|
+
|
|
28
|
+
The following skills are now available:
|
|
29
|
+
- `/fetch-config` - Receive event model from modeling tool
|
|
30
|
+
- `/gen-skeleton` - Generate backend skeleton
|
|
31
|
+
- `/gen-state-change` - Generate command handlers
|
|
32
|
+
- `/gen-state-view` - Generate read models
|
|
33
|
+
- `/gen-automation` - Generate automation processors
|
|
34
|
+
- `/gen-ui` - Generate React UI with shadcn/ui
|
|
35
|
+
- `/help` - This guide
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step 2: Create Your Event Model
|
|
40
|
+
|
|
41
|
+
You have two options:
|
|
42
|
+
|
|
43
|
+
### Option A: Use a Demo Config (Quickstart)
|
|
44
|
+
|
|
45
|
+
If you want to try the workflow without modeling, use our demo config:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cp .claude/skills/help/templates/demo-config.json config.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This includes a simple shopping cart domain with:
|
|
52
|
+
- Commands: Add Item, Remove Item, Checkout Cart
|
|
53
|
+
- Events: Cart Created, Item Added, Item Removed, Cart Checked Out
|
|
54
|
+
- Read Models: Active Carts, Cart History
|
|
55
|
+
|
|
56
|
+
### Option B: Model Your Own Domain
|
|
57
|
+
|
|
58
|
+
1. **Use an Event Modeling Tool** (recommended: Miro, Mural, or similar)
|
|
59
|
+
- Create your event model with commands, events, aggregates, and read models
|
|
60
|
+
- Follow event modeling notation (orange=commands, blue=events, green=read models, yellow=aggregates)
|
|
61
|
+
|
|
62
|
+
2. **Export to config.json**
|
|
63
|
+
- Most event modeling tools support JSON export
|
|
64
|
+
- Alternatively, use our config receiver:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Start the config receiver server
|
|
68
|
+
/fetch-config
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This starts a server on http://localhost:3001 that waits for your event modeling tool to POST the config.
|
|
72
|
+
|
|
73
|
+
**Expected config.json structure:**
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"slices": [
|
|
77
|
+
{
|
|
78
|
+
"id": "unique-id",
|
|
79
|
+
"title": "Add Item",
|
|
80
|
+
"sliceType": "STATE_CHANGE",
|
|
81
|
+
"aggregate": "Cart",
|
|
82
|
+
"command": { "name": "AddItem", "fields": [...] },
|
|
83
|
+
"events": [{ "name": "ItemAdded", "fields": [...] }],
|
|
84
|
+
"specifications": [...]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Step 3: Generate Skeleton Application
|
|
93
|
+
|
|
94
|
+
Once you have a `config.json` file, generate your application skeleton:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
/gen-skeleton
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
You'll be prompted for:
|
|
101
|
+
- **Application name** - This becomes your project name (e.g., "my-shopping-cart")
|
|
102
|
+
|
|
103
|
+
This generates:
|
|
104
|
+
- Complete TypeScript backend with Express
|
|
105
|
+
- Supabase integration for authentication and database
|
|
106
|
+
- Event store setup
|
|
107
|
+
- Test infrastructure
|
|
108
|
+
- Development scripts
|
|
109
|
+
|
|
110
|
+
**What gets created:**
|
|
111
|
+
```
|
|
112
|
+
your-app/
|
|
113
|
+
├── src/
|
|
114
|
+
│ ├── common/ # Shared utilities (event store, DB, etc.)
|
|
115
|
+
│ ├── core/ # Core types and patterns
|
|
116
|
+
│ ├── slices/ # Your domain slices (generated next)
|
|
117
|
+
│ └── events/ # Event definitions
|
|
118
|
+
├── supabase/ # Database migrations
|
|
119
|
+
├── server.ts # Express server
|
|
120
|
+
├── package.json # Dependencies
|
|
121
|
+
└── .env # Configuration
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
After generation:
|
|
125
|
+
```bash
|
|
126
|
+
npm install # Install dependencies
|
|
127
|
+
npm run build # Verify TypeScript compiles
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Generate State Change Slices (Commands)
|
|
131
|
+
|
|
132
|
+
State change slices handle commands and emit events:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
/gen-state-change
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
This will:
|
|
139
|
+
1. Read your config.json
|
|
140
|
+
2. Show available STATE_CHANGE slices
|
|
141
|
+
3. Let you select which ones to generate
|
|
142
|
+
4. Create command handlers with:
|
|
143
|
+
- Business logic (decide/evolve pattern)
|
|
144
|
+
- API endpoints
|
|
145
|
+
- Tests
|
|
146
|
+
- OpenAPI documentation
|
|
147
|
+
|
|
148
|
+
### Generate State View Slices (Read Models)
|
|
149
|
+
|
|
150
|
+
State view slices build queryable read models from events:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
/gen-state-view
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This creates:
|
|
157
|
+
- Event projections that build read models
|
|
158
|
+
- Query endpoints
|
|
159
|
+
- Database migrations
|
|
160
|
+
- Tests
|
|
161
|
+
|
|
162
|
+
### Generate Automation Slices (Background Jobs)
|
|
163
|
+
|
|
164
|
+
Automation slices run scheduled tasks:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
/gen-automation
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
This creates:
|
|
171
|
+
- Cron-based processors
|
|
172
|
+
- Work queue handlers
|
|
173
|
+
- Automated command firing
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Step 5: Use Ralph to Auto-Implement Slices
|
|
178
|
+
|
|
179
|
+
**Ralph** is an AI agent that automatically implements your slices. Here's how:
|
|
180
|
+
|
|
181
|
+
### Mark Slices for Implementation
|
|
182
|
+
|
|
183
|
+
Edit `.slices/index.json` and change a slice's status to `"Planned"`:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"id": "...",
|
|
188
|
+
"title": "Add Item",
|
|
189
|
+
"status": "Planned", // Change from "Created" to "Planned"
|
|
190
|
+
"folder": "additem"
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Start Ralph Loop
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
./ralph.sh
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Ralph will:
|
|
201
|
+
1. Find the highest priority slice with status "Planned"
|
|
202
|
+
2. Read the specification from `.slices/{folder}/.slice.json`
|
|
203
|
+
3. Implement the slice using event sourcing patterns
|
|
204
|
+
4. Write tests
|
|
205
|
+
5. Run tests and build to verify
|
|
206
|
+
6. Update status to "Done"
|
|
207
|
+
7. Repeat for next planned slice
|
|
208
|
+
|
|
209
|
+
**Ralph monitors:**
|
|
210
|
+
- `.slices/index.json` - Tracks which slices to implement
|
|
211
|
+
- `.slices/{folder}/.slice.json` - Detailed specifications
|
|
212
|
+
- `progress.txt` - Logs each iteration
|
|
213
|
+
- `AGENTS.md` - Learnings for future iterations
|
|
214
|
+
|
|
215
|
+
**Ralph runs until:**
|
|
216
|
+
- All "Planned" slices are "Done" (outputs `<promise>COMPLETE</promise>`)
|
|
217
|
+
- No "Planned" slices found (outputs `<promise>NO_TASKS</promise>`)
|
|
218
|
+
- Max iterations reached (default: 10)
|
|
219
|
+
|
|
220
|
+
You can watch Ralph work:
|
|
221
|
+
```bash
|
|
222
|
+
tail -f progress.txt # Watch progress in real-time
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Step 6: Run Your Application
|
|
228
|
+
|
|
229
|
+
Once slices are implemented, start your app:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npm run dev
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Your application starts on http://localhost:3000 with:
|
|
236
|
+
- API endpoints at `/api/*`
|
|
237
|
+
- Swagger documentation at `/api-docs`
|
|
238
|
+
- Authentication via Supabase
|
|
239
|
+
- Event store in PostgreSQL
|
|
240
|
+
|
|
241
|
+
### Test Your API
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Health check
|
|
245
|
+
curl http://localhost:3000/api/health
|
|
246
|
+
|
|
247
|
+
# Call a command (requires auth)
|
|
248
|
+
curl -X POST http://localhost:3000/api/add-item \
|
|
249
|
+
-H "Content-Type: application/json" \
|
|
250
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
251
|
+
-d '{"cartId": "cart-123", "itemId": "item-456"}'
|
|
252
|
+
|
|
253
|
+
# Query a read model
|
|
254
|
+
curl http://localhost:3000/api/carts \
|
|
255
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Common Workflows
|
|
261
|
+
|
|
262
|
+
### Iterate on Your Model
|
|
263
|
+
|
|
264
|
+
1. Update your event model
|
|
265
|
+
2. Re-export config.json (or restart `/fetch-config`)
|
|
266
|
+
3. Regenerate slices: `/gen-state-change` or `/gen-state-view`
|
|
267
|
+
4. Mark slices as "Planned" in `.slices/index.json`
|
|
268
|
+
5. Run Ralph: `./ralph.sh`
|
|
269
|
+
|
|
270
|
+
### Add a New Slice
|
|
271
|
+
|
|
272
|
+
1. Add slice to config.json
|
|
273
|
+
2. Regenerate: `/gen-state-change` or `/gen-state-view`
|
|
274
|
+
3. Mark as "Planned" in `.slices/index.json`
|
|
275
|
+
4. Run Ralph: `./ralph.sh`
|
|
276
|
+
|
|
277
|
+
### Implement Manually (without Ralph)
|
|
278
|
+
|
|
279
|
+
You can always implement slices manually:
|
|
280
|
+
|
|
281
|
+
1. Read the spec in `.slices/{folder}/.slice.json`
|
|
282
|
+
2. Follow patterns in `CLAUDE.md` and `AGENTS.md`
|
|
283
|
+
3. Implement in `src/slices/{folder}/`
|
|
284
|
+
4. Write tests in `src/slices/{folder}/*.test.ts`
|
|
285
|
+
5. Run `npm run build && npm test`
|
|
286
|
+
6. Update status to "Done" in `.slices/index.json`
|
|
287
|
+
|
|
288
|
+
### Generate UI
|
|
289
|
+
|
|
290
|
+
After backend slices are done:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
/gen-ui
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
This creates a React frontend with:
|
|
297
|
+
- shadcn/ui components
|
|
298
|
+
- Supabase authentication
|
|
299
|
+
- Type-safe API client
|
|
300
|
+
- Tailwind CSS styling
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Architecture Patterns
|
|
305
|
+
|
|
306
|
+
### Event Sourcing
|
|
307
|
+
|
|
308
|
+
Commands don't directly mutate state. Instead:
|
|
309
|
+
|
|
310
|
+
1. **Command** arrives (e.g., "Add Item")
|
|
311
|
+
2. **decide()** function validates and returns events
|
|
312
|
+
3. **Events** are stored in event store (immutable facts)
|
|
313
|
+
4. **evolve()** function rebuilds state from events
|
|
314
|
+
5. **Projections** build read models from event stream
|
|
315
|
+
|
|
316
|
+
### Slice Structure
|
|
317
|
+
|
|
318
|
+
Each slice is self-contained:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
src/slices/AddItem/
|
|
322
|
+
├── AddItemCommand.ts # decide() + evolve() logic
|
|
323
|
+
├── AddItem.test.ts # Given/when/then tests
|
|
324
|
+
├── routes.ts # HTTP endpoint
|
|
325
|
+
└── .slice.json # Specification
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Testing Pattern
|
|
329
|
+
|
|
330
|
+
Tests use given/when/then:
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
given([CartCreated, ItemAdded]) // Precondition events
|
|
334
|
+
.when(AddItem) // Command to test
|
|
335
|
+
.then([ItemAdded]) // Expected events
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Troubleshooting
|
|
341
|
+
|
|
342
|
+
### "config.json not found"
|
|
343
|
+
|
|
344
|
+
Run `/fetch-config` to start the receiver, or create one manually.
|
|
345
|
+
|
|
346
|
+
### "No slices with status Planned"
|
|
347
|
+
|
|
348
|
+
Edit `.slices/index.json` and change a slice's status to `"Planned"`.
|
|
349
|
+
|
|
350
|
+
### "Tests failing"
|
|
351
|
+
|
|
352
|
+
Check `progress.txt` for Ralph's latest attempt. Review test output:
|
|
353
|
+
```bash
|
|
354
|
+
npm test
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### "Build errors"
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
npm run build
|
|
361
|
+
# Fix TypeScript errors shown
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### "Ralph keeps saying NO_TASKS"
|
|
365
|
+
|
|
366
|
+
Ralph only works on slices with status "Planned" (case insensitive).
|
|
367
|
+
Check `.slices/index.json` and ensure at least one slice has:
|
|
368
|
+
```json
|
|
369
|
+
"status": "Planned"
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Next Steps
|
|
375
|
+
|
|
376
|
+
Now you're ready to build event-driven applications! Here are some resources:
|
|
377
|
+
|
|
378
|
+
- **Event Modeling**: Learn more at https://eventmodeling.org
|
|
379
|
+
- **Event Sourcing**: See @event-driven-io/emmett docs
|
|
380
|
+
- **Supabase**: Authentication and database - https://supabase.com/docs
|
|
381
|
+
- **Project Instructions**: Read `CLAUDE.md` for project-specific guidelines
|
|
382
|
+
- **Agent Learnings**: Check `AGENTS.md` for implementation patterns
|
|
383
|
+
|
|
384
|
+
## Need Help?
|
|
385
|
+
|
|
386
|
+
Ask me anything about:
|
|
387
|
+
- Event modeling concepts
|
|
388
|
+
- Slice implementation details
|
|
389
|
+
- Testing strategies
|
|
390
|
+
- Architecture decisions
|
|
391
|
+
- Troubleshooting specific errors
|
|
392
|
+
|
|
393
|
+
Happy event-driven development!
|