@crossdelta/platform-sdk 0.7.21 → 0.8.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/README.md +226 -403
- package/bin/cli.js +195 -182
- package/bin/services/ai/instructions/ai-instructions.md +32 -31
- package/bin/templates/workspace/packages/contracts/README.md.hbs +5 -5
- package/package.json +2 -2
|
@@ -20,31 +20,28 @@ These rules define how AI-generated scaffolded services must be structured.
|
|
|
20
20
|
|
|
21
21
|
**Rule:** Always use **plural namespace** (`orders.`, `users.`, `payments.`) to match JetStream stream subjects (`orders.>`, `users.>`, etc.)
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### 3-Step Workflow
|
|
24
24
|
|
|
25
25
|
**STEP 1: CREATE Contract** (`packages/contracts/src/events/<event-name>.ts`):
|
|
26
26
|
```ts
|
|
27
27
|
import { createContract } from '@crossdelta/cloudevents'
|
|
28
28
|
import { z } from 'zod'
|
|
29
29
|
|
|
30
|
+
export const OrdersCreatedSchema = z.object({
|
|
31
|
+
orderId: z.string(),
|
|
32
|
+
customerId: z.string(),
|
|
33
|
+
total: z.number(),
|
|
34
|
+
})
|
|
35
|
+
|
|
30
36
|
export const OrdersCreatedContract = createContract({
|
|
31
37
|
type: 'orders.created', // plural namespace!
|
|
32
|
-
schema:
|
|
33
|
-
orderId: z.string(),
|
|
34
|
-
customerId: z.string(),
|
|
35
|
-
total: z.number(),
|
|
36
|
-
}),
|
|
38
|
+
schema: OrdersCreatedSchema,
|
|
37
39
|
})
|
|
38
40
|
|
|
39
41
|
export type OrdersCreatedData = z.infer<typeof OrdersCreatedContract.schema>
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
**STEP 2:
|
|
43
|
-
```ts
|
|
44
|
-
export * from './events/orders-created'
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**STEP 3: Create Event Handler** (`src/events/orders-created.event.ts`):
|
|
44
|
+
**STEP 2: Create Event Handler** (`src/events/orders-created.event.ts`):
|
|
48
45
|
```ts
|
|
49
46
|
import { handleEvent } from '@crossdelta/cloudevents'
|
|
50
47
|
import { OrdersCreatedContract, type OrdersCreatedData } from '{{scope}}/contracts'
|
|
@@ -55,7 +52,7 @@ export default handleEvent(OrdersCreatedContract, async (data: OrdersCreatedData
|
|
|
55
52
|
})
|
|
56
53
|
```
|
|
57
54
|
|
|
58
|
-
**STEP
|
|
55
|
+
**STEP 3: Setup Consumer** (`src/index.ts`):
|
|
59
56
|
```ts
|
|
60
57
|
import '@crossdelta/telemetry'
|
|
61
58
|
|
|
@@ -107,9 +104,11 @@ pf new hono-micro services/my-service -y
|
|
|
107
104
|
For Event Consumer services:
|
|
108
105
|
|
|
109
106
|
```post-commands
|
|
110
|
-
pf event
|
|
107
|
+
pf event add <event.type> --service services/my-service
|
|
111
108
|
```
|
|
112
109
|
|
|
110
|
+
**Note:** `pf event add` creates contract, mock, handler, and adds the export to `packages/contracts/src/index.ts`.
|
|
111
|
+
|
|
113
112
|
---
|
|
114
113
|
|
|
115
114
|
# 3. Dependencies Block
|
|
@@ -134,18 +133,13 @@ services/my-service/
|
|
|
134
133
|
│ ├── index.ts # NATS consumer setup
|
|
135
134
|
│ ├── events/
|
|
136
135
|
│ │ └── orders-created.event.ts # Event handler
|
|
137
|
-
│
|
|
138
|
-
│
|
|
139
|
-
│
|
|
140
|
-
│ └── types/
|
|
141
|
-
│ └── orders.ts
|
|
136
|
+
│ └── use-cases/
|
|
137
|
+
│ ├── process-order.use-case.ts
|
|
138
|
+
│ └── process-order.test.ts
|
|
142
139
|
└── README.md
|
|
143
140
|
|
|
144
|
-
packages/contracts/
|
|
145
|
-
|
|
146
|
-
│ ├── events/
|
|
147
|
-
│ │ └── orders-created.ts # Contract
|
|
148
|
-
│ └── index.ts
|
|
141
|
+
packages/contracts/src/events/
|
|
142
|
+
└── orders-created.ts # Contract (export added by CLI)
|
|
149
143
|
```
|
|
150
144
|
|
|
151
145
|
**Event Publisher:**
|
|
@@ -153,14 +147,16 @@ packages/contracts/
|
|
|
153
147
|
services/my-service/
|
|
154
148
|
├── src/
|
|
155
149
|
│ ├── index.ts # REST API + publish()
|
|
156
|
-
│
|
|
157
|
-
│
|
|
158
|
-
│
|
|
159
|
-
│ └── types/
|
|
160
|
-
│ └── orders.ts
|
|
150
|
+
│ └── use-cases/
|
|
151
|
+
│ ├── create-order.use-case.ts
|
|
152
|
+
│ └── create-order.test.ts
|
|
161
153
|
└── README.md
|
|
162
154
|
```
|
|
163
155
|
|
|
156
|
+
**IMPORTANT:** Do NOT create `src/types/` directories. All types come from contracts:
|
|
157
|
+
- `OrdersCreatedData` → import from `@scope/contracts`
|
|
158
|
+
- Custom request/response types → define inline or in use-case files
|
|
159
|
+
|
|
164
160
|
---
|
|
165
161
|
|
|
166
162
|
# 5. Code Style
|
|
@@ -209,9 +205,10 @@ Combines REST endpoints + NATS consumer.
|
|
|
209
205
|
|
|
210
206
|
- Live in `src/use-cases/*.use-case.ts`
|
|
211
207
|
- Pure functions, no framework imports
|
|
212
|
-
- Import types from `
|
|
208
|
+
- Import types from `@scope/contracts`
|
|
213
209
|
- Inject dependencies as parameters (Map, services, etc.)
|
|
214
210
|
- NO manual validation (adapters handle that)
|
|
211
|
+
- **Event handlers:** Always log the event type and a key identifier (e.g., `console.log('📦 Processing order:', data.orderId)`) at the start of the use-case for debugging visibility
|
|
215
212
|
|
|
216
213
|
```ts
|
|
217
214
|
import type { OrdersCreatedData } from '{{scope}}/contracts'
|
|
@@ -220,6 +217,8 @@ export const processOrder = async (
|
|
|
220
217
|
data: OrdersCreatedData,
|
|
221
218
|
orderStore: Map<string, any>
|
|
222
219
|
) => {
|
|
220
|
+
console.log('📦 Processing order:', data.orderId)
|
|
221
|
+
|
|
223
222
|
orderStore.set(data.orderId, { ...data, processedAt: new Date() })
|
|
224
223
|
return { success: true }
|
|
225
224
|
}
|
|
@@ -257,8 +256,10 @@ describe('Process Order', () => {
|
|
|
257
256
|
- Put logic in handlers or index.ts
|
|
258
257
|
- Use `src/handlers/` (use `src/events/`)
|
|
259
258
|
- Insert semicolons
|
|
259
|
+
- Edit `packages/contracts/src/index.ts` directly (CLI handles exports)
|
|
260
260
|
|
|
261
261
|
**DO:**
|
|
262
262
|
- Follow naming convention (plural event types)
|
|
263
|
-
- Create contracts in `packages/contracts
|
|
263
|
+
- Create contracts in `packages/contracts/src/events/`
|
|
264
|
+
- Export schema separately from contract
|
|
264
265
|
- Keep code minimal and clean
|
|
@@ -70,8 +70,8 @@ Contracts are **auto-generated** when you create event handlers:
|
|
|
70
70
|
# 1. Create service with event handler
|
|
71
71
|
pf new hono-micro notifications --ai -d "Sends emails on orders.created events"
|
|
72
72
|
|
|
73
|
-
# 2.
|
|
74
|
-
pf event
|
|
73
|
+
# 2. Add event (creates contract, mock, handler)
|
|
74
|
+
pf event add orders.created --service services/notifications
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
This creates:
|
|
@@ -109,13 +109,13 @@ export type OrdersCreatedData = z.infer<typeof OrdersCreatedContract.schema>
|
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
111
|
# List all available events
|
|
112
|
-
pf event
|
|
112
|
+
pf event list
|
|
113
113
|
|
|
114
114
|
# Publish mock event
|
|
115
|
-
pf event
|
|
115
|
+
pf event publish orders.created
|
|
116
116
|
|
|
117
117
|
# Publish with custom data
|
|
118
|
-
pf event
|
|
118
|
+
pf event publish orders.created --data '{"orderId":"test-123"}'
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
## Guidelines
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossdelta/platform-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Opinionated platform toolkit for event-driven microservices. Scaffold Turborepo workspaces, generate services from natural language, and deploy via Pulumi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"scaffolding",
|