@jaypie/mcp 0.2.6 → 0.2.8
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/index.js +1 -1
- package/package.json +1 -1
- package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +34 -2
- package/prompts/Jaypie_CICD_with_GitHub_Actions.md +19 -0
- package/prompts/Jaypie_Fabricator.md +256 -0
- package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +16 -0
- package/prompts/Jaypie_Vocabulary_Package.md +105 -10
- package/prompts/Templates_CDK_Subpackage.md +2 -0
package/dist/index.js
CHANGED
|
@@ -885,7 +885,7 @@ function listLlmProviders() {
|
|
|
885
885
|
};
|
|
886
886
|
}
|
|
887
887
|
|
|
888
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.
|
|
888
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.8"
|
|
889
889
|
;
|
|
890
890
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
891
891
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -153,12 +153,44 @@ Note: API Gateway has a 29-second timeout limit. For longer streaming operations
|
|
|
153
153
|
|
|
154
154
|
### Stack Types
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
Always extend Jaypie stack classes instead of raw CDK classes:
|
|
157
|
+
|
|
158
|
+
| Use | Instead of |
|
|
159
|
+
|-----|------------|
|
|
160
|
+
| `JaypieAppStack` | `cdk.Stack` |
|
|
161
|
+
| `JaypieInfrastructureStack` | `cdk.Stack` |
|
|
162
|
+
|
|
163
|
+
Jaypie stacks automatically configure:
|
|
164
|
+
- `env` with `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION` (required for context providers)
|
|
165
|
+
- Standard tagging
|
|
166
|
+
- Removal policies based on environment
|
|
167
|
+
|
|
157
168
|
```typescript
|
|
158
169
|
new JaypieAppStack(scope, "AppStack"); // Application resources
|
|
159
170
|
new JaypieInfrastructureStack(scope, "InfraStack"); // Infrastructure resources
|
|
160
171
|
```
|
|
161
172
|
|
|
173
|
+
#### Error: Using cdk.Stack with Context Providers
|
|
174
|
+
|
|
175
|
+
Using `cdk.Stack` directly with constructs that need context providers causes:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
ValidationError: Cannot retrieve value from context provider hosted-zone since
|
|
179
|
+
account/region are not specified at the stack level.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Solution:** Change the base class:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Wrong
|
|
186
|
+
import * as cdk from "aws-cdk-lib";
|
|
187
|
+
export class AppStack extends cdk.Stack { ... }
|
|
188
|
+
|
|
189
|
+
// Correct
|
|
190
|
+
import { JaypieAppStack } from "@jaypie/constructs";
|
|
191
|
+
export class AppStack extends JaypieAppStack { ... }
|
|
192
|
+
```
|
|
193
|
+
|
|
162
194
|
### Secrets Management
|
|
163
195
|
|
|
164
196
|
Use `JaypieEnvSecret` for cross-stack secret sharing:
|
|
@@ -314,7 +346,7 @@ const table = new JaypieDynamoDb(this, "MyTable", {
|
|
|
314
346
|
// Connect table to Lambda
|
|
315
347
|
new JaypieLambda(this, "Worker", {
|
|
316
348
|
code: "dist",
|
|
317
|
-
tables: [table], // Grants read/write, sets
|
|
349
|
+
tables: [table], // Grants read/write, sets DYNAMODB_TABLE_NAME
|
|
318
350
|
});
|
|
319
351
|
```
|
|
320
352
|
|
|
@@ -190,6 +190,25 @@ Pass secrets only to steps that need them:
|
|
|
190
190
|
|
|
191
191
|
Never expose secrets in logs or workflow outputs.
|
|
192
192
|
|
|
193
|
+
## CDK Stack Names
|
|
194
|
+
|
|
195
|
+
The `stack-name` parameter in deploy workflows must match the stack ID defined in `packages/cdk/bin/cdk.ts`:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// bin/cdk.ts
|
|
199
|
+
new AppStack(app, "AppStack"); // "AppStack" is the stack ID
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
# deploy-*.yml
|
|
204
|
+
- name: Deploy CDK Stack
|
|
205
|
+
uses: ./.github/actions/cdk-deploy
|
|
206
|
+
with:
|
|
207
|
+
stack-name: AppStack # Must match the stack ID above
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
If you rename the stack ID (e.g., to "MyProjectAppStack" for clarity in AWS), update all deploy workflows to match. Mismatched names cause "No stacks match the name(s)" errors.
|
|
211
|
+
|
|
193
212
|
## Integrations
|
|
194
213
|
|
|
195
214
|
### AWS
|
|
@@ -359,3 +359,259 @@ class TenantFabricator {
|
|
|
359
359
|
4. **Seed Flexibility**: Accepts strings, numbers, or UUIDs as seeds
|
|
360
360
|
5. **Hierarchical Generation**: Nested fabricators enable deterministic tree structures for complex data models
|
|
361
361
|
6. **Identity & Naming**: Every fabricator has a unique ID and name for tracking and debugging
|
|
362
|
+
|
|
363
|
+
## EventFabricator: Temporal Event Generation
|
|
364
|
+
|
|
365
|
+
### Overview
|
|
366
|
+
|
|
367
|
+
`EventFabricator` is an abstract base class for generating temporally-distributed events across a year. It builds on `Fabricator` to add:
|
|
368
|
+
- Annual event counts with configurable distribution
|
|
369
|
+
- Temporal templates for hour, day, week, month, and date weighting
|
|
370
|
+
- Timezone-aware hour shifting
|
|
371
|
+
- Derived event system for cascading events
|
|
372
|
+
|
|
373
|
+
### Basic Usage
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import {
|
|
377
|
+
EventFabricator,
|
|
378
|
+
HOURS_BUSINESS,
|
|
379
|
+
DAYS_WEEKDAYS_ONLY,
|
|
380
|
+
type CreateEventParams,
|
|
381
|
+
} from "@jaypie/fabricator";
|
|
382
|
+
|
|
383
|
+
interface SimpleEvent {
|
|
384
|
+
id: string;
|
|
385
|
+
timestamp: Date;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
class SimpleEventFabricator extends EventFabricator<SimpleEvent> {
|
|
389
|
+
protected createEvent({ seed, timestamp }: CreateEventParams): SimpleEvent {
|
|
390
|
+
return { id: seed, timestamp };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const fab = new SimpleEventFabricator({
|
|
395
|
+
seed: "my-events",
|
|
396
|
+
annualCount: 1000,
|
|
397
|
+
template: [HOURS_BUSINESS, DAYS_WEEKDAYS_ONLY],
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
const events = fab.events({ year: 2025 });
|
|
401
|
+
// Returns 1000 events during business hours on weekdays
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Temporal Templates
|
|
405
|
+
|
|
406
|
+
Templates control event distribution. They can be combined:
|
|
407
|
+
|
|
408
|
+
**Hour Templates:**
|
|
409
|
+
- `HOURS_BUSINESS` - 8am-5pm
|
|
410
|
+
- `HOURS_RETAIL` - 10am-8pm
|
|
411
|
+
- `HOURS_EVENING` - 6pm-10pm
|
|
412
|
+
- `HOURS_24_7` - All hours equal
|
|
413
|
+
|
|
414
|
+
**Day Templates:**
|
|
415
|
+
- `DAYS_WEEKDAYS_ONLY` - Mon-Fri only
|
|
416
|
+
- `DAYS_NO_SUNDAY` - All but Sunday
|
|
417
|
+
- `DAYS_NO_MONDAY` - All but Monday
|
|
418
|
+
|
|
419
|
+
**Curve Templates (gradual peaks):**
|
|
420
|
+
- `CURVE_EVENING_PEAK` - Peaks at 7pm
|
|
421
|
+
- `CURVE_ECOMMERCE` - Peaks at 8pm
|
|
422
|
+
- `CURVE_MIDDAY_PEAK` - Peaks at 11am
|
|
423
|
+
|
|
424
|
+
**Spike Templates (sharp peaks):**
|
|
425
|
+
- `SPIKE_MORNING` - 7-8am peak
|
|
426
|
+
- `SPIKE_LUNCH` - 12-1pm peak
|
|
427
|
+
- `SPIKE_EVENING` - 6-7pm peak
|
|
428
|
+
|
|
429
|
+
**Boost/Lull Templates (multipliers):**
|
|
430
|
+
- `BOOST_SUMMER`, `LULL_SUMMER`
|
|
431
|
+
- `BOOST_WINTER`, `LULL_WINTER`
|
|
432
|
+
- `BOOST_WEEKENDS`, `LULL_WEEKENDS`
|
|
433
|
+
- `BOOST_HOLIDAY_SEASON` - Nov-Dec 1.5x
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
const fab = new MyFabricator({
|
|
437
|
+
template: [
|
|
438
|
+
HOURS_BUSINESS,
|
|
439
|
+
DAYS_WEEKDAYS_ONLY,
|
|
440
|
+
BOOST_HOLIDAY_SEASON,
|
|
441
|
+
CURVE_MIDDAY_PEAK,
|
|
442
|
+
],
|
|
443
|
+
});
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Derived Events: Cascading Event Generation
|
|
447
|
+
|
|
448
|
+
### Overview
|
|
449
|
+
|
|
450
|
+
The derived event system allows events to spawn follow-up events based on probabilistic rules. This is ideal for modeling:
|
|
451
|
+
- Financial transactions with voids, refunds, chargebacks
|
|
452
|
+
- Subscription renewals with payment retries
|
|
453
|
+
- Any event chains with cause-and-effect relationships
|
|
454
|
+
|
|
455
|
+
### Configuration
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import {
|
|
459
|
+
EventFabricator,
|
|
460
|
+
CHANCE,
|
|
461
|
+
type DerivedConfig,
|
|
462
|
+
type TimestampedEvent,
|
|
463
|
+
} from "@jaypie/fabricator";
|
|
464
|
+
|
|
465
|
+
interface Transaction extends TimestampedEvent {
|
|
466
|
+
id: string;
|
|
467
|
+
amount: number;
|
|
468
|
+
type: "purchase" | "void" | "refund" | "chargeback";
|
|
469
|
+
parentId?: string;
|
|
470
|
+
timestamp: Date;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const derivedConfig: DerivedConfig<Transaction> = {
|
|
474
|
+
rules: [
|
|
475
|
+
{
|
|
476
|
+
name: "void",
|
|
477
|
+
probability: CHANCE.RARE, // 2.1%
|
|
478
|
+
condition: (parent) => parent.type === "purchase",
|
|
479
|
+
timing: { mode: "same-day" },
|
|
480
|
+
createDerived: ({ parent, seed, timestamp }) => ({
|
|
481
|
+
id: seed,
|
|
482
|
+
type: "void",
|
|
483
|
+
amount: -parent.amount,
|
|
484
|
+
timestamp,
|
|
485
|
+
parentId: parent.id,
|
|
486
|
+
}),
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "refund",
|
|
490
|
+
probability: 0.10, // 10%
|
|
491
|
+
timing: {
|
|
492
|
+
mode: "range",
|
|
493
|
+
delayMin: 1,
|
|
494
|
+
delayMax: 14,
|
|
495
|
+
unit: "days",
|
|
496
|
+
},
|
|
497
|
+
createDerived: ({ parent, seed, timestamp }) => ({
|
|
498
|
+
id: seed,
|
|
499
|
+
type: "refund",
|
|
500
|
+
amount: -parent.amount,
|
|
501
|
+
timestamp,
|
|
502
|
+
parentId: parent.id,
|
|
503
|
+
}),
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
boundaryBehavior: "include", // include | exclude | clamp
|
|
507
|
+
maxDepth: 4, // Prevent infinite chains
|
|
508
|
+
};
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Timing Modes
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
interface DerivedTiming {
|
|
515
|
+
mode: "same-day" | "fixed" | "range" | "recurring";
|
|
516
|
+
delayMin?: number;
|
|
517
|
+
delayMax?: number;
|
|
518
|
+
unit?: "days" | "weeks" | "months" | "hours" | "minutes" | "seconds";
|
|
519
|
+
interval?: number; // For recurring
|
|
520
|
+
maxRecurrences?: number; // For recurring
|
|
521
|
+
until?: Date | "end-of-year";
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
**Examples:**
|
|
526
|
+
- Same day: `{ mode: "same-day" }`
|
|
527
|
+
- Fixed delay: `{ mode: "fixed", delayMin: 7, unit: "days" }`
|
|
528
|
+
- Range: `{ mode: "range", delayMin: 1, delayMax: 14, unit: "days" }`
|
|
529
|
+
- Monthly recurring: `{ mode: "recurring", interval: 1, unit: "months", until: "end-of-year" }`
|
|
530
|
+
|
|
531
|
+
### Nested Derived Events (Chains)
|
|
532
|
+
|
|
533
|
+
Derived events can spawn their own derived events:
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
{
|
|
537
|
+
name: "chargeback",
|
|
538
|
+
probability: CHANCE.RARE,
|
|
539
|
+
timing: { mode: "range", delayMin: 30, delayMax: 90, unit: "days" },
|
|
540
|
+
createDerived: ({ parent, seed, timestamp }) => ({
|
|
541
|
+
id: seed,
|
|
542
|
+
type: "chargeback",
|
|
543
|
+
amount: -parent.amount,
|
|
544
|
+
timestamp,
|
|
545
|
+
parentId: parent.id,
|
|
546
|
+
}),
|
|
547
|
+
derived: [ // Nested rules for chargebacks
|
|
548
|
+
{
|
|
549
|
+
name: "representment",
|
|
550
|
+
probability: 0.70, // 70% of chargebacks
|
|
551
|
+
timing: { mode: "range", delayMin: 7, delayMax: 21, unit: "days" },
|
|
552
|
+
createDerived: ({ parent, seed, timestamp }) => ({
|
|
553
|
+
id: seed,
|
|
554
|
+
type: "representment",
|
|
555
|
+
amount: Math.abs(parent.amount), // Re-charge
|
|
556
|
+
timestamp,
|
|
557
|
+
parentId: parent.id,
|
|
558
|
+
}),
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Using with EventFabricator
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
class TransactionFabricator extends EventFabricator<Transaction> {
|
|
568
|
+
constructor(options = {}) {
|
|
569
|
+
super({
|
|
570
|
+
...options,
|
|
571
|
+
derived: derivedConfig,
|
|
572
|
+
template: [HOURS_BUSINESS, DAYS_WEEKDAYS_ONLY],
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
protected createEvent({ seed, timestamp }: CreateEventParams): Transaction {
|
|
577
|
+
const fab = new Fabricator({ seed });
|
|
578
|
+
return {
|
|
579
|
+
id: seed,
|
|
580
|
+
type: "purchase",
|
|
581
|
+
amount: fab.random({ min: 10, max: 500, currency: true }),
|
|
582
|
+
timestamp,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const fab = new TransactionFabricator({
|
|
588
|
+
seed: "my-business",
|
|
589
|
+
annualCount: 1000,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
// Get all events including derived events
|
|
593
|
+
const events = fab.events({ year: 2025 });
|
|
594
|
+
|
|
595
|
+
// Get events with metadata (parent refs, depth, rule names)
|
|
596
|
+
const eventsWithMeta = fab.eventsWithMeta({ year: 2025 });
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Event Metadata
|
|
600
|
+
|
|
601
|
+
`eventsWithMeta()` returns events with relationship data:
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
interface EventWithDerivedMeta<T> {
|
|
605
|
+
event: T;
|
|
606
|
+
depth: number; // 0 = primary, 1 = first derived, etc.
|
|
607
|
+
parentSeed?: string; // Seed of parent event
|
|
608
|
+
ruleName?: string; // Rule that created this derived event
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Key Properties
|
|
613
|
+
|
|
614
|
+
1. **Deterministic**: Same seed produces same derived event cascade
|
|
615
|
+
2. **Chronological**: All events (primary + derived) sorted by timestamp
|
|
616
|
+
3. **Depth-Limited**: `maxDepth` prevents infinite chains
|
|
617
|
+
4. **Boundary Control**: Events outside target year can be included, excluded, or clamped
|
|
@@ -1115,6 +1115,22 @@ The environment must be created in GitHub repository settings before the workflo
|
|
|
1115
1115
|
- Verify the AWS role has permissions to access any Secrets Manager secrets
|
|
1116
1116
|
- Review CloudFormation events in the AWS Console for specific errors
|
|
1117
1117
|
|
|
1118
|
+
### Error: "Cannot retrieve value from context provider hosted-zone"
|
|
1119
|
+
|
|
1120
|
+
Stacks using context providers must extend `JaypieAppStack`, not `cdk.Stack`:
|
|
1121
|
+
|
|
1122
|
+
```typescript
|
|
1123
|
+
// Wrong
|
|
1124
|
+
import * as cdk from "aws-cdk-lib";
|
|
1125
|
+
export class AppStack extends cdk.Stack { ... }
|
|
1126
|
+
|
|
1127
|
+
// Correct
|
|
1128
|
+
import { JaypieAppStack } from "@jaypie/constructs";
|
|
1129
|
+
export class AppStack extends JaypieAppStack { ... }
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
`JaypieAppStack` automatically sets `env` with `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION`.
|
|
1133
|
+
|
|
1118
1134
|
### Variables Not Being Applied
|
|
1119
1135
|
|
|
1120
1136
|
- Composite actions cannot access `vars.*` directly
|
|
@@ -162,6 +162,7 @@ Context callbacks connect to adapter registration:
|
|
|
162
162
|
| `String` | `"string"`, `""` | String coercion |
|
|
163
163
|
| `Number` | `"number"` | Number coercion |
|
|
164
164
|
| `Boolean` | `"boolean"` | Boolean coercion |
|
|
165
|
+
| `Date` | `DateType` | Date coercion (ISO strings, timestamps) |
|
|
165
166
|
| `Array` | `"array"`, `[]` | Array coercion |
|
|
166
167
|
| `Object` | `"object"`, `{}` | Object coercion |
|
|
167
168
|
| `[String]` | `[""]` | Typed array of strings |
|
|
@@ -171,6 +172,7 @@ Context callbacks connect to adapter registration:
|
|
|
171
172
|
| `/regex/` | - | String with regex validation |
|
|
172
173
|
| `["a", "b"]` | - | Validated string (must match) |
|
|
173
174
|
| `[1, 2, 3]` | - | Validated number (must match) |
|
|
175
|
+
| `StatusType` | - | Validated status ("pending", "processing", etc.) |
|
|
174
176
|
|
|
175
177
|
### Coercion Examples
|
|
176
178
|
|
|
@@ -201,6 +203,14 @@ coerce([1, 2], [String]); // → ["1", "2"]
|
|
|
201
203
|
coerce({ value: "42" }, Number); // → 42
|
|
202
204
|
coerce(["true"], Boolean); // → true
|
|
203
205
|
coerce('{"value": 5}', Number); // → 5
|
|
206
|
+
|
|
207
|
+
// Date coercion
|
|
208
|
+
import { coerceToDate, coerceFromDate } from "@jaypie/vocabulary";
|
|
209
|
+
|
|
210
|
+
coerceToDate("2026-01-15T10:30:00Z"); // → Date object
|
|
211
|
+
coerceToDate(1736942400000); // → Date from timestamp
|
|
212
|
+
coerceFromDate(new Date(), String); // → ISO string
|
|
213
|
+
coerceFromDate(new Date(), Number); // → Unix timestamp (ms)
|
|
204
214
|
```
|
|
205
215
|
|
|
206
216
|
### RegExp Type Shorthand
|
|
@@ -236,6 +246,30 @@ input: {
|
|
|
236
246
|
}
|
|
237
247
|
```
|
|
238
248
|
|
|
249
|
+
### StatusType
|
|
250
|
+
|
|
251
|
+
A predefined validated string type for common status values:
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { StatusType, isStatus, STATUS_VALUES } from "@jaypie/vocabulary";
|
|
255
|
+
|
|
256
|
+
// StatusType is: ["canceled", "complete", "error", "pending", "processing", "queued", "sending"]
|
|
257
|
+
|
|
258
|
+
const handler = serviceHandler({
|
|
259
|
+
input: {
|
|
260
|
+
status: { type: StatusType, default: "pending" },
|
|
261
|
+
},
|
|
262
|
+
service: ({ status }) => status,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
await handler({ status: "processing" }); // ✓
|
|
266
|
+
await handler({ status: "invalid" }); // ✗ BadRequestError
|
|
267
|
+
|
|
268
|
+
// Type guard
|
|
269
|
+
isStatus("pending"); // → true
|
|
270
|
+
isStatus("unknown"); // → false
|
|
271
|
+
```
|
|
272
|
+
|
|
239
273
|
## Entity Types
|
|
240
274
|
|
|
241
275
|
The vocabulary provides standard entity types for consistent data modeling:
|
|
@@ -302,6 +336,40 @@ progress?:
|
|
|
302
336
|
nextPercentageCheckpoint?: Number
|
|
303
337
|
```
|
|
304
338
|
|
|
339
|
+
### BaseEntity Utilities
|
|
340
|
+
|
|
341
|
+
Field constants and utility functions for working with entities:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import {
|
|
345
|
+
// Field name constants
|
|
346
|
+
BASE_ENTITY_FIELDS, // All field names as constants
|
|
347
|
+
BASE_ENTITY_REQUIRED_FIELDS, // ["createdAt", "id", "model", "updatedAt"]
|
|
348
|
+
BASE_ENTITY_AUTO_FIELDS, // ["createdAt", "history", "id", "updatedAt"]
|
|
349
|
+
BASE_ENTITY_TIMESTAMP_FIELDS, // ["archivedAt", "createdAt", "deletedAt", "updatedAt"]
|
|
350
|
+
|
|
351
|
+
// Type guards
|
|
352
|
+
isBaseEntity, // Check if value is a complete BaseEntity
|
|
353
|
+
hasBaseEntityShape, // Check if value has minimum shape (id + model)
|
|
354
|
+
|
|
355
|
+
// Field helpers
|
|
356
|
+
isAutoField, // Check if field is auto-generated
|
|
357
|
+
isTimestampField, // Check if field is a timestamp
|
|
358
|
+
|
|
359
|
+
// Utilities
|
|
360
|
+
createBaseEntityInput, // Create minimal input with required model
|
|
361
|
+
pickBaseEntityFields, // Extract only BaseEntity fields from object
|
|
362
|
+
} from "@jaypie/vocabulary";
|
|
363
|
+
|
|
364
|
+
// Example: Check if a field should be auto-generated
|
|
365
|
+
isAutoField("id"); // → true
|
|
366
|
+
isAutoField("name"); // → false
|
|
367
|
+
|
|
368
|
+
// Example: Extract BaseEntity fields from mixed object
|
|
369
|
+
const mixed = { id: "123", model: "record", customField: "value" };
|
|
370
|
+
pickBaseEntityFields(mixed); // → { id: "123", model: "record" }
|
|
371
|
+
```
|
|
372
|
+
|
|
305
373
|
## TypeScript Types
|
|
306
374
|
|
|
307
375
|
```typescript
|
|
@@ -315,20 +383,22 @@ import type {
|
|
|
315
383
|
Job,
|
|
316
384
|
MessageEntity,
|
|
317
385
|
Progress,
|
|
386
|
+
Status,
|
|
318
387
|
|
|
319
388
|
// Message types
|
|
320
389
|
Message,
|
|
321
390
|
MessageLevel,
|
|
322
391
|
|
|
323
392
|
// Coercion types
|
|
393
|
+
ArrayElementType,
|
|
324
394
|
CoercionType,
|
|
325
|
-
ScalarType,
|
|
326
395
|
CompositeType,
|
|
396
|
+
DateCoercionType,
|
|
397
|
+
RegExpType,
|
|
398
|
+
ScalarType,
|
|
327
399
|
TypedArrayType,
|
|
328
|
-
ValidatedStringType,
|
|
329
400
|
ValidatedNumberType,
|
|
330
|
-
|
|
331
|
-
ArrayElementType,
|
|
401
|
+
ValidatedStringType,
|
|
332
402
|
|
|
333
403
|
// Service handler types
|
|
334
404
|
InputFieldDefinition,
|
|
@@ -358,6 +428,20 @@ interface Message {
|
|
|
358
428
|
### Main Export (`@jaypie/vocabulary`)
|
|
359
429
|
|
|
360
430
|
```typescript
|
|
431
|
+
// BaseEntity utilities
|
|
432
|
+
export {
|
|
433
|
+
BASE_ENTITY_AUTO_FIELDS,
|
|
434
|
+
BASE_ENTITY_FIELDS,
|
|
435
|
+
BASE_ENTITY_REQUIRED_FIELDS,
|
|
436
|
+
BASE_ENTITY_TIMESTAMP_FIELDS,
|
|
437
|
+
createBaseEntityInput,
|
|
438
|
+
hasBaseEntityShape,
|
|
439
|
+
isAutoField,
|
|
440
|
+
isBaseEntity,
|
|
441
|
+
isTimestampField,
|
|
442
|
+
pickBaseEntityFields,
|
|
443
|
+
} from "./base-entity.js";
|
|
444
|
+
|
|
361
445
|
// Coercion functions
|
|
362
446
|
export {
|
|
363
447
|
coerce,
|
|
@@ -370,17 +454,28 @@ export {
|
|
|
370
454
|
coerceToString,
|
|
371
455
|
} from "./coerce.js";
|
|
372
456
|
|
|
457
|
+
// Date coercion
|
|
458
|
+
export {
|
|
459
|
+
coerceFromDate,
|
|
460
|
+
coerceToDate,
|
|
461
|
+
DateType,
|
|
462
|
+
isDateType,
|
|
463
|
+
isValidDate,
|
|
464
|
+
} from "./coerce-date.js";
|
|
465
|
+
|
|
466
|
+
// Status type
|
|
467
|
+
export { isStatus, STATUS_VALUES, StatusType } from "./status.js";
|
|
468
|
+
|
|
373
469
|
// Service Handler
|
|
374
470
|
export { serviceHandler } from "./serviceHandler.js";
|
|
375
471
|
|
|
376
|
-
//
|
|
377
|
-
export * as commander from "./commander/index.js";
|
|
378
|
-
export * as lambda from "./lambda/index.js";
|
|
472
|
+
// LLM adapter (re-exported, no optional deps)
|
|
379
473
|
export * as llm from "./llm/index.js";
|
|
380
|
-
export * as mcp from "./mcp/index.js";
|
|
381
474
|
|
|
382
|
-
//
|
|
383
|
-
|
|
475
|
+
// Note: Other adapters have optional dependencies and must be imported directly:
|
|
476
|
+
// import { registerServiceCommand } from "@jaypie/vocabulary/commander";
|
|
477
|
+
// import { lambdaServiceHandler } from "@jaypie/vocabulary/lambda";
|
|
478
|
+
// import { registerMcpTool } from "@jaypie/vocabulary/mcp";
|
|
384
479
|
|
|
385
480
|
// Version
|
|
386
481
|
export const VOCABULARY_VERSION: string;
|
|
@@ -22,6 +22,8 @@ new InfrastructureStack(app, "InfrastructureStack");
|
|
|
22
22
|
new AppStack(app, "AppStack");
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
> **Important:** The second argument to `new AppStack(app, "AppStack")` is the stack ID used by CloudFormation. This must exactly match the `stack-name` parameter in your GitHub Actions deploy workflows. If you customize this value (e.g., `"MyProjectAppStack"`), update `.github/workflows/deploy-*.yml` accordingly.
|
|
26
|
+
|
|
25
27
|
## lib/cdk-app.ts
|
|
26
28
|
|
|
27
29
|
```typescript
|