@crossdelta/platform-sdk 0.16.0 → 0.16.2
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/bin/cli.js +171 -170
- package/bin/docs/generators/hono-bun.md +73 -2
- package/bin/docs/generators/hono-node.md +70 -0
- package/bin/docs/generators/nest.md +12 -2
- package/bin/docs/generators/service.md +69 -23
- package/bin/templates/hono-microservice/src/config/env.ts.hbs +14 -0
- package/bin/templates/hono-microservice/src/index.ts.hbs +1 -1
- package/bin/templates/workspace/infra/package.json.hbs +1 -1
- package/bin/templates/workspace/packages/contracts/package.json.hbs +1 -1
- package/package.json +1 -1
- package/bin/templates/workspace/.github/copilot-instructions.md.hbs +0 -72
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## 🚨 CRITICAL: AI Generation Rules
|
|
4
4
|
|
|
5
5
|
**DO NOT create from scratch:**
|
|
6
|
+
- ❌ `src/index.ts` - Entry point created by CLI with port configuration
|
|
6
7
|
- ❌ `infra/services/<name>.ts` - Created by CLI with port assignment
|
|
7
8
|
- ❌ `Dockerfile` - Created by CLI
|
|
8
9
|
- ❌ `package.json` - Created by CLI
|
|
@@ -31,9 +32,16 @@ pf new hono-micro services/push-notifications -y
|
|
|
31
32
|
|
|
32
33
|
## Entry Point (src/index.ts)
|
|
33
34
|
|
|
35
|
+
**⚠️ CRITICAL: Import Order**
|
|
36
|
+
1. **Environment validation** (`./config/env`) - Validate env vars before loading any modules
|
|
37
|
+
2. **Telemetry** (`@crossdelta/telemetry`) - Patch modules before they're imported
|
|
38
|
+
3. All other imports follow
|
|
39
|
+
|
|
34
40
|
**REST API:**
|
|
35
41
|
```ts
|
|
42
|
+
import './config/env'
|
|
36
43
|
import '@crossdelta/telemetry'
|
|
44
|
+
|
|
37
45
|
import { Hono } from 'hono'
|
|
38
46
|
|
|
39
47
|
// Replace MY_SERVICE with actual service name in SCREAMING_SNAKE_CASE
|
|
@@ -49,7 +57,9 @@ console.log(`Service running on http://localhost:${port}`)
|
|
|
49
57
|
|
|
50
58
|
**Event Consumer:**
|
|
51
59
|
```ts
|
|
60
|
+
import './config/env'
|
|
52
61
|
import '@crossdelta/telemetry'
|
|
62
|
+
|
|
53
63
|
import { consumeJetStreams } from '@crossdelta/cloudevents'
|
|
54
64
|
import { Hono } from 'hono'
|
|
55
65
|
|
|
@@ -80,7 +90,9 @@ consumeJetStreams({
|
|
|
80
90
|
|
|
81
91
|
**Event Publisher:**
|
|
82
92
|
```ts
|
|
93
|
+
import './config/env'
|
|
83
94
|
import '@crossdelta/telemetry'
|
|
95
|
+
|
|
84
96
|
import { publish } from '@crossdelta/cloudevents'
|
|
85
97
|
import { Hono } from 'hono'
|
|
86
98
|
|
|
@@ -102,9 +114,68 @@ console.log(`Service running on http://localhost:${port}`)
|
|
|
102
114
|
|
|
103
115
|
---
|
|
104
116
|
|
|
105
|
-
## Environment Validation (
|
|
117
|
+
## Environment Validation (src/config/env.ts)
|
|
118
|
+
|
|
119
|
+
**⚠️ REQUIRED: Environment validation must be created for all services**
|
|
120
|
+
|
|
121
|
+
The scaffold automatically creates `src/config/env.ts` with basic validation.
|
|
122
|
+
|
|
123
|
+
**Default generated file:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { z } from 'zod'
|
|
127
|
+
|
|
128
|
+
const envSchema = z.object({
|
|
129
|
+
MY_SERVICE_PORT: z.string().optional(),
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const result = envSchema.safeParse(process.env)
|
|
133
|
+
if (!result.success) {
|
|
134
|
+
console.error('❌ Environment validation failed:')
|
|
135
|
+
console.error(result.error.format())
|
|
136
|
+
process.exit(1)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const env = result.data
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Add required environment variables:**
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { z } from 'zod'
|
|
146
|
+
|
|
147
|
+
const envSchema = z.object({
|
|
148
|
+
// Port is optional (has fallback in index.ts)
|
|
149
|
+
MY_SERVICE_PORT: z.string().optional(),
|
|
150
|
+
|
|
151
|
+
// Add your required env vars here
|
|
152
|
+
DATABASE_URL: z.string().url(),
|
|
153
|
+
API_KEY: z.string().min(1, 'API_KEY is required'),
|
|
154
|
+
REDIS_URL: z.string().url().optional(),
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
const result = envSchema.safeParse(process.env)
|
|
158
|
+
if (!result.success) {
|
|
159
|
+
console.error('❌ Environment validation failed:')
|
|
160
|
+
console.error(result.error.format())
|
|
161
|
+
process.exit(1)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const env = result.data
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Rules:**
|
|
168
|
+
- ✅ Use `safeParse()` + explicit error handling for better error messages
|
|
169
|
+
- ✅ Export validated `env` object for type-safe access
|
|
170
|
+
- ✅ Use Zod v4 syntax (no params on `.email()`, `.url()`, etc.)
|
|
171
|
+
- ✅ Port is always optional (has fallback in index.ts)
|
|
172
|
+
- ❌ DO NOT add PORT to env schema - it's read directly from process.env
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Environment Validation (Optional - Legacy)
|
|
106
177
|
|
|
107
|
-
**For services with required env vars:**
|
|
178
|
+
**For services with required env vars (DEPRECATED - use src/config/env.ts instead):**
|
|
108
179
|
|
|
109
180
|
### 1️⃣ Create `src/config/env.ts`:
|
|
110
181
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## 🚨 CRITICAL: AI Generation Rules
|
|
4
4
|
|
|
5
5
|
**DO NOT generate these files** - they are created by `pf new hono-micro`:
|
|
6
|
+
- ❌ `src/index.ts` - Entry point with port configuration
|
|
6
7
|
- ❌ `infra/services/<name>.ts` - Infrastructure config with assigned port
|
|
7
8
|
- ❌ `Dockerfile` - Container configuration
|
|
8
9
|
- ❌ `package.json` - Dependencies and scripts
|
|
@@ -31,9 +32,16 @@ pf new hono-micro services/push-notifications -y
|
|
|
31
32
|
|
|
32
33
|
## Entry Point (src/index.ts)
|
|
33
34
|
|
|
35
|
+
**⚠️ CRITICAL: Import Order**
|
|
36
|
+
1. **Environment validation** (`./config/env`) - Validate env vars before loading any modules
|
|
37
|
+
2. **Telemetry** (`@crossdelta/telemetry`) - Patch modules before they're imported
|
|
38
|
+
3. All other imports follow
|
|
39
|
+
|
|
34
40
|
**REST API:**
|
|
35
41
|
```ts
|
|
42
|
+
import './config/env'
|
|
36
43
|
import '@crossdelta/telemetry'
|
|
44
|
+
|
|
37
45
|
import { serve } from '@hono/node-server'
|
|
38
46
|
import { Hono } from 'hono'
|
|
39
47
|
|
|
@@ -50,7 +58,9 @@ serve({ fetch: app.fetch, port }, (info) => {
|
|
|
50
58
|
|
|
51
59
|
**Event Consumer:**
|
|
52
60
|
```ts
|
|
61
|
+
import './config/env'
|
|
53
62
|
import '@crossdelta/telemetry'
|
|
63
|
+
|
|
54
64
|
import { consumeJetStreams } from '@crossdelta/cloudevents'
|
|
55
65
|
import { serve } from '@hono/node-server'
|
|
56
66
|
import { Hono } from 'hono'
|
|
@@ -83,7 +93,9 @@ consumeJetStreams({
|
|
|
83
93
|
|
|
84
94
|
**Event Publisher:**
|
|
85
95
|
```ts
|
|
96
|
+
import './config/env'
|
|
86
97
|
import '@crossdelta/telemetry'
|
|
98
|
+
|
|
87
99
|
import { publish } from '@crossdelta/cloudevents'
|
|
88
100
|
import { serve } from '@hono/node-server'
|
|
89
101
|
import { Hono } from 'hono'
|
|
@@ -107,6 +119,64 @@ serve({ fetch: app.fetch, port }, (info) => {
|
|
|
107
119
|
|
|
108
120
|
---
|
|
109
121
|
|
|
122
|
+
## Environment Validation (src/config/env.ts)
|
|
123
|
+
|
|
124
|
+
**⚠️ REQUIRED: Environment validation must be created for all services**
|
|
125
|
+
|
|
126
|
+
The scaffold automatically creates `src/config/env.ts` with basic validation.
|
|
127
|
+
|
|
128
|
+
**Default generated file:**
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { z } from 'zod'
|
|
132
|
+
|
|
133
|
+
const envSchema = z.object({
|
|
134
|
+
MY_SERVICE_PORT: z.string().optional(),
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
const result = envSchema.safeParse(process.env)
|
|
138
|
+
if (!result.success) {
|
|
139
|
+
console.error('❌ Environment validation failed:')
|
|
140
|
+
console.error(result.error.format())
|
|
141
|
+
process.exit(1)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const env = result.data
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Add required environment variables:**
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { z } from 'zod'
|
|
151
|
+
|
|
152
|
+
const envSchema = z.object({
|
|
153
|
+
// Port is optional (has fallback in index.ts)
|
|
154
|
+
MY_SERVICE_PORT: z.string().optional(),
|
|
155
|
+
|
|
156
|
+
// Add your required env vars here
|
|
157
|
+
DATABASE_URL: z.string().url(),
|
|
158
|
+
API_KEY: z.string().min(1, 'API_KEY is required'),
|
|
159
|
+
REDIS_URL: z.string().url().optional(),
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const result = envSchema.safeParse(process.env)
|
|
163
|
+
if (!result.success) {
|
|
164
|
+
console.error('❌ Environment validation failed:')
|
|
165
|
+
console.error(result.error.format())
|
|
166
|
+
process.exit(1)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export const env = result.data
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Rules:**
|
|
173
|
+
- ✅ Use `safeParse()` + explicit error handling for better error messages
|
|
174
|
+
- ✅ Export validated `env` object for type-safe access
|
|
175
|
+
- ✅ Use Zod v4 syntax (no params on `.email()`, `.url()`, etc.)
|
|
176
|
+
- ✅ Port is always optional (has fallback in index.ts)
|
|
177
|
+
- ❌ DO NOT add PORT to env schema - it's read directly from process.env
|
|
178
|
+
|
|
179
|
+
---
|
|
110
180
|
## Environment Validation (Optional)
|
|
111
181
|
|
|
112
182
|
**For services with required env vars:**
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
## 🚨 CRITICAL: AI Generation Rules
|
|
8
8
|
|
|
9
9
|
**DO NOT generate these files** - they are created by `pf new nest-micro`:
|
|
10
|
+
- ❌ `src/main.ts` - Entry point with port configuration
|
|
10
11
|
- ❌ `infra/services/<name>.ts` - Infrastructure config with assigned port
|
|
11
12
|
- ❌ `Dockerfile` - Container configuration
|
|
12
13
|
- ❌ `package.json` - Dependencies and scripts
|
|
@@ -39,7 +40,10 @@
|
|
|
39
40
|
import { z } from 'zod'
|
|
40
41
|
|
|
41
42
|
export const envSchema = z.object({
|
|
42
|
-
|
|
43
|
+
// ❌ WRONG: Don't define service port - it's set by CLI via SERVICE_NAME_PORT
|
|
44
|
+
// PORT: z.string().transform(Number).default('8080'),
|
|
45
|
+
|
|
46
|
+
// ✅ CORRECT: Only define service-specific env vars
|
|
43
47
|
PUSHER_INSTANCE_ID: z.string().min(1),
|
|
44
48
|
PUSHER_SECRET_KEY: z.string().min(1),
|
|
45
49
|
NATS_URL: z.string().url().default('nats://localhost:4222'),
|
|
@@ -48,6 +52,12 @@ export const envSchema = z.object({
|
|
|
48
52
|
export type Env = z.infer<typeof envSchema>
|
|
49
53
|
```
|
|
50
54
|
|
|
55
|
+
**⚠️ CRITICAL: Port Configuration**
|
|
56
|
+
- **DO NOT** define `PORT` or `SERVICE_NAME_PORT` in `env.schema.ts`
|
|
57
|
+
- Service port is automatically set by CLI via `MY_SERVICE_PORT` env variable
|
|
58
|
+
- Read port in `main.ts`: `const port = Number(process.env.MY_SERVICE_PORT) || 8080`
|
|
59
|
+
- Port is assigned during `pf new nest-micro` and stored in `.env.local`
|
|
60
|
+
|
|
51
61
|
```ts
|
|
52
62
|
// src/app.module.ts
|
|
53
63
|
import { Module } from '@nestjs/common'
|
|
@@ -77,7 +87,7 @@ export class MyService {
|
|
|
77
87
|
|
|
78
88
|
doSomething() {
|
|
79
89
|
const instanceId = this.config.get('PUSHER_INSTANCE_ID') // Type-safe!
|
|
80
|
-
const
|
|
90
|
+
const natsUrl = this.config.get('NATS_URL') // string with default
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
```
|
|
@@ -32,12 +32,14 @@ const port = Number(process.env.MY_HONO_SERVICE_PORT) || 8080
|
|
|
32
32
|
- The port is written to `.env.local` (e.g., `MY_SERVICE_PORT=4001`)
|
|
33
33
|
- Service code MUST use the correct env variable name
|
|
34
34
|
- DO NOT change the port in generated files!
|
|
35
|
+
- **DO NOT include port in env schemas** (e.g., Zod schemas, ConfigModule validation)
|
|
35
36
|
|
|
36
37
|
**When generating service code:**
|
|
37
38
|
1. Determine the correct env variable name from service name
|
|
38
39
|
2. Use ONLY that variable: `process.env.MY_SERVICE_PORT`
|
|
39
40
|
3. DO NOT use generic `PORT` - it causes conflicts!
|
|
40
41
|
4. Keep the `|| 8080` fallback for when `.env.local` is missing
|
|
42
|
+
5. **DO NOT add port to env.schema.ts** - it's read directly from process.env
|
|
41
43
|
|
|
42
44
|
---
|
|
43
45
|
|
|
@@ -254,7 +256,11 @@ The exact command depends on the framework - see the framework-specific docs:
|
|
|
254
256
|
5. Health check endpoint
|
|
255
257
|
6. Dockerfile
|
|
256
258
|
|
|
257
|
-
**⚠️ AI MUST NOT generate
|
|
259
|
+
**⚠️ AI MUST NOT generate these files** - They are automatically created by the CLI:
|
|
260
|
+
- ❌ `infra/services/<name>.ts` - CLI creates with correct port assignment
|
|
261
|
+
- ❌ `src/index.ts` (Hono) or `src/main.ts` (NestJS) - CLI creates with correct entry point
|
|
262
|
+
- ❌ `package.json` - CLI creates with correct dependencies
|
|
263
|
+
- ❌ `Dockerfile` - CLI creates with correct runtime
|
|
258
264
|
|
|
259
265
|
---
|
|
260
266
|
|
|
@@ -382,6 +388,8 @@ pf event add orders.created --service services/my-service
|
|
|
382
388
|
@pusher/push-notifications-server
|
|
383
389
|
```
|
|
384
390
|
|
|
391
|
+
> **Note:** When using external packages, always check the official documentation for the current API. Example: `@pusher/push-notifications-server` - check [npmjs.com](https://www.npmjs.com/package/@pusher/push-notifications-server) for latest usage patterns and avoid deprecated methods.
|
|
392
|
+
|
|
385
393
|
---
|
|
386
394
|
|
|
387
395
|
## 🚨 CRITICAL: Schema Fields Consistency
|
|
@@ -425,40 +433,68 @@ export const OrdersCreatedSchema = z.object({
|
|
|
425
433
|
|
|
426
434
|
## Naming Convention
|
|
427
435
|
|
|
428
|
-
|
|
436
|
+
**🚨 CRITICAL: Singular vs. Plural Architecture Rule**
|
|
429
437
|
|
|
430
438
|
| Component | Format | Example | Reason |
|
|
431
439
|
|-----------|--------|---------|--------|
|
|
432
|
-
| **Event Type** | **Singular** | `
|
|
433
|
-
| **
|
|
440
|
+
| **Event Type** | **Singular** | `customer.created` | Describes a single event |
|
|
441
|
+
| **Event Folder** | **PLURAL** | `customers/` | Domain grouping (matches stream) |
|
|
442
|
+
| **Stream** | **PLURAL** | `CUSTOMERS` | Collection of events for a domain |
|
|
443
|
+
| **Mock Files** | **PLURAL folder** | `customers/created.mock.json` | Must match event folder |
|
|
444
|
+
|
|
445
|
+
**Merksatz:**
|
|
446
|
+
- **Singular** describes an event
|
|
447
|
+
- **Plural** describes a domain
|
|
434
448
|
|
|
435
|
-
|
|
449
|
+
### File Structure Example
|
|
450
|
+
|
|
451
|
+
```
|
|
452
|
+
packages/contracts/src/events/
|
|
453
|
+
├── customers/ ✅ PLURAL (domain)
|
|
454
|
+
│ ├── created.ts (customer.created event)
|
|
455
|
+
│ ├── created.mock.json ✅ PLURAL folder
|
|
456
|
+
│ └── updated.ts (customer.updated event)
|
|
457
|
+
└── orders/ ✅ PLURAL (domain)
|
|
458
|
+
├── created.ts (order.created event)
|
|
459
|
+
└── created.mock.json ✅ PLURAL folder
|
|
460
|
+
|
|
461
|
+
// ❌ WRONG - Mixed singular/plural:
|
|
462
|
+
packages/contracts/src/events/
|
|
463
|
+
├── customers/created.ts ✅ PLURAL
|
|
464
|
+
└── customer/created.mock.json ❌ SINGULAR - causes inconsistency!
|
|
465
|
+
```
|
|
436
466
|
|
|
437
|
-
### Examples
|
|
467
|
+
### Contract Examples
|
|
438
468
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
|
442
|
-
|
|
469
|
+
### Contract Examples
|
|
470
|
+
|
|
471
|
+
| Event Type | Contract | Folder | Stream |
|
|
472
|
+
|------------|----------|--------|--------|
|
|
473
|
+
| `customer.created` | `CustomerCreatedContract` | `customers/` | `CUSTOMERS` ✅ |
|
|
474
|
+
| `order.created` | `OrderCreatedContract` | `orders/` | `ORDERS` ✅ |
|
|
475
|
+
| `domain.created` | `DomainCreatedContract` | `domains/` | `DOMAINS` ✅ |
|
|
443
476
|
|
|
444
477
|
```typescript
|
|
445
478
|
// ✅ CORRECT
|
|
446
|
-
export const
|
|
447
|
-
type: '
|
|
448
|
-
channel: { stream: '
|
|
449
|
-
schema:
|
|
479
|
+
export const CustomerCreatedContract = createContract({
|
|
480
|
+
type: 'customer.created', // Singular event
|
|
481
|
+
channel: { stream: 'CUSTOMERS' }, // Plural stream
|
|
482
|
+
schema: CustomerCreatedSchema,
|
|
450
483
|
})
|
|
451
484
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
485
|
+
// Folder: packages/contracts/src/events/customers/created.ts ✅ PLURAL
|
|
486
|
+
// Mock: packages/contracts/src/events/customers/created.mock.json ✅ PLURAL
|
|
487
|
+
|
|
488
|
+
// ❌ WRONG - Singular stream
|
|
489
|
+
export const CustomerCreatedContract = createContract({
|
|
490
|
+
type: 'customer.created',
|
|
491
|
+
channel: { stream: 'CUSTOMER' }, // ❌ Must be CUSTOMERS (plural!)
|
|
492
|
+
schema: CustomerCreatedSchema,
|
|
456
493
|
})
|
|
457
494
|
|
|
458
|
-
// ❌ WRONG
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
channel: { stream: 'DOMAIN' }, // ❌ Must be DOMAINS (plural!)
|
|
495
|
+
// ❌ WRONG - Mixed folders
|
|
496
|
+
// Folder: packages/contracts/src/events/customers/created.ts ✅
|
|
497
|
+
// Mock: packages/contracts/src/events/customer/created.mock.json ❌ Singular!
|
|
462
498
|
schema: DomainCreatedSchema,
|
|
463
499
|
})
|
|
464
500
|
```
|
|
@@ -509,6 +545,14 @@ consumeJetStreams({
|
|
|
509
545
|
| `post-commands` | Runs after files created (e.g., `pf event add`) |
|
|
510
546
|
| `dependencies` | Extra npm packages (NOT `@crossdelta/*`) |
|
|
511
547
|
|
|
548
|
+
**When adding dependencies:**
|
|
549
|
+
- ✅ Search npm for the latest stable version
|
|
550
|
+
- ✅ Check package README for current API usage
|
|
551
|
+
- ✅ Avoid deprecated APIs - look for deprecation warnings in docs
|
|
552
|
+
- ✅ Prefer packages with TypeScript definitions (`@types/*` or built-in)
|
|
553
|
+
- ✅ Check GitHub for recent activity and TypeScript support
|
|
554
|
+
- ⚠️ If using an unfamiliar package, mention: "Check official docs for latest API"
|
|
555
|
+
|
|
512
556
|
---
|
|
513
557
|
|
|
514
558
|
## Service Types
|
|
@@ -561,4 +605,6 @@ packages/contracts/src/events/
|
|
|
561
605
|
- ✅ NestJS: Business logic in Services + pure helper functions
|
|
562
606
|
- ✅ Log event type and key identifier in handlers
|
|
563
607
|
- ✅ Keep handlers thin - delegate to use-cases/services
|
|
564
|
-
- ✅
|
|
608
|
+
- ✅ Use current, non-deprecated APIs - check package documentation
|
|
609
|
+
- ✅ Prefer TypeScript-first packages with good type definitions
|
|
610
|
+
- ✅ Check npm for latest package versions and breaking changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
const envSchema = z.object({
|
|
4
|
+
{{envKey}}_PORT: z.string().optional(),
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
const result = envSchema.safeParse(process.env)
|
|
8
|
+
if (!result.success) {
|
|
9
|
+
console.error('❌ Environment validation failed:')
|
|
10
|
+
console.error(result.error.format())
|
|
11
|
+
process.exit(1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const env = result.data
|
package/package.json
CHANGED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# Copilot Instructions (Project-Agnostic, TypeScript-Focused)
|
|
2
|
-
|
|
3
|
-
You are assisting in TypeScript-first monorepos using modern TypeScript tooling such as Bun or Node, Turborepo, Hono, NestJS, Zod, event-driven patterns, and Pulumi/Kubernetes infrastructure.
|
|
4
|
-
|
|
5
|
-
Always generate **minimal diffs**, never full rewrites.
|
|
6
|
-
|
|
7
|
-
## General Behavior
|
|
8
|
-
- Produce short, focused, code-first answers.
|
|
9
|
-
- Modify only the necessary parts.
|
|
10
|
-
- Analyze only the opened file unless explicitly asked.
|
|
11
|
-
- Follow existing architecture and naming conventions.
|
|
12
|
-
- Prefer strict typing; avoid `any`.
|
|
13
|
-
- **Reuse existing code**: Before implementing new functionality, search the codebase for existing functions, utilities, or services that can be reused. Avoid duplicating logic.
|
|
14
|
-
|
|
15
|
-
## Code Style
|
|
16
|
-
- Single quotes, no semicolons, 2-space indent, trailing commas.
|
|
17
|
-
- Alphabetically sorted imports; no unused imports.
|
|
18
|
-
- Arrow functions over `function` declarations.
|
|
19
|
-
- Template literals over string concatenation.
|
|
20
|
-
- Prefer pure and functional programming patterns (map/filter/reduce).
|
|
21
|
-
- Avoid mutable state and imperative loops.
|
|
22
|
-
- No decorative section header blocks (no ASCII art separators like `// ─────────────`).
|
|
23
|
-
- Use blank lines to separate logical sections naturally.
|
|
24
|
-
- Organize code: types → helpers → higher-order functions.
|
|
25
|
-
- Use JSDoc for exported functions and complex logic; keep inline comments minimal.
|
|
26
|
-
- Self-documenting code over comments: clear naming, pure functions, obvious control flow.
|
|
27
|
-
|
|
28
|
-
## Validation & Types
|
|
29
|
-
- Use Zod for schemas.
|
|
30
|
-
- Export inferred types using `z.infer`.
|
|
31
|
-
- Do NOT include literal event types inside schemas.
|
|
32
|
-
- Do not duplicate validation logic across layers.
|
|
33
|
-
|
|
34
|
-
## Service & Module Structure
|
|
35
|
-
- Entry points handle wiring (server start, telemetry, routing, consumers).
|
|
36
|
-
- Business logic lives in use-case modules.
|
|
37
|
-
- Event handlers must be thin wrappers around use-cases.
|
|
38
|
-
|
|
39
|
-
## Event Handling
|
|
40
|
-
- Use shared CloudEvents/messaging libraries, not raw clients.
|
|
41
|
-
- Handlers: Schema → inferred type → thin handler → use-case delegation.
|
|
42
|
-
- Handlers named `*.event.ts`.
|
|
43
|
-
|
|
44
|
-
## Infrastructure
|
|
45
|
-
- Use fluent port builders when available.
|
|
46
|
-
- Expose a `/health` endpoint.
|
|
47
|
-
- Avoid legacy containerPort usage.
|
|
48
|
-
|
|
49
|
-
## Testing
|
|
50
|
-
- Test use-cases, not handlers or frameworks.
|
|
51
|
-
- Prefer simple direct tests, no mocks.
|
|
52
|
-
- Validate both error and success paths.
|
|
53
|
-
|
|
54
|
-
## AI Output Format
|
|
55
|
-
- Provide only necessary files.
|
|
56
|
-
- Use relative paths.
|
|
57
|
-
- Keep comments minimal.
|
|
58
|
-
- Do not generate abstractions not already present.
|
|
59
|
-
|
|
60
|
-
## Service-Specific Guidelines
|
|
61
|
-
|
|
62
|
-
When working with specific service types or packages, refer to these detailed guidelines:
|
|
63
|
-
|
|
64
|
-
### Service Generation & Architecture
|
|
65
|
-
- [CLI Service Generator](../packages/platform-sdk/docs/generators/service.md) - AI code generation rules
|
|
66
|
-
|
|
67
|
-
### Key Packages
|
|
68
|
-
- [@crossdelta/cloudevents](../packages/cloudevents/README.md) - Event handling with NATS and CloudEvents
|
|
69
|
-
- [@crossdelta/telemetry](../packages/telemetry/README.md) - OpenTelemetry instrumentation
|
|
70
|
-
- [@crossdelta/infrastructure](../packages/infrastructure/README.md) - Pulumi/K8s configuration
|
|
71
|
-
|
|
72
|
-
**When generating services**: Always check the appropriate guidelines above to ensure correct patterns, especially for event-driven architectures.
|