@pattern-stack/codegen 0.22.0 → 0.23.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 (48) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/{chunk-NR7QQ6ZI.js → chunk-42763UEE.js} +2 -2
  3. package/dist/{chunk-6ECCJVYW.js → chunk-4M66MQYA.js} +44 -2
  4. package/dist/chunk-4M66MQYA.js.map +1 -0
  5. package/dist/{chunk-FNHNSFIJ.js → chunk-6XP2Q5SS.js} +2 -2
  6. package/dist/{chunk-VDL5CJ5C.js → chunk-7B7MMDOJ.js} +54 -1
  7. package/dist/chunk-7B7MMDOJ.js.map +1 -0
  8. package/dist/{chunk-NXHL5YII.js → chunk-7LKAMLV4.js} +4 -4
  9. package/dist/{chunk-6DQEIXYU.js → chunk-FIUC6QB5.js} +1 -1
  10. package/dist/chunk-FIUC6QB5.js.map +1 -0
  11. package/dist/{chunk-DB5UXJC3.js → chunk-PNCOUFFI.js} +4 -2
  12. package/dist/chunk-PNCOUFFI.js.map +1 -0
  13. package/dist/{chunk-QXVCRA23.js → chunk-SH76CFAY.js} +9 -4
  14. package/dist/chunk-SH76CFAY.js.map +1 -0
  15. package/dist/runtime/base-classes/index.js +17 -17
  16. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  17. package/dist/runtime/subsystems/auth/index.js +7 -7
  18. package/dist/runtime/subsystems/bridge/bridge.module.js +4 -4
  19. package/dist/runtime/subsystems/bridge/index.js +4 -4
  20. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +1 -1
  21. package/dist/runtime/subsystems/events/events.module.js +2 -2
  22. package/dist/runtime/subsystems/events/index.js +2 -2
  23. package/dist/runtime/subsystems/index.js +12 -12
  24. package/dist/runtime/subsystems/jobs/index.js +3 -3
  25. package/dist/runtime/subsystems/jobs/job-worker.d.ts +592 -4
  26. package/dist/runtime/subsystems/jobs/job-worker.js +3 -1
  27. package/dist/runtime/subsystems/jobs/job-worker.module.js +3 -3
  28. package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +19 -0
  29. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +1 -1
  30. package/dist/src/cli/index.js +211 -60
  31. package/dist/src/cli/index.js.map +1 -1
  32. package/dist/src/index.d.ts +477 -1
  33. package/dist/src/index.js +1 -1
  34. package/package.json +1 -1
  35. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +23 -7
  36. package/runtime/subsystems/jobs/job-worker.module.ts +5 -0
  37. package/runtime/subsystems/jobs/job-worker.ts +126 -12
  38. package/runtime/subsystems/jobs/jobs-domain.module.ts +19 -0
  39. package/templates/entity/new/clean-lite-ps/prompt-extension.js +59 -10
  40. package/templates/subsystem/jobs-config/codegen-config-jobs-block.ejs.t +11 -0
  41. package/dist/chunk-6DQEIXYU.js.map +0 -1
  42. package/dist/chunk-6ECCJVYW.js.map +0 -1
  43. package/dist/chunk-DB5UXJC3.js.map +0 -1
  44. package/dist/chunk-QXVCRA23.js.map +0 -1
  45. package/dist/chunk-VDL5CJ5C.js.map +0 -1
  46. /package/dist/{chunk-NR7QQ6ZI.js.map → chunk-42763UEE.js.map} +0 -0
  47. /package/dist/{chunk-FNHNSFIJ.js.map → chunk-6XP2Q5SS.js.map} +0 -0
  48. /package/dist/{chunk-NXHL5YII.js.map → chunk-7LKAMLV4.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,16 @@ 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
+ }, "strict", z.ZodTypeAny, {
1535
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1536
+ exclude_fields?: string[] | undefined;
1537
+ }, {
1538
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1539
+ exclude_fields?: string[] | undefined;
1540
+ }>>;
1531
1541
  }, "strip", z.ZodTypeAny, {
1532
1542
  electric: boolean;
1533
1543
  providers?: Record<string, {
@@ -1537,6 +1547,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
1537
1547
  field_mapping?: Record<string, string> | undefined;
1538
1548
  read_only_fields?: string[] | undefined;
1539
1549
  }> | undefined;
1550
+ sink?: {
1551
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1552
+ exclude_fields?: string[] | undefined;
1553
+ } | undefined;
1540
1554
  }, {
1541
1555
  electric?: boolean | undefined;
1542
1556
  providers?: Record<string, {
@@ -1546,6 +1560,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
1546
1560
  field_mapping?: Record<string, string> | undefined;
1547
1561
  read_only_fields?: string[] | undefined;
1548
1562
  }> | undefined;
1563
+ sink?: {
1564
+ delete?: "noop" | "soft" | "tombstone" | undefined;
1565
+ exclude_fields?: string[] | undefined;
1566
+ } | undefined;
1549
1567
  }>>;
1550
1568
  detection: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"mode", [z.ZodObject<{
1551
1569
  mode: z.ZodLiteral<"poll">;
@@ -2187,6 +2205,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2187
2205
  field_mapping?: Record<string, string> | undefined;
2188
2206
  read_only_fields?: string[] | undefined;
2189
2207
  }> | undefined;
2208
+ sink?: {
2209
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2210
+ exclude_fields?: string[] | undefined;
2211
+ } | undefined;
2190
2212
  } | undefined;
2191
2213
  detection?: Record<string, {
2192
2214
  poll: {
@@ -2400,6 +2422,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2400
2422
  field_mapping?: Record<string, string> | undefined;
2401
2423
  read_only_fields?: string[] | undefined;
2402
2424
  }> | undefined;
2425
+ sink?: {
2426
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2427
+ exclude_fields?: string[] | undefined;
2428
+ } | undefined;
2403
2429
  } | undefined;
2404
2430
  detection?: Record<string, {
2405
2431
  poll: {
@@ -2613,6 +2639,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2613
2639
  field_mapping?: Record<string, string> | undefined;
2614
2640
  read_only_fields?: string[] | undefined;
2615
2641
  }> | undefined;
2642
+ sink?: {
2643
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2644
+ exclude_fields?: string[] | undefined;
2645
+ } | undefined;
2616
2646
  } | undefined;
2617
2647
  detection?: Record<string, {
2618
2648
  poll: {
@@ -2826,6 +2856,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2826
2856
  field_mapping?: Record<string, string> | undefined;
2827
2857
  read_only_fields?: string[] | undefined;
2828
2858
  }> | undefined;
2859
+ sink?: {
2860
+ delete?: "noop" | "soft" | "tombstone" | undefined;
2861
+ exclude_fields?: string[] | undefined;
2862
+ } | undefined;
2829
2863
  } | undefined;
2830
2864
  detection?: Record<string, {
2831
2865
  poll: {
@@ -3039,6 +3073,10 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3039
3073
  field_mapping?: Record<string, string> | undefined;
3040
3074
  read_only_fields?: string[] | undefined;
3041
3075
  }> | undefined;
3076
+ sink?: {
3077
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3078
+ exclude_fields?: string[] | undefined;
3079
+ } | undefined;
3042
3080
  } | undefined;
3043
3081
  detection?: Record<string, {
3044
3082
  poll: {
@@ -3252,6 +3290,444 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3252
3290
  field_mapping?: Record<string, string> | undefined;
3253
3291
  read_only_fields?: string[] | undefined;
3254
3292
  }> | undefined;
3293
+ sink?: {
3294
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3295
+ exclude_fields?: string[] | undefined;
3296
+ } | undefined;
3297
+ } | undefined;
3298
+ detection?: Record<string, {
3299
+ poll: {
3300
+ cursor: {
3301
+ field: string;
3302
+ kind: "systemModstamp";
3303
+ } | {
3304
+ field: string;
3305
+ kind: "replayId";
3306
+ } | {
3307
+ field: string;
3308
+ kind: "timestamp";
3309
+ } | {
3310
+ field: string;
3311
+ kind: "eventId";
3312
+ } | {
3313
+ field: string;
3314
+ kind: "historyId";
3315
+ } | {
3316
+ field: string;
3317
+ kind: "syncToken";
3318
+ };
3319
+ provenance?: "poll" | "cdc" | undefined;
3320
+ };
3321
+ mode: "poll";
3322
+ mapping: {
3323
+ source: string;
3324
+ target: string;
3325
+ transform?: string | undefined;
3326
+ }[];
3327
+ filters?: {
3328
+ field: string;
3329
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3330
+ value?: unknown;
3331
+ }[] | undefined;
3332
+ } | {
3333
+ webhook: {
3334
+ eventIdField?: string | undefined;
3335
+ };
3336
+ mode: "webhook";
3337
+ mapping: {
3338
+ source: string;
3339
+ target: string;
3340
+ transform?: string | undefined;
3341
+ }[];
3342
+ filters?: {
3343
+ field: string;
3344
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3345
+ value?: unknown;
3346
+ }[] | undefined;
3347
+ }> | undefined;
3348
+ events?: {
3349
+ name: string;
3350
+ queue: string;
3351
+ body: Record<string, string>;
3352
+ generate_handler?: boolean | undefined;
3353
+ }[] | undefined;
3354
+ emits?: string[] | undefined;
3355
+ analytics?: {
3356
+ metrics?: Record<string, {
3357
+ type: "simple";
3358
+ measure: string;
3359
+ filter?: string | undefined;
3360
+ description?: string | undefined;
3361
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3362
+ label?: string | undefined;
3363
+ } | {
3364
+ type: "derived";
3365
+ expr: string;
3366
+ metrics: string[];
3367
+ description?: string | undefined;
3368
+ label?: string | undefined;
3369
+ } | {
3370
+ type: "ratio";
3371
+ numerator: string | {
3372
+ type: "simple";
3373
+ measure: string;
3374
+ filter?: string | undefined;
3375
+ description?: string | undefined;
3376
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3377
+ label?: string | undefined;
3378
+ };
3379
+ denominator: string | {
3380
+ type: "simple";
3381
+ measure: string;
3382
+ filter?: string | undefined;
3383
+ description?: string | undefined;
3384
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3385
+ label?: string | undefined;
3386
+ };
3387
+ filter?: string | undefined;
3388
+ description?: string | undefined;
3389
+ label?: string | undefined;
3390
+ } | {
3391
+ type: "cumulative";
3392
+ measure: string;
3393
+ description?: string | undefined;
3394
+ label?: string | undefined;
3395
+ window?: string | undefined;
3396
+ grain_to_date?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3397
+ }> | undefined;
3398
+ measure_packs?: string[] | undefined;
3399
+ cube_name?: string | undefined;
3400
+ } | undefined;
3401
+ unique_indexes?: {
3402
+ fields: string[];
3403
+ name?: string | undefined;
3404
+ }[] | undefined;
3405
+ }>, {
3406
+ fields: Record<string, {
3407
+ type: "string" | "boolean" | "integer" | "date" | "json" | "decimal" | "uuid" | "datetime" | "entity_ref" | "string_array" | "enum";
3408
+ required: boolean;
3409
+ nullable: boolean;
3410
+ default?: unknown;
3411
+ entity_type?: "primary" | "unique" | "foreign" | "natural" | undefined;
3412
+ min?: number | undefined;
3413
+ max?: number | undefined;
3414
+ unique?: boolean | undefined;
3415
+ measure?: boolean | undefined;
3416
+ analytics_aggregation?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3417
+ agg_time_dimension?: string | undefined;
3418
+ non_additive_dimension?: string | {
3419
+ name: string;
3420
+ window_choice?: string | undefined;
3421
+ window_groupings?: string[] | undefined;
3422
+ } | undefined;
3423
+ dimension?: boolean | undefined;
3424
+ dimension_type?: "categorical" | "time" | undefined;
3425
+ time_granularity?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3426
+ is_partition?: boolean | undefined;
3427
+ entity?: boolean | undefined;
3428
+ entity_role?: string | undefined;
3429
+ analytics_visibility?: "internal" | "agent" | "public" | undefined;
3430
+ semantic_expr?: string | undefined;
3431
+ semantic_label?: string | undefined;
3432
+ ui_label?: string | undefined;
3433
+ ui_type?: "number" | "boolean" | "date" | "json" | "datetime" | "enum" | "text" | "textarea" | "money" | "percentage" | "email" | "url" | "reference" | "badge" | "password" | undefined;
3434
+ ui_importance?: "primary" | "secondary" | "tertiary" | undefined;
3435
+ ui_group?: string | undefined;
3436
+ ui_sortable?: boolean | undefined;
3437
+ ui_filterable?: boolean | undefined;
3438
+ ui_visible?: boolean | undefined;
3439
+ ui_placeholder?: string | undefined;
3440
+ ui_help?: string | undefined;
3441
+ ui_format?: Record<string, unknown> | undefined;
3442
+ ui_key_field?: boolean | undefined;
3443
+ ui_key_field_order?: number | undefined;
3444
+ max_length?: number | undefined;
3445
+ min_length?: number | undefined;
3446
+ choices?: string[] | undefined;
3447
+ choices_from?: string | undefined;
3448
+ allowed_types?: string[] | undefined;
3449
+ index?: boolean | undefined;
3450
+ foreign_key?: string | undefined;
3451
+ }>;
3452
+ entity: {
3453
+ name: string;
3454
+ table: string;
3455
+ plural: string;
3456
+ expose: ("repository" | "rest" | "trpc" | "electric")[];
3457
+ config?: Record<string, unknown> | undefined;
3458
+ folder_structure?: "flat" | "nested" | undefined;
3459
+ file_grouping?: "separate" | "grouped" | undefined;
3460
+ behavior_strategy?: "base_class" | "inline" | undefined;
3461
+ pattern?: string | undefined;
3462
+ patterns?: string[] | undefined;
3463
+ scopeable?: boolean | undefined;
3464
+ surface?: string | undefined;
3465
+ context?: string | undefined;
3466
+ sync?: "electric" | "api" | undefined;
3467
+ };
3468
+ behaviors: (string | {
3469
+ name: string;
3470
+ options?: Record<string, unknown> | undefined;
3471
+ })[];
3472
+ eav: boolean;
3473
+ eav_value_table: boolean;
3474
+ relationships?: Record<string, {
3475
+ type: "belongs_to" | "has_many" | "has_one";
3476
+ target: string;
3477
+ foreign_key: string;
3478
+ on_delete: "cascade" | "restrict" | "set_null" | "no_action";
3479
+ nullable?: boolean | undefined;
3480
+ through?: string | undefined;
3481
+ inverse?: string | undefined;
3482
+ }> | undefined;
3483
+ generate?: {
3484
+ writes: boolean;
3485
+ } | undefined;
3486
+ eav_definition_table?: string | undefined;
3487
+ queries?: ({
3488
+ by: string[];
3489
+ select?: string[] | undefined;
3490
+ limit?: boolean | undefined;
3491
+ unique?: boolean | undefined;
3492
+ order?: string | undefined;
3493
+ via?: string | undefined;
3494
+ } | {
3495
+ filters: string[];
3496
+ name: "search";
3497
+ paginate: boolean;
3498
+ search?: string | undefined;
3499
+ order?: string | undefined;
3500
+ })[] | undefined;
3501
+ integration?: {
3502
+ electric: boolean;
3503
+ providers?: Record<string, {
3504
+ cdc: boolean;
3505
+ direction: "inbound" | "outbound" | "bidirectional";
3506
+ remote_entity: string;
3507
+ field_mapping?: Record<string, string> | undefined;
3508
+ read_only_fields?: string[] | undefined;
3509
+ }> | undefined;
3510
+ sink?: {
3511
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3512
+ exclude_fields?: string[] | undefined;
3513
+ } | undefined;
3514
+ } | undefined;
3515
+ detection?: Record<string, {
3516
+ poll: {
3517
+ cursor: {
3518
+ field: string;
3519
+ kind: "systemModstamp";
3520
+ } | {
3521
+ field: string;
3522
+ kind: "replayId";
3523
+ } | {
3524
+ field: string;
3525
+ kind: "timestamp";
3526
+ } | {
3527
+ field: string;
3528
+ kind: "eventId";
3529
+ } | {
3530
+ field: string;
3531
+ kind: "historyId";
3532
+ } | {
3533
+ field: string;
3534
+ kind: "syncToken";
3535
+ };
3536
+ provenance?: "poll" | "cdc" | undefined;
3537
+ };
3538
+ mode: "poll";
3539
+ mapping: {
3540
+ source: string;
3541
+ target: string;
3542
+ transform?: string | undefined;
3543
+ }[];
3544
+ filters: {
3545
+ field: string;
3546
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3547
+ value?: unknown;
3548
+ }[];
3549
+ } | {
3550
+ webhook: {
3551
+ eventIdField?: string | undefined;
3552
+ };
3553
+ mode: "webhook";
3554
+ mapping: {
3555
+ source: string;
3556
+ target: string;
3557
+ transform?: string | undefined;
3558
+ }[];
3559
+ filters: {
3560
+ field: string;
3561
+ op: "eq" | "neq" | "in" | "nin" | "gt" | "gte" | "lt" | "lte";
3562
+ value?: unknown;
3563
+ }[];
3564
+ }> | undefined;
3565
+ events?: {
3566
+ name: string;
3567
+ queue: string;
3568
+ body: Record<string, string>;
3569
+ generate_handler: boolean;
3570
+ }[] | undefined;
3571
+ emits?: string[] | undefined;
3572
+ analytics?: {
3573
+ metrics?: Record<string, {
3574
+ type: "simple";
3575
+ measure: string;
3576
+ filter?: string | undefined;
3577
+ description?: string | undefined;
3578
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3579
+ label?: string | undefined;
3580
+ } | {
3581
+ type: "derived";
3582
+ expr: string;
3583
+ metrics: string[];
3584
+ description?: string | undefined;
3585
+ label?: string | undefined;
3586
+ } | {
3587
+ type: "ratio";
3588
+ numerator: string | {
3589
+ type: "simple";
3590
+ measure: string;
3591
+ filter?: string | undefined;
3592
+ description?: string | undefined;
3593
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3594
+ label?: string | undefined;
3595
+ };
3596
+ denominator: string | {
3597
+ type: "simple";
3598
+ measure: string;
3599
+ filter?: string | undefined;
3600
+ description?: string | undefined;
3601
+ agg?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3602
+ label?: string | undefined;
3603
+ };
3604
+ filter?: string | undefined;
3605
+ description?: string | undefined;
3606
+ label?: string | undefined;
3607
+ } | {
3608
+ type: "cumulative";
3609
+ measure: string;
3610
+ description?: string | undefined;
3611
+ label?: string | undefined;
3612
+ window?: string | undefined;
3613
+ grain_to_date?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3614
+ }> | undefined;
3615
+ measure_packs?: string[] | undefined;
3616
+ cube_name?: string | undefined;
3617
+ } | undefined;
3618
+ unique_indexes?: {
3619
+ fields: string[];
3620
+ name?: string | undefined;
3621
+ }[] | undefined;
3622
+ }, {
3623
+ fields: Record<string, {
3624
+ type: "string" | "boolean" | "integer" | "date" | "json" | "decimal" | "uuid" | "datetime" | "entity_ref" | "string_array" | "enum";
3625
+ required?: boolean | undefined;
3626
+ default?: unknown;
3627
+ entity_type?: "primary" | "unique" | "foreign" | "natural" | undefined;
3628
+ nullable?: boolean | undefined;
3629
+ min?: number | undefined;
3630
+ max?: number | undefined;
3631
+ unique?: boolean | undefined;
3632
+ measure?: boolean | undefined;
3633
+ analytics_aggregation?: "sum" | "min" | "max" | "count" | "count_distinct" | "average" | "median" | "percentile" | "sum_boolean" | undefined;
3634
+ agg_time_dimension?: string | undefined;
3635
+ non_additive_dimension?: string | {
3636
+ name: string;
3637
+ window_choice?: string | undefined;
3638
+ window_groupings?: string[] | undefined;
3639
+ } | undefined;
3640
+ dimension?: boolean | undefined;
3641
+ dimension_type?: "categorical" | "time" | undefined;
3642
+ time_granularity?: "day" | "week" | "month" | "quarter" | "year" | undefined;
3643
+ is_partition?: boolean | undefined;
3644
+ entity?: boolean | undefined;
3645
+ entity_role?: string | undefined;
3646
+ analytics_visibility?: "internal" | "agent" | "public" | undefined;
3647
+ semantic_expr?: string | undefined;
3648
+ semantic_label?: string | undefined;
3649
+ ui_label?: string | undefined;
3650
+ ui_type?: "number" | "boolean" | "date" | "json" | "datetime" | "enum" | "text" | "textarea" | "money" | "percentage" | "email" | "url" | "reference" | "badge" | "password" | undefined;
3651
+ ui_importance?: "primary" | "secondary" | "tertiary" | undefined;
3652
+ ui_group?: string | undefined;
3653
+ ui_sortable?: boolean | undefined;
3654
+ ui_filterable?: boolean | undefined;
3655
+ ui_visible?: boolean | undefined;
3656
+ ui_placeholder?: string | undefined;
3657
+ ui_help?: string | undefined;
3658
+ ui_format?: Record<string, unknown> | undefined;
3659
+ ui_key_field?: boolean | undefined;
3660
+ ui_key_field_order?: number | undefined;
3661
+ max_length?: number | undefined;
3662
+ min_length?: number | undefined;
3663
+ choices?: string[] | undefined;
3664
+ choices_from?: string | undefined;
3665
+ allowed_types?: string[] | undefined;
3666
+ index?: boolean | undefined;
3667
+ foreign_key?: string | undefined;
3668
+ }>;
3669
+ entity: {
3670
+ name: string;
3671
+ table: string;
3672
+ plural: string;
3673
+ config?: Record<string, unknown> | undefined;
3674
+ folder_structure?: "flat" | "nested" | undefined;
3675
+ file_grouping?: "separate" | "grouped" | undefined;
3676
+ behavior_strategy?: "base_class" | "inline" | undefined;
3677
+ expose?: ("repository" | "rest" | "trpc" | "electric")[] | undefined;
3678
+ pattern?: string | undefined;
3679
+ patterns?: string[] | undefined;
3680
+ scopeable?: boolean | undefined;
3681
+ surface?: string | undefined;
3682
+ context?: string | undefined;
3683
+ sync?: "electric" | "api" | undefined;
3684
+ };
3685
+ relationships?: Record<string, {
3686
+ type: "belongs_to" | "has_many" | "has_one";
3687
+ target: string;
3688
+ foreign_key: string;
3689
+ nullable?: boolean | undefined;
3690
+ through?: string | undefined;
3691
+ inverse?: string | undefined;
3692
+ on_delete?: "cascade" | "restrict" | "set_null" | "no_action" | undefined;
3693
+ }> | undefined;
3694
+ behaviors?: (string | {
3695
+ name: string;
3696
+ options?: Record<string, unknown> | undefined;
3697
+ })[] | undefined;
3698
+ generate?: {
3699
+ writes?: boolean | undefined;
3700
+ } | undefined;
3701
+ eav?: boolean | undefined;
3702
+ eav_value_table?: boolean | undefined;
3703
+ eav_definition_table?: string | undefined;
3704
+ queries?: ({
3705
+ by: string[];
3706
+ select?: string[] | undefined;
3707
+ limit?: boolean | undefined;
3708
+ unique?: boolean | undefined;
3709
+ order?: string | undefined;
3710
+ via?: string | undefined;
3711
+ } | {
3712
+ filters: string[];
3713
+ name: "search";
3714
+ search?: string | undefined;
3715
+ order?: string | undefined;
3716
+ paginate?: boolean | undefined;
3717
+ })[] | undefined;
3718
+ integration?: {
3719
+ electric?: boolean | undefined;
3720
+ providers?: Record<string, {
3721
+ direction: "inbound" | "outbound" | "bidirectional";
3722
+ remote_entity: string;
3723
+ cdc?: boolean | undefined;
3724
+ field_mapping?: Record<string, string> | undefined;
3725
+ read_only_fields?: string[] | undefined;
3726
+ }> | undefined;
3727
+ sink?: {
3728
+ delete?: "noop" | "soft" | "tombstone" | undefined;
3729
+ exclude_fields?: string[] | undefined;
3730
+ } | undefined;
3255
3731
  } | undefined;
3256
3732
  detection?: Record<string, {
3257
3733
  poll: {
package/dist/src/index.js CHANGED
@@ -45,7 +45,7 @@ import {
45
45
  validateOrchestrationProject,
46
46
  validatePatternComposition,
47
47
  validatePatternProject
48
- } from "../chunk-6ECCJVYW.js";
48
+ } from "../chunk-4M66MQYA.js";
49
49
  import "../chunk-KVOWSC5S.js";
50
50
  import "../chunk-QFUIE37H.js";
51
51
  import "../chunk-FFUDEIFF.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.23.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()) {
@@ -261,6 +261,11 @@ export class JobWorkerOrchestrator implements OnModuleInit, OnModuleDestroy {
261
261
  this.options.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS,
262
262
  pollIntervalMs: drizzleExt?.pollIntervalMs,
263
263
  listenNotify: drizzleExt?.listenNotify,
264
+ // CLAIM-HB-1 — lease tuning knobs. All optional; the worker defaults
265
+ // claimHeartbeatIntervalMs to staleThresholdMs/3 when omitted.
266
+ staleSweeperIntervalMs: drizzleExt?.staleSweeperIntervalMs,
267
+ staleThresholdMs: drizzleExt?.staleThresholdMs,
268
+ claimHeartbeatIntervalMs: drizzleExt?.claimHeartbeatIntervalMs,
264
269
  };
265
270
  const worker = this.options.workerFactory
266
271
  ? this.options.workerFactory(workerOptions)