@crossdelta/platform-sdk 0.3.13 → 0.3.14

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.
@@ -203,6 +203,22 @@ These commands will be executed automatically by the CLI.
203
203
 
204
204
  **CRITICAL:** The service path in the `pf new` command MUST match the service name provided by the user exactly. If the user specifies `services/my-service`, use `services/my-service`. Do NOT modify or prepend paths.
205
205
 
206
+ ### Dependencies (Optional)
207
+
208
+ If the service requires additional npm packages beyond what's scaffolded, list them in a `dependencies` block:
209
+
210
+ ```dependencies
211
+ @pusher/push-notifications-server
212
+ zod
213
+ drizzle-orm
214
+ ```
215
+
216
+ **Format:**
217
+ - One package per line
218
+ - Use exact package names from npm (e.g., `@scope/package-name`)
219
+ - Comments starting with `#` are ignored
220
+ - These packages will be installed using the existing integration system
221
+
206
222
  ### Source Files
207
223
 
208
224
  Format source files with path headers. Paths are relative to the service directory (e.g., `src/index.ts`, NOT `services/my-service/src/index.ts`):
@@ -212,8 +228,173 @@ Format source files with path headers. Paths are relative to the service directo
212
228
  // code here
213
229
  ```
214
230
 
215
- **Important:**
216
- - Always include the `pf new` command to scaffold the service first
217
- - Only generate `src/` files - package.json, Dockerfile, tsconfig.json are created by `pf new`
218
- - Follow the Service Entry Point Pattern above
219
- - Biome lint/format runs automatically after generation – don't worry about minor formatting
231
+ #### `src/handlers/event-name.event.ts`
232
+ ```typescript
233
+ // event handler code
234
+ ```
235
+
236
+ #### `src/use-cases/business-logic.use-case.ts`
237
+ ```typescript
238
+ // business logic code
239
+ ```
240
+
241
+ ### Tests
242
+
243
+ Always generate tests for the service. Use Bun's native test runner (`bun:test`):
244
+
245
+ #### `src/index.test.ts`
246
+ ```typescript
247
+ import { describe, expect, it } from 'bun:test'
248
+
249
+ describe('Service Health Check', () => {
250
+ it('should respond to health check', async () => {
251
+ const app = new Hono()
252
+ app.get('/health', (c) => c.json({ status: 'ok' }))
253
+
254
+ const req = new Request('http://localhost/health')
255
+ const res = await app.fetch(req)
256
+
257
+ expect(res.status).toBe(200)
258
+ const json = await res.json()
259
+ expect(json).toEqual({ status: 'ok' })
260
+ })
261
+ })
262
+ ```
263
+
264
+ #### `src/use-cases/business-logic.use-case.test.ts`
265
+ ```typescript
266
+ import { describe, expect, it, beforeEach, vi } from 'bun:test'
267
+ import { myUseCase } from './business-logic.use-case'
268
+
269
+ describe('BusinessLogic Use Case', () => {
270
+ beforeEach(() => {
271
+ vi.clearAllMocks()
272
+ })
273
+
274
+ it('should handle valid input correctly', async () => {
275
+ const result = await myUseCase({ id: '123' })
276
+ expect(result).toBeDefined()
277
+ })
278
+
279
+ it('should throw error for invalid input', async () => {
280
+ await expect(myUseCase({ id: '' })).rejects.toThrow()
281
+ })
282
+ })
283
+ ```
284
+
285
+ **Test Guidelines:**
286
+ - Write tests ONLY for use cases (NOT event handlers)
287
+ - Event handlers are thin wrappers - the use cases contain the testable logic
288
+ - Use Bun's native test runner: `import { describe, expect, it, beforeEach, afterEach, vi } from 'bun:test'`
289
+ - Use `vi` from `bun:test` for mocking (NOT jest or vitest)
290
+ - Use descriptive test names in English
291
+ - Test both happy paths and error cases
292
+ - Focus on validation and error handling
293
+ - DO NOT mock external libraries (Pusher, AWS SDK, etc.) - they are hard to mock correctly
294
+ - Test environment variable validation and input validation
295
+ - Use `beforeEach`/`afterEach` to clean up mocks: `vi.clearAllMocks()` or `vi.restoreAllMocks()`
296
+
297
+ **Example: Testing validation and error handling**
298
+ ```typescript
299
+ import { describe, expect, it, beforeEach, afterEach } from 'bun:test'
300
+ import { sendNotification } from './send-notification.use-case'
301
+
302
+ describe('Send Notification Use Case', () => {
303
+ const originalEnv = process.env
304
+
305
+ beforeEach(() => {
306
+ process.env = { ...originalEnv }
307
+ })
308
+
309
+ afterEach(() => {
310
+ process.env = originalEnv
311
+ })
312
+
313
+ it('should throw error if orderId is missing', async () => {
314
+ await expect(
315
+ sendNotification({ orderId: '', customerId: 'cust-1' })
316
+ ).rejects.toThrow('Missing orderId')
317
+ })
318
+
319
+ it('should throw error if credentials are not set', async () => {
320
+ delete process.env.PUSHER_BEAMS_INSTANCE_ID
321
+
322
+ await expect(
323
+ sendNotification({ orderId: '123', customerId: 'cust-1' })
324
+ ).rejects.toThrow('Missing Pusher Beams credentials')
325
+ })
326
+ })
327
+ ```
328
+
329
+ ### README
330
+
331
+ Generate a service-specific README documenting:
332
+
333
+ #### `README.md`
334
+ ```markdown
335
+ # Service Name
336
+
337
+ Brief description of what this service does.
338
+
339
+ ## Features
340
+
341
+ - Feature 1
342
+ - Feature 2
343
+
344
+ ## Environment Variables
345
+
346
+ | Variable | Description | Required | Default |
347
+ |----------|-------------|----------|---------|
348
+ | `SERVICE_PORT` | Port the service runs on | No | 4001 |
349
+ | `NATS_URL` | NATS server URL | Yes | - |
350
+
351
+ ## Events
352
+
353
+ ### Publishes
354
+ - `{{projectName}}.service.event` - Description
355
+
356
+ ### Consumes
357
+ - `{{projectName}}.other.event` - Description
358
+
359
+ ## API Endpoints
360
+
361
+ ### `GET /health`
362
+ Health check endpoint.
363
+
364
+ **Response:**
365
+ \`\`\`json
366
+ { "status": "ok" }
367
+ \`\`\`
368
+
369
+ ## Development
370
+
371
+ \`\`\`bash
372
+ bun dev # Start in development mode
373
+ bun test # Run tests
374
+ \`\`\`
375
+ ```
376
+
377
+ **CRITICAL - You MUST generate ALL of these:**
378
+ 1. ✅ `pf new` command (first step - scaffolds the service)
379
+ 2. ✅ Source files (`src/index.ts`, `src/handlers/*.event.ts`, `src/use-cases/*.use-case.ts`)
380
+ 3. ✅ **Test files for EVERY use case** (`src/use-cases/*.test.ts`) - DO NOT test event handlers
381
+ 4. ✅ **Complete README.md** with:
382
+ - Service description & features
383
+ - Environment variables table
384
+ - Events (published/consumed)
385
+ - API endpoints documentation
386
+ - Development commands
387
+
388
+ **DO NOT skip tests or README** - they are REQUIRED, not optional.
389
+
390
+ **Test Strategy:**
391
+ - Focus on validation (input parameters, environment variables)
392
+ - Test error handling and edge cases
393
+ - Keep tests simple - avoid complex mocking of external libraries
394
+ - Test the business logic, not the external API calls
395
+
396
+ **Format notes:**
397
+ - Follow the Service Entry Point Pattern and folder structure above
398
+ - Biome lint/format runs automatically after generation – don't worry about minor formatting
399
+ - **ALL code comments, documentation, and README files MUST be written in English**
400
+ - **Tests MUST be compatible with Bun's test runner** (`bun:test` module with `describe`, `it`, `expect`, `beforeEach`, `afterEach`, `vi` for mocking)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "CLI toolkit for scaffolding Turborepo workspaces with Pulumi infrastructure and Hono/NestJS microservices",
5
5
  "keywords": [
6
6
  "cli",