@pattern-stack/codegen 0.22.0 → 0.24.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/consumer-skills/integration/SKILL.md +11 -3
  3. package/dist/{chunk-XKWOJZZ4.js → chunk-37PILMIT.js} +4 -4
  4. package/dist/{chunk-NR7QQ6ZI.js → chunk-6M6LZEP6.js} +3 -3
  5. package/dist/{chunk-VDL5CJ5C.js → chunk-7B7MMDOJ.js} +54 -1
  6. package/dist/chunk-7B7MMDOJ.js.map +1 -0
  7. package/dist/{chunk-NXHL5YII.js → chunk-7LKAMLV4.js} +4 -4
  8. package/dist/{chunk-6DQEIXYU.js → chunk-CKLM57IE.js} +10 -10
  9. package/dist/chunk-CKLM57IE.js.map +1 -0
  10. package/dist/{chunk-QXVCRA23.js → chunk-ENAR3F5S.js} +9 -4
  11. package/dist/chunk-ENAR3F5S.js.map +1 -0
  12. package/dist/{chunk-FFUDEIFF.js → chunk-HN5HT5WL.js} +2 -2
  13. package/dist/{chunk-6ECCJVYW.js → chunk-K4BQQ2NN.js} +46 -2
  14. package/dist/chunk-K4BQQ2NN.js.map +1 -0
  15. package/dist/{chunk-QFUIE37H.js → chunk-KFXXOFDC.js} +4 -4
  16. package/dist/{chunk-O2A6XHGD.js → chunk-LLDJS7PJ.js} +2 -2
  17. package/dist/{chunk-JOBQ6RUU.js → chunk-LQZESSM3.js} +28 -1
  18. package/dist/chunk-LQZESSM3.js.map +1 -0
  19. package/dist/{chunk-JRQO2IOF.js → chunk-MU54DZCC.js} +27 -1
  20. package/dist/chunk-MU54DZCC.js.map +1 -0
  21. package/dist/{chunk-INO47JXD.js → chunk-PBENHIN2.js} +3 -3
  22. package/dist/{chunk-CLWBNXKF.js → chunk-PLUJEQLU.js} +2 -2
  23. package/dist/{chunk-DB5UXJC3.js → chunk-PNCOUFFI.js} +4 -2
  24. package/dist/chunk-PNCOUFFI.js.map +1 -0
  25. package/dist/{chunk-S7C6TIIF.js → chunk-S5G3HO7N.js} +3 -1
  26. package/dist/chunk-S5G3HO7N.js.map +1 -0
  27. package/dist/{chunk-FNHNSFIJ.js → chunk-WZOPWQN2.js} +2 -2
  28. package/dist/{chunk-TDEHU73T.js → chunk-YIVQ7KLS.js} +46 -5
  29. package/dist/chunk-YIVQ7KLS.js.map +1 -0
  30. package/dist/runtime/subsystems/auth/auth.module.js +2 -2
  31. package/dist/runtime/subsystems/auth/index.js +4 -4
  32. package/dist/runtime/subsystems/bridge/bridge.module.js +7 -7
  33. package/dist/runtime/subsystems/bridge/index.js +7 -7
  34. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +1 -1
  35. package/dist/runtime/subsystems/events/events.module.js +5 -5
  36. package/dist/runtime/subsystems/events/generated/bus.js +3 -3
  37. package/dist/runtime/subsystems/events/generated/index.d.ts +2 -2
  38. package/dist/runtime/subsystems/events/generated/index.js +9 -3
  39. package/dist/runtime/subsystems/events/generated/registry.d.ts +36 -0
  40. package/dist/runtime/subsystems/events/generated/registry.js +1 -1
  41. package/dist/runtime/subsystems/events/generated/schemas.d.ts +109 -1
  42. package/dist/runtime/subsystems/events/generated/schemas.js +7 -1
  43. package/dist/runtime/subsystems/events/generated/types.d.ts +48 -2
  44. package/dist/runtime/subsystems/events/index.js +5 -5
  45. package/dist/runtime/subsystems/index.d.ts +3 -2
  46. package/dist/runtime/subsystems/index.js +29 -25
  47. package/dist/runtime/subsystems/integration/execute-integration.use-case.d.ts +11 -1
  48. package/dist/runtime/subsystems/integration/execute-integration.use-case.js +2 -2
  49. package/dist/runtime/subsystems/integration/index.d.ts +2 -1
  50. package/dist/runtime/subsystems/integration/index.js +10 -8
  51. package/dist/runtime/subsystems/integration/integration-change-emitter.protocol.d.ts +106 -0
  52. package/dist/runtime/subsystems/integration/integration-change-emitter.protocol.js +1 -0
  53. package/dist/runtime/subsystems/integration/integration-change-emitter.protocol.js.map +1 -0
  54. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +2 -2
  55. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +2 -2
  56. package/dist/runtime/subsystems/integration/integration.module.js +4 -4
  57. package/dist/runtime/subsystems/integration/integration.tokens.d.ts +11 -1
  58. package/dist/runtime/subsystems/integration/integration.tokens.js +3 -1
  59. package/dist/runtime/subsystems/jobs/index.js +12 -12
  60. package/dist/runtime/subsystems/jobs/job-worker.d.ts +592 -4
  61. package/dist/runtime/subsystems/jobs/job-worker.js +3 -1
  62. package/dist/runtime/subsystems/jobs/job-worker.module.js +6 -6
  63. package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +19 -0
  64. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +4 -4
  65. package/dist/runtime/subsystems/observability/index.js +3 -3
  66. package/dist/runtime/subsystems/observability/observability.module.js +3 -3
  67. package/dist/runtime/subsystems/observability/observability.service.js +2 -2
  68. package/dist/src/cli/index.js +413 -85
  69. package/dist/src/cli/index.js.map +1 -1
  70. package/dist/src/index.d.ts +490 -1
  71. package/dist/src/index.js +7 -7
  72. package/package.json +1 -1
  73. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +23 -7
  74. package/runtime/subsystems/events/generated/registry.ts +27 -0
  75. package/runtime/subsystems/events/generated/schemas.ts +26 -0
  76. package/runtime/subsystems/events/generated/types.ts +52 -0
  77. package/runtime/subsystems/index.ts +23 -0
  78. package/runtime/subsystems/integration/execute-integration.use-case.ts +69 -1
  79. package/runtime/subsystems/integration/index.ts +6 -0
  80. package/runtime/subsystems/integration/integration-change-emitter.protocol.ts +107 -0
  81. package/runtime/subsystems/integration/integration.tokens.ts +11 -0
  82. package/runtime/subsystems/jobs/job-worker.module.ts +5 -0
  83. package/runtime/subsystems/jobs/job-worker.ts +126 -12
  84. package/runtime/subsystems/jobs/jobs-domain.module.ts +19 -0
  85. package/templates/entity/new/clean-lite-ps/prompt-extension.js +59 -10
  86. package/templates/subsystem/jobs-config/codegen-config-jobs-block.ejs.t +11 -0
  87. package/dist/chunk-6DQEIXYU.js.map +0 -1
  88. package/dist/chunk-6ECCJVYW.js.map +0 -1
  89. package/dist/chunk-DB5UXJC3.js.map +0 -1
  90. package/dist/chunk-JOBQ6RUU.js.map +0 -1
  91. package/dist/chunk-JRQO2IOF.js.map +0 -1
  92. package/dist/chunk-QXVCRA23.js.map +0 -1
  93. package/dist/chunk-S7C6TIIF.js.map +0 -1
  94. package/dist/chunk-TDEHU73T.js.map +0 -1
  95. package/dist/chunk-VDL5CJ5C.js.map +0 -1
  96. /package/dist/{chunk-XKWOJZZ4.js.map → chunk-37PILMIT.js.map} +0 -0
  97. /package/dist/{chunk-NR7QQ6ZI.js.map → chunk-6M6LZEP6.js.map} +0 -0
  98. /package/dist/{chunk-NXHL5YII.js.map → chunk-7LKAMLV4.js.map} +0 -0
  99. /package/dist/{chunk-FFUDEIFF.js.map → chunk-HN5HT5WL.js.map} +0 -0
  100. /package/dist/{chunk-QFUIE37H.js.map → chunk-KFXXOFDC.js.map} +0 -0
  101. /package/dist/{chunk-O2A6XHGD.js.map → chunk-LLDJS7PJ.js.map} +0 -0
  102. /package/dist/{chunk-INO47JXD.js.map → chunk-PBENHIN2.js.map} +0 -0
  103. /package/dist/{chunk-CLWBNXKF.js.map → chunk-PLUJEQLU.js.map} +0 -0
  104. /package/dist/{chunk-FNHNSFIJ.js.map → chunk-WZOPWQN2.js.map} +0 -0
@@ -283,7 +283,7 @@ interface CodegenManifest {
283
283
  };
284
284
  }
285
285
 
286
- declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
286
+ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
287
287
  entity: z.ZodEffects<z.ZodObject<{
288
288
  name: z.ZodString;
289
289
  plural: z.ZodString;
@@ -1528,6 +1528,19 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
1528
1528
  field_mapping?: Record<string, string> | undefined;
1529
1529
  read_only_fields?: string[] | undefined;
1530
1530
  }>>>;
1531
+ sink: z.ZodOptional<z.ZodObject<{
1532
+ delete: z.ZodOptional<z.ZodEnum<["soft", "tombstone", "noop"]>>;
1533
+ exclude_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1534
+ emit_changes: z.ZodOptional<z.ZodBoolean>;
1535
+ }, "strict", z.ZodTypeAny, {
1536
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1537
+ exclude_fields?: string[] | undefined;
1538
+ emit_changes?: boolean | undefined;
1539
+ }, {
1540
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1541
+ exclude_fields?: string[] | undefined;
1542
+ emit_changes?: boolean | undefined;
1543
+ }>>;
1531
1544
  }, "strip", z.ZodTypeAny, {
1532
1545
  electric: boolean;
1533
1546
  providers?: Record<string, {
@@ -1537,6 +1550,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
1537
1550
  field_mapping?: Record<string, string> | undefined;
1538
1551
  read_only_fields?: string[] | undefined;
1539
1552
  }> | undefined;
1553
+ sink?: {
1554
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1555
+ exclude_fields?: string[] | undefined;
1556
+ emit_changes?: boolean | undefined;
1557
+ } | undefined;
1540
1558
  }, {
1541
1559
  electric?: boolean | undefined;
1542
1560
  providers?: Record<string, {
@@ -1546,6 +1564,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
1546
1564
  field_mapping?: Record<string, string> | undefined;
1547
1565
  read_only_fields?: string[] | undefined;
1548
1566
  }> | undefined;
1567
+ sink?: {
1568
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1569
+ exclude_fields?: string[] | undefined;
1570
+ emit_changes?: boolean | undefined;
1571
+ } | undefined;
1549
1572
  }>>;
1550
1573
  detection: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"mode", [z.ZodObject<{
1551
1574
  mode: z.ZodLiteral<"poll">;
@@ -2187,6 +2210,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2187
2210
  field_mapping?: Record<string, string> | undefined;
2188
2211
  read_only_fields?: string[] | undefined;
2189
2212
  }> | undefined;
2213
+ sink?: {
2214
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2215
+ exclude_fields?: string[] | undefined;
2216
+ emit_changes?: boolean | undefined;
2217
+ } | undefined;
2190
2218
  } | undefined;
2191
2219
  detection?: Record<string, {
2192
2220
  poll: {
@@ -2400,6 +2428,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2400
2428
  field_mapping?: Record<string, string> | undefined;
2401
2429
  read_only_fields?: string[] | undefined;
2402
2430
  }> | undefined;
2431
+ sink?: {
2432
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2433
+ exclude_fields?: string[] | undefined;
2434
+ emit_changes?: boolean | undefined;
2435
+ } | undefined;
2403
2436
  } | undefined;
2404
2437
  detection?: Record<string, {
2405
2438
  poll: {
@@ -2613,6 +2646,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2613
2646
  field_mapping?: Record<string, string> | undefined;
2614
2647
  read_only_fields?: string[] | undefined;
2615
2648
  }> | undefined;
2649
+ sink?: {
2650
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2651
+ exclude_fields?: string[] | undefined;
2652
+ emit_changes?: boolean | undefined;
2653
+ } | undefined;
2616
2654
  } | undefined;
2617
2655
  detection?: Record<string, {
2618
2656
  poll: {
@@ -2826,6 +2864,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2826
2864
  field_mapping?: Record<string, string> | undefined;
2827
2865
  read_only_fields?: string[] | undefined;
2828
2866
  }> | undefined;
2867
+ sink?: {
2868
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2869
+ exclude_fields?: string[] | undefined;
2870
+ emit_changes?: boolean | undefined;
2871
+ } | undefined;
2829
2872
  } | undefined;
2830
2873
  detection?: Record<string, {
2831
2874
  poll: {
@@ -3039,6 +3082,11 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3039
3082
  field_mapping?: Record<string, string> | undefined;
3040
3083
  read_only_fields?: string[] | undefined;
3041
3084
  }> | undefined;
3085
+ sink?: {
3086
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3087
+ exclude_fields?: string[] | undefined;
3088
+ emit_changes?: boolean | undefined;
3089
+ } | undefined;
3042
3090
  } | undefined;
3043
3091
  detection?: Record<string, {
3044
3092
  poll: {
@@ -3252,6 +3300,447 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3252
3300
  field_mapping?: Record<string, string> | undefined;
3253
3301
  read_only_fields?: string[] | undefined;
3254
3302
  }> | undefined;
3303
+ sink?: {
3304
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3305
+ exclude_fields?: string[] | undefined;
3306
+ emit_changes?: boolean | undefined;
3307
+ } | undefined;
3308
+ } | undefined;
3309
+ detection?: Record<string, {
3310
+ poll: {
3311
+ cursor: {
3312
+ field: string;
3313
+ kind: "systemModstamp";
3314
+ } | {
3315
+ field: string;
3316
+ kind: "replayId";
3317
+ } | {
3318
+ field: string;
3319
+ kind: "timestamp";
3320
+ } | {
3321
+ field: string;
3322
+ kind: "eventId";
3323
+ } | {
3324
+ field: string;
3325
+ kind: "historyId";
3326
+ } | {
3327
+ field: string;
3328
+ kind: "syncToken";
3329
+ };
3330
+ provenance?: "poll" | "cdc" | undefined;
3331
+ };
3332
+ mode: "poll";
3333
+ mapping: {
3334
+ source: string;
3335
+ target: string;
3336
+ transform?: string | undefined;
3337
+ }[];
3338
+ filters?: {
3339
+ field: string;
3340
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3341
+ value?: unknown;
3342
+ }[] | undefined;
3343
+ } | {
3344
+ webhook: {
3345
+ eventIdField?: string | undefined;
3346
+ };
3347
+ mode: "webhook";
3348
+ mapping: {
3349
+ source: string;
3350
+ target: string;
3351
+ transform?: string | undefined;
3352
+ }[];
3353
+ filters?: {
3354
+ field: string;
3355
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3356
+ value?: unknown;
3357
+ }[] | undefined;
3358
+ }> | undefined;
3359
+ events?: {
3360
+ name: string;
3361
+ queue: string;
3362
+ body: Record<string, string>;
3363
+ generate_handler?: boolean | undefined;
3364
+ }[] | undefined;
3365
+ emits?: string[] | undefined;
3366
+ analytics?: {
3367
+ metrics?: Record<string, {
3368
+ type: "simple";
3369
+ measure: string;
3370
+ filter?: string | undefined;
3371
+ description?: string | undefined;
3372
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3373
+ label?: string | undefined;
3374
+ } | {
3375
+ type: "derived";
3376
+ expr: string;
3377
+ metrics: string[];
3378
+ description?: string | undefined;
3379
+ label?: string | undefined;
3380
+ } | {
3381
+ type: "ratio";
3382
+ numerator: string | {
3383
+ type: "simple";
3384
+ measure: string;
3385
+ filter?: string | undefined;
3386
+ description?: string | undefined;
3387
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3388
+ label?: string | undefined;
3389
+ };
3390
+ denominator: string | {
3391
+ type: "simple";
3392
+ measure: string;
3393
+ filter?: string | undefined;
3394
+ description?: string | undefined;
3395
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3396
+ label?: string | undefined;
3397
+ };
3398
+ filter?: string | undefined;
3399
+ description?: string | undefined;
3400
+ label?: string | undefined;
3401
+ } | {
3402
+ type: "cumulative";
3403
+ measure: string;
3404
+ description?: string | undefined;
3405
+ label?: string | undefined;
3406
+ window?: string | undefined;
3407
+ grain_to_date?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3408
+ }> | undefined;
3409
+ measure_packs?: string[] | undefined;
3410
+ cube_name?: string | undefined;
3411
+ } | undefined;
3412
+ unique_indexes?: {
3413
+ fields: string[];
3414
+ name?: string | undefined;
3415
+ }[] | undefined;
3416
+ }>, {
3417
+ fields: Record<string, {
3418
+ type: "string" | "boolean" | "integer" | "date" | "json" | "decimal" | "uuid" | "datetime" | "entity_ref" | "string_array" | "enum";
3419
+ required: boolean;
3420
+ nullable: boolean;
3421
+ default?: unknown;
3422
+ entity_type?: "primary" | "unique" | "foreign" | "natural" | undefined;
3423
+ min?: number | undefined;
3424
+ max?: number | undefined;
3425
+ unique?: boolean | undefined;
3426
+ measure?: boolean | undefined;
3427
+ analytics_aggregation?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3428
+ agg_time_dimension?: string | undefined;
3429
+ non_additive_dimension?: string | {
3430
+ name: string;
3431
+ window_choice?: string | undefined;
3432
+ window_groupings?: string[] | undefined;
3433
+ } | undefined;
3434
+ dimension?: boolean | undefined;
3435
+ dimension_type?: "categorical" | "time" | undefined;
3436
+ time_granularity?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3437
+ is_partition?: boolean | undefined;
3438
+ entity?: boolean | undefined;
3439
+ entity_role?: string | undefined;
3440
+ analytics_visibility?: "internal" | "agent" | "public" | undefined;
3441
+ semantic_expr?: string | undefined;
3442
+ semantic_label?: string | undefined;
3443
+ ui_label?: string | undefined;
3444
+ ui_type?: "number" | "boolean" | "date" | "json" | "datetime" | "enum" | "text" | "textarea" | "money" | "percentage" | "email" | "url" | "reference" | "badge" | "password" | undefined;
3445
+ ui_importance?: "primary" | "secondary" | "tertiary" | undefined;
3446
+ ui_group?: string | undefined;
3447
+ ui_sortable?: boolean | undefined;
3448
+ ui_filterable?: boolean | undefined;
3449
+ ui_visible?: boolean | undefined;
3450
+ ui_placeholder?: string | undefined;
3451
+ ui_help?: string | undefined;
3452
+ ui_format?: Record<string, unknown> | undefined;
3453
+ ui_key_field?: boolean | undefined;
3454
+ ui_key_field_order?: number | undefined;
3455
+ max_length?: number | undefined;
3456
+ min_length?: number | undefined;
3457
+ choices?: string[] | undefined;
3458
+ choices_from?: string | undefined;
3459
+ allowed_types?: string[] | undefined;
3460
+ index?: boolean | undefined;
3461
+ foreign_key?: string | undefined;
3462
+ }>;
3463
+ entity: {
3464
+ name: string;
3465
+ table: string;
3466
+ plural: string;
3467
+ expose: ("repository" | "rest" | "trpc" | "electric")[];
3468
+ config?: Record<string, unknown> | undefined;
3469
+ folder_structure?: "flat" | "nested" | undefined;
3470
+ file_grouping?: "separate" | "grouped" | undefined;
3471
+ behavior_strategy?: "base_class" | "inline" | undefined;
3472
+ pattern?: string | undefined;
3473
+ patterns?: string[] | undefined;
3474
+ scopeable?: boolean | undefined;
3475
+ surface?: string | undefined;
3476
+ context?: string | undefined;
3477
+ sync?: "electric" | "api" | undefined;
3478
+ };
3479
+ behaviors: (string | {
3480
+ name: string;
3481
+ options?: Record<string, unknown> | undefined;
3482
+ })[];
3483
+ eav: boolean;
3484
+ eav_value_table: boolean;
3485
+ relationships?: Record<string, {
3486
+ type: "belongs_to" | "has_many" | "has_one";
3487
+ target: string;
3488
+ foreign_key: string;
3489
+ on_delete: "cascade" | "restrict" | "set_null" | "no_action";
3490
+ nullable?: boolean | undefined;
3491
+ through?: string | undefined;
3492
+ inverse?: string | undefined;
3493
+ }> | undefined;
3494
+ generate?: {
3495
+ writes: boolean;
3496
+ } | undefined;
3497
+ eav_definition_table?: string | undefined;
3498
+ queries?: ({
3499
+ by: string[];
3500
+ select?: string[] | undefined;
3501
+ limit?: boolean | undefined;
3502
+ unique?: boolean | undefined;
3503
+ order?: string | undefined;
3504
+ via?: string | undefined;
3505
+ } | {
3506
+ filters: string[];
3507
+ name: "search";
3508
+ paginate: boolean;
3509
+ search?: string | undefined;
3510
+ order?: string | undefined;
3511
+ })[] | undefined;
3512
+ integration?: {
3513
+ electric: boolean;
3514
+ providers?: Record<string, {
3515
+ cdc: boolean;
3516
+ direction: "inbound" | "outbound" | "bidirectional";
3517
+ remote_entity: string;
3518
+ field_mapping?: Record<string, string> | undefined;
3519
+ read_only_fields?: string[] | undefined;
3520
+ }> | undefined;
3521
+ sink?: {
3522
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3523
+ exclude_fields?: string[] | undefined;
3524
+ emit_changes?: boolean | undefined;
3525
+ } | undefined;
3526
+ } | undefined;
3527
+ detection?: Record<string, {
3528
+ poll: {
3529
+ cursor: {
3530
+ field: string;
3531
+ kind: "systemModstamp";
3532
+ } | {
3533
+ field: string;
3534
+ kind: "replayId";
3535
+ } | {
3536
+ field: string;
3537
+ kind: "timestamp";
3538
+ } | {
3539
+ field: string;
3540
+ kind: "eventId";
3541
+ } | {
3542
+ field: string;
3543
+ kind: "historyId";
3544
+ } | {
3545
+ field: string;
3546
+ kind: "syncToken";
3547
+ };
3548
+ provenance?: "poll" | "cdc" | undefined;
3549
+ };
3550
+ mode: "poll";
3551
+ mapping: {
3552
+ source: string;
3553
+ target: string;
3554
+ transform?: string | undefined;
3555
+ }[];
3556
+ filters: {
3557
+ field: string;
3558
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3559
+ value?: unknown;
3560
+ }[];
3561
+ } | {
3562
+ webhook: {
3563
+ eventIdField?: string | undefined;
3564
+ };
3565
+ mode: "webhook";
3566
+ mapping: {
3567
+ source: string;
3568
+ target: string;
3569
+ transform?: string | undefined;
3570
+ }[];
3571
+ filters: {
3572
+ field: string;
3573
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3574
+ value?: unknown;
3575
+ }[];
3576
+ }> | undefined;
3577
+ events?: {
3578
+ name: string;
3579
+ queue: string;
3580
+ body: Record<string, string>;
3581
+ generate_handler: boolean;
3582
+ }[] | undefined;
3583
+ emits?: string[] | undefined;
3584
+ analytics?: {
3585
+ metrics?: Record<string, {
3586
+ type: "simple";
3587
+ measure: string;
3588
+ filter?: string | undefined;
3589
+ description?: string | undefined;
3590
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3591
+ label?: string | undefined;
3592
+ } | {
3593
+ type: "derived";
3594
+ expr: string;
3595
+ metrics: string[];
3596
+ description?: string | undefined;
3597
+ label?: string | undefined;
3598
+ } | {
3599
+ type: "ratio";
3600
+ numerator: string | {
3601
+ type: "simple";
3602
+ measure: string;
3603
+ filter?: string | undefined;
3604
+ description?: string | undefined;
3605
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3606
+ label?: string | undefined;
3607
+ };
3608
+ denominator: string | {
3609
+ type: "simple";
3610
+ measure: string;
3611
+ filter?: string | undefined;
3612
+ description?: string | undefined;
3613
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3614
+ label?: string | undefined;
3615
+ };
3616
+ filter?: string | undefined;
3617
+ description?: string | undefined;
3618
+ label?: string | undefined;
3619
+ } | {
3620
+ type: "cumulative";
3621
+ measure: string;
3622
+ description?: string | undefined;
3623
+ label?: string | undefined;
3624
+ window?: string | undefined;
3625
+ grain_to_date?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3626
+ }> | undefined;
3627
+ measure_packs?: string[] | undefined;
3628
+ cube_name?: string | undefined;
3629
+ } | undefined;
3630
+ unique_indexes?: {
3631
+ fields: string[];
3632
+ name?: string | undefined;
3633
+ }[] | undefined;
3634
+ }, {
3635
+ fields: Record<string, {
3636
+ type: "string" | "boolean" | "integer" | "date" | "json" | "decimal" | "uuid" | "datetime" | "entity_ref" | "string_array" | "enum";
3637
+ required?: boolean | undefined;
3638
+ default?: unknown;
3639
+ entity_type?: "primary" | "unique" | "foreign" | "natural" | undefined;
3640
+ nullable?: boolean | undefined;
3641
+ min?: number | undefined;
3642
+ max?: number | undefined;
3643
+ unique?: boolean | undefined;
3644
+ measure?: boolean | undefined;
3645
+ analytics_aggregation?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3646
+ agg_time_dimension?: string | undefined;
3647
+ non_additive_dimension?: string | {
3648
+ name: string;
3649
+ window_choice?: string | undefined;
3650
+ window_groupings?: string[] | undefined;
3651
+ } | undefined;
3652
+ dimension?: boolean | undefined;
3653
+ dimension_type?: "categorical" | "time" | undefined;
3654
+ time_granularity?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3655
+ is_partition?: boolean | undefined;
3656
+ entity?: boolean | undefined;
3657
+ entity_role?: string | undefined;
3658
+ analytics_visibility?: "internal" | "agent" | "public" | undefined;
3659
+ semantic_expr?: string | undefined;
3660
+ semantic_label?: string | undefined;
3661
+ ui_label?: string | undefined;
3662
+ ui_type?: "number" | "boolean" | "date" | "json" | "datetime" | "enum" | "text" | "textarea" | "money" | "percentage" | "email" | "url" | "reference" | "badge" | "password" | undefined;
3663
+ ui_importance?: "primary" | "secondary" | "tertiary" | undefined;
3664
+ ui_group?: string | undefined;
3665
+ ui_sortable?: boolean | undefined;
3666
+ ui_filterable?: boolean | undefined;
3667
+ ui_visible?: boolean | undefined;
3668
+ ui_placeholder?: string | undefined;
3669
+ ui_help?: string | undefined;
3670
+ ui_format?: Record<string, unknown> | undefined;
3671
+ ui_key_field?: boolean | undefined;
3672
+ ui_key_field_order?: number | undefined;
3673
+ max_length?: number | undefined;
3674
+ min_length?: number | undefined;
3675
+ choices?: string[] | undefined;
3676
+ choices_from?: string | undefined;
3677
+ allowed_types?: string[] | undefined;
3678
+ index?: boolean | undefined;
3679
+ foreign_key?: string | undefined;
3680
+ }>;
3681
+ entity: {
3682
+ name: string;
3683
+ table: string;
3684
+ plural: string;
3685
+ config?: Record<string, unknown> | undefined;
3686
+ folder_structure?: "flat" | "nested" | undefined;
3687
+ file_grouping?: "separate" | "grouped" | undefined;
3688
+ behavior_strategy?: "base_class" | "inline" | undefined;
3689
+ expose?: ("repository" | "rest" | "trpc" | "electric")[] | undefined;
3690
+ pattern?: string | undefined;
3691
+ patterns?: string[] | undefined;
3692
+ scopeable?: boolean | undefined;
3693
+ surface?: string | undefined;
3694
+ context?: string | undefined;
3695
+ sync?: "electric" | "api" | undefined;
3696
+ };
3697
+ relationships?: Record<string, {
3698
+ type: "belongs_to" | "has_many" | "has_one";
3699
+ target: string;
3700
+ foreign_key: string;
3701
+ nullable?: boolean | undefined;
3702
+ through?: string | undefined;
3703
+ inverse?: string | undefined;
3704
+ on_delete?: "cascade" | "restrict" | "set_null" | "no_action" | undefined;
3705
+ }> | undefined;
3706
+ behaviors?: (string | {
3707
+ name: string;
3708
+ options?: Record<string, unknown> | undefined;
3709
+ })[] | undefined;
3710
+ generate?: {
3711
+ writes?: boolean | undefined;
3712
+ } | undefined;
3713
+ eav?: boolean | undefined;
3714
+ eav_value_table?: boolean | undefined;
3715
+ eav_definition_table?: string | undefined;
3716
+ queries?: ({
3717
+ by: string[];
3718
+ select?: string[] | undefined;
3719
+ limit?: boolean | undefined;
3720
+ unique?: boolean | undefined;
3721
+ order?: string | undefined;
3722
+ via?: string | undefined;
3723
+ } | {
3724
+ filters: string[];
3725
+ name: "search";
3726
+ search?: string | undefined;
3727
+ order?: string | undefined;
3728
+ paginate?: boolean | undefined;
3729
+ })[] | undefined;
3730
+ integration?: {
3731
+ electric?: boolean | undefined;
3732
+ providers?: Record<string, {
3733
+ direction: "inbound" | "outbound" | "bidirectional";
3734
+ remote_entity: string;
3735
+ cdc?: boolean | undefined;
3736
+ field_mapping?: Record<string, string> | undefined;
3737
+ read_only_fields?: string[] | undefined;
3738
+ }> | undefined;
3739
+ sink?: {
3740
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3741
+ exclude_fields?: string[] | undefined;
3742
+ emit_changes?: boolean | undefined;
3743
+ } | undefined;
3255
3744
  } | undefined;
3256
3745
  detection?: Record<string, {
3257
3746
  poll: {
package/dist/src/index.js CHANGED
@@ -45,13 +45,13 @@ import {
45
45
  validateOrchestrationProject,
46
46
  validatePatternComposition,
47
47
  validatePatternProject
48
- } from "../chunk-6ECCJVYW.js";
48
+ } from "../chunk-K4BQQ2NN.js";
49
49
  import "../chunk-KVOWSC5S.js";
50
- import "../chunk-QFUIE37H.js";
51
- import "../chunk-FFUDEIFF.js";
52
- import "../chunk-EO2QPOKH.js";
53
50
  import "../chunk-PRWIX6UW.js";
54
- import "../chunk-O2A6XHGD.js";
51
+ import "../chunk-KFXXOFDC.js";
52
+ import "../chunk-HN5HT5WL.js";
53
+ import "../chunk-EO2QPOKH.js";
54
+ import "../chunk-LLDJS7PJ.js";
55
55
  import "../chunk-HNWZFNKP.js";
56
56
  import "../chunk-AHV4GDYM.js";
57
57
  import "../chunk-SQDOBLBP.js";
@@ -62,8 +62,8 @@ import "../chunk-JEINYUJH.js";
62
62
  import "../chunk-5TK7MEN4.js";
63
63
  import "../chunk-4KNXX6TI.js";
64
64
  import "../chunk-3CJFPU6Q.js";
65
- import "../chunk-TDEHU73T.js";
66
- import "../chunk-S7C6TIIF.js";
65
+ import "../chunk-YIVQ7KLS.js";
66
+ import "../chunk-S5G3HO7N.js";
67
67
  import "../chunk-MZ6GV4YF.js";
68
68
  import "../chunk-LG57S2SC.js";
69
69
  import "../chunk-U64T4YZE.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pattern-stack/codegen",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Entity-driven code generation for full-stack TypeScript applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -401,18 +401,34 @@ export class DrizzleEventBus implements IEventBus, IEventReadPort, OnModuleInit,
401
401
 
402
402
  // The idempotency guard is the partial UNIQUE expression index
403
403
  // `idx_domain_events_schedule_slot` on (type, metadata->>'scheduleSlot').
404
- // Drizzle 0.45's typed `onConflictDoNothing({ target })` only accepts
405
- // columns, so it can't name an expression index — we instead let the
406
- // insert run and treat a unique-violation (SQLSTATE 23505) as the
407
- // already-materialised no-op. This is the exactly-one-per-slot invariant:
408
- // a concurrent or repeat materialise of the same slot loses the race at
409
- // the DB and reports `created: false`.
404
+ // Use a BARE (no-target) `ON CONFLICT DO NOTHING`: Drizzle 0.45's typed
405
+ // `onConflictDoNothing({ target })` only accepts columns so it can't NAME
406
+ // the expression index, but the no-arg form emits target-less
407
+ // `ON CONFLICT DO NOTHING`, which Postgres applies to ANY unique
408
+ // constraint/index including this expression index. `.returning({ id })`
409
+ // then gives us the rowcount discriminator: zero rows back == the slot was
410
+ // already materialised (DO NOTHING fired), so `created: false`. This keeps
411
+ // the happy path off the exception channel — a repeat materialise no longer
412
+ // raises SQLSTATE 23505, so Postgres logs no scary `duplicate key value
413
+ // violates unique constraint` ERROR line on every colliding boot/tick.
414
+ //
415
+ // The unique-violation catch is retained as a fallback for the genuine
416
+ // concurrent-insert race window (two sessions clear the conflict check and
417
+ // both attempt the insert in the same instant) and for backends whose
418
+ // driver surfaces a 23505 rather than honouring DO NOTHING; in both cases
419
+ // it collapses to the same `created: false` no-op.
420
+ let inserted: Array<{ id: string }>;
410
421
  try {
411
- await this.db.insert(domainEvents).values(values);
422
+ inserted = await this.db
423
+ .insert(domainEvents)
424
+ .values(values)
425
+ .onConflictDoNothing()
426
+ .returning({ id: domainEvents.id });
412
427
  } catch (err) {
413
428
  if (isUniqueViolation(err)) return { created: false };
414
429
  throw err;
415
430
  }
431
+ if (inserted.length === 0) return { created: false };
416
432
 
417
433
  // Wake the drainer for an already-due tick. A future slot waits for polling.
418
434
  if (spec.slotStart.getTime() <= Date.now()) {
@@ -71,6 +71,33 @@ export const eventRegistry = {
71
71
  version: 1,
72
72
  retry: { attempts: 3, backoff: 'exponential' },
73
73
  },
74
+ 'message_created': {
75
+ type: 'message_created',
76
+ tier: 'domain',
77
+ direction: 'change',
78
+ pool: 'events_change',
79
+ aggregate: 'message',
80
+ version: 1,
81
+ retry: { attempts: 3, backoff: 'exponential' },
82
+ },
83
+ 'message_deleted': {
84
+ type: 'message_deleted',
85
+ tier: 'domain',
86
+ direction: 'change',
87
+ pool: 'events_change',
88
+ aggregate: 'message',
89
+ version: 1,
90
+ retry: { attempts: 3, backoff: 'exponential' },
91
+ },
92
+ 'message_edited': {
93
+ type: 'message_edited',
94
+ tier: 'domain',
95
+ direction: 'change',
96
+ pool: 'events_change',
97
+ aggregate: 'message',
98
+ version: 1,
99
+ retry: { attempts: 3, backoff: 'exponential' },
100
+ },
74
101
  'stripe_payment_received': {
75
102
  type: 'stripe_payment_received',
76
103
  tier: 'domain',