@porulle/core 0.8.0 → 0.10.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 (162) hide show
  1. package/dist/auth/middleware.d.ts.map +1 -1
  2. package/dist/auth/middleware.js +26 -7
  3. package/dist/auth/setup.d.ts.map +1 -1
  4. package/dist/auth/setup.js +7 -5
  5. package/dist/config/defaults.d.ts.map +1 -1
  6. package/dist/config/defaults.js +3 -1
  7. package/dist/config/types.d.ts +13 -3
  8. package/dist/config/types.d.ts.map +1 -1
  9. package/dist/generated/plugin-manifest.d.ts +3 -0
  10. package/dist/generated/plugin-manifest.d.ts.map +1 -1
  11. package/dist/generated/plugin-manifest.js +1 -0
  12. package/dist/hooks/checkout-completion.d.ts.map +1 -1
  13. package/dist/hooks/checkout-completion.js +2 -2
  14. package/dist/hooks/checkout.d.ts.map +1 -1
  15. package/dist/hooks/checkout.js +1 -1
  16. package/dist/index.d.ts +5 -2
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +2 -0
  19. package/dist/interfaces/rest/router.d.ts.map +1 -1
  20. package/dist/interfaces/rest/router.js +2 -0
  21. package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -1
  22. package/dist/interfaces/rest/routes/admin/staff.js +37 -3
  23. package/dist/interfaces/rest/routes/checkout.d.ts +9 -0
  24. package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
  25. package/dist/interfaces/rest/routes/checkout.js +82 -22
  26. package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -1
  27. package/dist/interfaces/rest/routes/inventory.js +13 -0
  28. package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
  29. package/dist/interfaces/rest/routes/orders.js +13 -0
  30. package/dist/interfaces/rest/schemas/catalog.d.ts +391 -0
  31. package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
  32. package/dist/interfaces/rest/schemas/orders.js +2 -2
  33. package/dist/interfaces/rest/schemas/responses.d.ts +85 -0
  34. package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
  35. package/dist/interfaces/rest/schemas/search.d.ts +17 -0
  36. package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
  37. package/dist/kernel/database/scoped-db.d.ts +2 -1
  38. package/dist/kernel/database/scoped-db.d.ts.map +1 -1
  39. package/dist/kernel/database/scoped-db.js +74 -15
  40. package/dist/kernel/errors.d.ts +12 -0
  41. package/dist/kernel/errors.d.ts.map +1 -1
  42. package/dist/kernel/errors.js +16 -0
  43. package/dist/kernel/jobs/adapter.d.ts +27 -8
  44. package/dist/kernel/jobs/adapter.d.ts.map +1 -1
  45. package/dist/kernel/jobs/adapter.js +1 -2
  46. package/dist/kernel/jobs/drizzle-adapter.d.ts +13 -3
  47. package/dist/kernel/jobs/drizzle-adapter.d.ts.map +1 -1
  48. package/dist/kernel/jobs/drizzle-adapter.js +46 -5
  49. package/dist/kernel/jobs/runner.d.ts +2 -1
  50. package/dist/kernel/jobs/runner.d.ts.map +1 -1
  51. package/dist/kernel/jobs/runner.js +100 -15
  52. package/dist/kernel/jobs/types.d.ts +13 -0
  53. package/dist/kernel/jobs/types.d.ts.map +1 -1
  54. package/dist/kernel/plugin/manifest.d.ts +5 -0
  55. package/dist/kernel/plugin/manifest.d.ts.map +1 -1
  56. package/dist/kernel/plugin/manifest.js +9 -0
  57. package/dist/modules/analytics/drizzle-adapter.d.ts.map +1 -1
  58. package/dist/modules/analytics/drizzle-adapter.js +16 -3
  59. package/dist/modules/cart/service.d.ts.map +1 -1
  60. package/dist/modules/cart/service.js +3 -2
  61. package/dist/modules/catalog/entity-service.d.ts +1 -0
  62. package/dist/modules/catalog/entity-service.d.ts.map +1 -1
  63. package/dist/modules/catalog/entity-service.js +49 -3
  64. package/dist/modules/catalog/repository/index.d.ts +2 -2
  65. package/dist/modules/catalog/repository/index.d.ts.map +1 -1
  66. package/dist/modules/catalog/repository/index.js +9 -1
  67. package/dist/modules/catalog/schema.d.ts +51 -0
  68. package/dist/modules/catalog/schema.d.ts.map +1 -1
  69. package/dist/modules/catalog/schema.js +12 -1
  70. package/dist/modules/catalog/schemas.d.ts +3 -1
  71. package/dist/modules/catalog/schemas.d.ts.map +1 -1
  72. package/dist/modules/channels/adapter.d.ts +117 -0
  73. package/dist/modules/channels/adapter.d.ts.map +1 -0
  74. package/dist/modules/channels/adapter.js +3 -0
  75. package/dist/modules/customers/service.d.ts.map +1 -1
  76. package/dist/modules/customers/service.js +6 -0
  77. package/dist/modules/inventory/repository/index.js +4 -4
  78. package/dist/modules/inventory/service.d.ts.map +1 -1
  79. package/dist/modules/inventory/service.js +7 -3
  80. package/dist/modules/orders/schema.d.ts +17 -0
  81. package/dist/modules/orders/schema.d.ts.map +1 -1
  82. package/dist/modules/orders/schema.js +4 -0
  83. package/dist/modules/orders/service.d.ts +16 -2
  84. package/dist/modules/orders/service.d.ts.map +1 -1
  85. package/dist/modules/orders/service.js +226 -26
  86. package/dist/modules/orders/stale-order-cleanup.d.ts.map +1 -1
  87. package/dist/modules/orders/stale-order-cleanup.js +37 -16
  88. package/dist/modules/pricing/service.d.ts.map +1 -1
  89. package/dist/modules/pricing/service.js +5 -5
  90. package/dist/modules/promotions/repository/index.d.ts +1 -1
  91. package/dist/modules/promotions/repository/index.d.ts.map +1 -1
  92. package/dist/modules/promotions/repository/index.js +6 -3
  93. package/dist/modules/promotions/service.d.ts +1 -0
  94. package/dist/modules/promotions/service.d.ts.map +1 -1
  95. package/dist/modules/promotions/service.js +1 -1
  96. package/dist/modules/webhooks/repository/index.d.ts +1 -1
  97. package/dist/modules/webhooks/repository/index.d.ts.map +1 -1
  98. package/dist/modules/webhooks/repository/index.js +16 -10
  99. package/dist/runtime/kernel.d.ts.map +1 -1
  100. package/dist/runtime/kernel.js +14 -2
  101. package/dist/runtime/server.d.ts +1 -4
  102. package/dist/runtime/server.d.ts.map +1 -1
  103. package/dist/runtime/server.js +16 -34
  104. package/dist/test-utils/create-test-config.d.ts.map +1 -1
  105. package/dist/test-utils/create-test-config.js +2 -0
  106. package/dist/test-utils/order-test-helpers.d.ts +12 -0
  107. package/dist/test-utils/order-test-helpers.d.ts.map +1 -0
  108. package/dist/test-utils/order-test-helpers.js +18 -0
  109. package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
  110. package/dist/test-utils/rest-api-test-utils.js +1 -0
  111. package/dist/test-utils/test-actors.js +1 -1
  112. package/dist/testing.d.ts +1 -0
  113. package/dist/testing.d.ts.map +1 -1
  114. package/dist/testing.js +1 -0
  115. package/package.json +1 -1
  116. package/src/auth/middleware.ts +26 -7
  117. package/src/auth/setup.ts +10 -4
  118. package/src/config/defaults.ts +3 -1
  119. package/src/config/types.ts +16 -3
  120. package/src/generated/plugin-capabilities.d.ts +1 -0
  121. package/src/generated/plugin-manifest.ts +1 -0
  122. package/src/generated/plugin-repositories.d.ts +1 -0
  123. package/src/hooks/checkout-completion.ts +22 -16
  124. package/src/hooks/checkout.ts +11 -8
  125. package/src/index.ts +31 -1
  126. package/src/interfaces/rest/router.ts +2 -0
  127. package/src/interfaces/rest/routes/admin/staff.ts +45 -3
  128. package/src/interfaces/rest/routes/checkout.ts +94 -28
  129. package/src/interfaces/rest/routes/inventory.ts +14 -0
  130. package/src/interfaces/rest/routes/orders.ts +11 -0
  131. package/src/interfaces/rest/schemas/orders.ts +2 -2
  132. package/src/kernel/database/scoped-db.ts +83 -15
  133. package/src/kernel/errors.ts +20 -0
  134. package/src/kernel/jobs/adapter.ts +39 -8
  135. package/src/kernel/jobs/drizzle-adapter.ts +72 -9
  136. package/src/kernel/jobs/runner.ts +194 -72
  137. package/src/kernel/jobs/types.ts +25 -0
  138. package/src/kernel/plugin/manifest.ts +15 -0
  139. package/src/modules/analytics/drizzle-adapter.ts +19 -3
  140. package/src/modules/cart/service.ts +3 -2
  141. package/src/modules/catalog/entity-service.ts +37 -2
  142. package/src/modules/catalog/repository/index.ts +13 -3
  143. package/src/modules/catalog/schema.ts +33 -18
  144. package/src/modules/catalog/schemas.ts +3 -1
  145. package/src/modules/channels/adapter.ts +139 -0
  146. package/src/modules/customers/service.ts +6 -0
  147. package/src/modules/inventory/repository/index.ts +4 -4
  148. package/src/modules/inventory/service.ts +12 -2
  149. package/src/modules/orders/schema.ts +4 -0
  150. package/src/modules/orders/service.ts +404 -64
  151. package/src/modules/orders/stale-order-cleanup.ts +52 -27
  152. package/src/modules/pricing/service.ts +5 -6
  153. package/src/modules/promotions/repository/index.ts +6 -2
  154. package/src/modules/promotions/service.ts +2 -0
  155. package/src/modules/webhooks/repository/index.ts +16 -14
  156. package/src/runtime/kernel.ts +16 -2
  157. package/src/runtime/server.ts +22 -42
  158. package/src/test-utils/create-test-config.ts +2 -0
  159. package/src/test-utils/order-test-helpers.ts +26 -0
  160. package/src/test-utils/rest-api-test-utils.ts +1 -0
  161. package/src/test-utils/test-actors.ts +1 -1
  162. package/src/testing.ts +1 -0
@@ -507,6 +507,23 @@ export declare const OrderLineItemSchema: import("drizzle-zod").BuildSchema<"sel
507
507
  identity: undefined;
508
508
  generated: undefined;
509
509
  }, {}, {}>;
510
+ isCustomPrice: import("drizzle-orm/pg-core").PgColumn<{
511
+ name: "is_custom_price";
512
+ tableName: "order_line_items";
513
+ dataType: "boolean";
514
+ columnType: "PgBoolean";
515
+ data: boolean;
516
+ driverParam: boolean;
517
+ notNull: true;
518
+ hasDefault: true;
519
+ isPrimaryKey: false;
520
+ isAutoincrement: false;
521
+ hasRuntimeDefault: false;
522
+ enumValues: undefined;
523
+ baseColumn: never;
524
+ identity: undefined;
525
+ generated: undefined;
526
+ }, {}, {}>;
510
527
  taxAmount: import("drizzle-orm/pg-core").PgColumn<{
511
528
  name: "tax_amount";
512
529
  tableName: "order_line_items";
@@ -769,6 +786,23 @@ export declare const OrderWithItemsSchema: z.ZodObject<{
769
786
  identity: undefined;
770
787
  generated: undefined;
771
788
  }, {}, {}>;
789
+ isCustomPrice: import("drizzle-orm/pg-core").PgColumn<{
790
+ name: "is_custom_price";
791
+ tableName: "order_line_items";
792
+ dataType: "boolean";
793
+ columnType: "PgBoolean";
794
+ data: boolean;
795
+ driverParam: boolean;
796
+ notNull: true;
797
+ hasDefault: true;
798
+ isPrimaryKey: false;
799
+ isAutoincrement: false;
800
+ hasRuntimeDefault: false;
801
+ enumValues: undefined;
802
+ baseColumn: never;
803
+ identity: undefined;
804
+ generated: undefined;
805
+ }, {}, {}>;
772
806
  taxAmount: import("drizzle-orm/pg-core").PgColumn<{
773
807
  name: "tax_amount";
774
808
  tableName: "order_line_items";
@@ -1892,6 +1926,23 @@ export declare const CatalogEntitySchema: import("drizzle-zod").BuildSchema<"sel
1892
1926
  identity: undefined;
1893
1927
  generated: undefined;
1894
1928
  }, {}, {}>;
1929
+ sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
1930
+ name: "source_store_id";
1931
+ tableName: "sellable_entities";
1932
+ dataType: "string";
1933
+ columnType: "PgText";
1934
+ data: string;
1935
+ driverParam: string;
1936
+ notNull: false;
1937
+ hasDefault: false;
1938
+ isPrimaryKey: false;
1939
+ isAutoincrement: false;
1940
+ hasRuntimeDefault: false;
1941
+ enumValues: [string, ...string[]];
1942
+ baseColumn: never;
1943
+ identity: undefined;
1944
+ generated: undefined;
1945
+ }, {}, {}>;
1895
1946
  type: import("drizzle-orm/pg-core").PgColumn<{
1896
1947
  name: "type";
1897
1948
  tableName: "sellable_entities";
@@ -3656,6 +3707,23 @@ export declare const CatalogEntityResponse: z.ZodObject<{
3656
3707
  identity: undefined;
3657
3708
  generated: undefined;
3658
3709
  }, {}, {}>;
3710
+ sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
3711
+ name: "source_store_id";
3712
+ tableName: "sellable_entities";
3713
+ dataType: "string";
3714
+ columnType: "PgText";
3715
+ data: string;
3716
+ driverParam: string;
3717
+ notNull: false;
3718
+ hasDefault: false;
3719
+ isPrimaryKey: false;
3720
+ isAutoincrement: false;
3721
+ hasRuntimeDefault: false;
3722
+ enumValues: [string, ...string[]];
3723
+ baseColumn: never;
3724
+ identity: undefined;
3725
+ generated: undefined;
3726
+ }, {}, {}>;
3659
3727
  type: import("drizzle-orm/pg-core").PgColumn<{
3660
3728
  name: "type";
3661
3729
  tableName: "sellable_entities";
@@ -3851,6 +3919,23 @@ export declare const CatalogEntityListResponse: z.ZodObject<{
3851
3919
  identity: undefined;
3852
3920
  generated: undefined;
3853
3921
  }, {}, {}>;
3922
+ sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
3923
+ name: "source_store_id";
3924
+ tableName: "sellable_entities";
3925
+ dataType: "string";
3926
+ columnType: "PgText";
3927
+ data: string;
3928
+ driverParam: string;
3929
+ notNull: false;
3930
+ hasDefault: false;
3931
+ isPrimaryKey: false;
3932
+ isAutoincrement: false;
3933
+ hasRuntimeDefault: false;
3934
+ enumValues: [string, ...string[]];
3935
+ baseColumn: never;
3936
+ identity: undefined;
3937
+ generated: undefined;
3938
+ }, {}, {}>;
3854
3939
  type: import("drizzle-orm/pg-core").PgColumn<{
3855
3940
  name: "type";
3856
3941
  tableName: "sellable_entities";
@@ -1 +1 @@
1
- {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/responses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/responses.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAStC,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAEpB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAE5B,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGL,CAAC;AAI7B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAEnB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAE3B,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGL,CAAC;AAI5B,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAoD,CAAC;AAEhF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAmE,CAAC;AAItG,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAGL,CAAC;AAI5B,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAkD,CAAC;AAKzE,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;kBAExE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;kBAE7E;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;;;;;;kBAS7E;AAID,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA6C,CAAC;AACxE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsD,CAAC;AACrF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAoD,CAAC;AAC9E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAmD,CAAC;AACjF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA0E,CAAC;AACnH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA6D,CAAC;AAChG,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsE,CAAC;AAC7G,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAkD,CAAC"}
@@ -56,6 +56,23 @@ export declare const searchRoute: {
56
56
  identity: undefined;
57
57
  generated: undefined;
58
58
  }, {}, {}>;
59
+ sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
60
+ name: "source_store_id";
61
+ tableName: "sellable_entities";
62
+ dataType: "string";
63
+ columnType: "PgText";
64
+ data: string;
65
+ driverParam: string;
66
+ notNull: false;
67
+ hasDefault: false;
68
+ isPrimaryKey: false;
69
+ isAutoincrement: false;
70
+ hasRuntimeDefault: false;
71
+ enumValues: [string, ...string[]];
72
+ baseColumn: never;
73
+ identity: undefined;
74
+ generated: undefined;
75
+ }, {}, {}>;
59
76
  type: import("drizzle-orm/pg-core").PgColumn<{
60
77
  name: "type";
61
78
  tableName: "sellable_entities";
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAKnD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBvB,CAAC"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAKnD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBvB,CAAC"}
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Wraps a Drizzle PgDatabase instance so that INSERT operations on
5
5
  * org-scoped tables automatically include the actor's organizationId,
6
- * and SELECT ... FROM org-scoped tables constrain rows to that organization.
6
+ * and SELECT / UPDATE / DELETE against org-scoped tables constrain rows to
7
+ * that organization — including when the caller supplies no WHERE clause.
7
8
  *
8
9
  * Plugin route handlers receive this scoped db via PluginContext.database.db
9
10
  * (organization resolved per operation from AsyncLocalStorage when used from
@@ -1 +1 @@
1
- {"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/kernel/database/scoped-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;AAgB3D,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,oBAAoB,GAAG,GAAG,CA+EpF"}
1
+ {"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/kernel/database/scoped-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;AAuD3D,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,oBAAoB,GAAG,GAAG,CA2GpF"}
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Wraps a Drizzle PgDatabase instance so that INSERT operations on
5
5
  * org-scoped tables automatically include the actor's organizationId,
6
- * and SELECT ... FROM org-scoped tables constrain rows to that organization.
6
+ * and SELECT / UPDATE / DELETE against org-scoped tables constrain rows to
7
+ * that organization — including when the caller supplies no WHERE clause.
7
8
  *
8
9
  * Plugin route handlers receive this scoped db via PluginContext.database.db
9
10
  * (organization resolved per operation from AsyncLocalStorage when used from
@@ -24,6 +25,40 @@ function tableHasOrganizationId(table) {
24
25
  return false;
25
26
  }
26
27
  }
28
+ /**
29
+ * Wrap a WHERE-able Drizzle builder so every `.where()` call AND-s `orgEq` in
30
+ * AND re-wraps its result. Re-wrapping is what makes a chained
31
+ * `.where(a).where(b)` safe: Drizzle's second `.where()` REPLACES the first, so
32
+ * without re-wrapping the chained call would reach the raw builder and execute
33
+ * with only the caller's condition — dropping the org predicate and leaking
34
+ * across tenants. Every link in the chain re-injects `orgEq`.
35
+ */
36
+ function wrapWhereable(builder, orgEq) {
37
+ return new Proxy(builder, {
38
+ get(st, sp, sr) {
39
+ const sv = Reflect.get(st, sp, sr);
40
+ if (sp === "where" && typeof sv === "function") {
41
+ return (condition, ...wRest) => {
42
+ const c = condition;
43
+ const merged = c ? and(orgEq, c) : orgEq;
44
+ const next = sv.call(st, merged, ...wRest);
45
+ return wrapWhereable(next, orgEq);
46
+ };
47
+ }
48
+ return typeof sv === "function" ? sv.bind(st) : sv;
49
+ },
50
+ });
51
+ }
52
+ /**
53
+ * Pre-apply the org predicate to a WHERE-able builder (UPDATE/DELETE) and wrap
54
+ * its `.where()` so a caller-supplied condition is AND-ed with the org filter
55
+ * rather than replacing it. Pre-applying `orgEq` immediately means a builder
56
+ * executed with NO caller `.where()` (e.g. `update(t).set(...)`) is still
57
+ * constrained to the org — it can never touch another tenant's rows.
58
+ */
59
+ function scopeWhereBuilder(builder, orgEq) {
60
+ return wrapWhereable(builder.where(orgEq), orgEq);
61
+ }
27
62
  export function createScopedDb(rawDb, orgSource) {
28
63
  if (!rawDb || typeof rawDb !== "object")
29
64
  return rawDb;
@@ -76,20 +111,7 @@ export function createScopedDb(rawDb, orgSource) {
76
111
  return chain;
77
112
  const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
78
113
  const inner = chain;
79
- const scoped = inner.where(orgEq);
80
- return new Proxy(scoped, {
81
- get(st, sp, sr) {
82
- const sv = Reflect.get(st, sp, sr);
83
- if (sp === "where" && typeof sv === "function") {
84
- return (condition, ...wRest) => {
85
- const c = condition;
86
- const merged = c ? and(orgEq, c) : orgEq;
87
- return sv.call(st, merged, ...wRest);
88
- };
89
- }
90
- return typeof sv === "function" ? sv.bind(st) : sv;
91
- },
92
- });
114
+ return wrapWhereable(inner.where(orgEq), orgEq);
93
115
  };
94
116
  }
95
117
  return typeof sbVal === "function" ? sbVal.bind(sbTarget) : sbVal;
@@ -97,6 +119,43 @@ export function createScopedDb(rawDb, orgSource) {
97
119
  });
98
120
  };
99
121
  }
122
+ if (prop === "update" && typeof value === "function") {
123
+ return (table) => {
124
+ const builder = value.call(target, table);
125
+ if (!tableHasOrganizationId(table))
126
+ return builder;
127
+ const orgCol = getTableColumns(table).organizationId;
128
+ if (!orgCol)
129
+ return builder;
130
+ const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
131
+ // The org filter lives after `.set()`, so wrap `.set()` and scope the
132
+ // resulting WHERE-able builder.
133
+ return new Proxy(builder, {
134
+ get(t, p, r) {
135
+ const v = Reflect.get(t, p, r);
136
+ if (p === "set" && typeof v === "function") {
137
+ return (data) => {
138
+ const setBuilder = v.call(t, data);
139
+ return scopeWhereBuilder(setBuilder, orgEq);
140
+ };
141
+ }
142
+ return typeof v === "function" ? v.bind(t) : v;
143
+ },
144
+ });
145
+ };
146
+ }
147
+ if (prop === "delete" && typeof value === "function") {
148
+ return (table) => {
149
+ const builder = value.call(target, table);
150
+ if (!tableHasOrganizationId(table))
151
+ return builder;
152
+ const orgCol = getTableColumns(table).organizationId;
153
+ if (!orgCol)
154
+ return builder;
155
+ const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
156
+ return scopeWhereBuilder(builder, orgEq);
157
+ };
158
+ }
100
159
  return typeof value === "function" ? value.bind(target) : value;
101
160
  },
102
161
  });
@@ -18,6 +18,18 @@ export declare class CommerceValidationError extends Error implements CommerceEr
18
18
  code: "VALIDATION_FAILED";
19
19
  constructor(message: string, fieldErrors?: FieldError[] | undefined, details?: unknown | undefined);
20
20
  }
21
+ /** Canonical message for a missing inventory record — the single source used by
22
+ * the inventory repository and mapped to the typed error below. */
23
+ export declare const INVENTORY_RECORD_NOT_FOUND_MESSAGE = "No inventory record found for this entity.";
24
+ /** Raised when an inventory reserve/release targets an entity with no inventory
25
+ * record. Consumers (e.g. order status transitions that tolerate a missing
26
+ * record) discriminate on `code === "INVENTORY_RECORD_NOT_FOUND"`, never the
27
+ * message string. */
28
+ export declare class CommerceInventoryRecordNotFoundError extends Error implements CommerceError {
29
+ details?: unknown | undefined;
30
+ code: "INVENTORY_RECORD_NOT_FOUND";
31
+ constructor(message?: string, details?: unknown | undefined);
32
+ }
21
33
  export declare class CommerceForbiddenError extends Error implements CommerceError {
22
34
  details?: unknown | undefined;
23
35
  code: "FORBIDDEN";
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;mEACmE;AACnE,eAAO,MAAM,kCAAkC,+CACD,CAAC;AAE/C;;;qBAGqB;AACrB,qBAAa,oCAAqC,SAAQ,KAAM,YAAW,aAAa;IAI7E,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,4BAA4B,CAAU;gBAE3C,OAAO,GAAE,MAA2C,EAC7C,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
@@ -18,6 +18,22 @@ export class CommerceValidationError extends Error {
18
18
  this.name = "CommerceValidationError";
19
19
  }
20
20
  }
21
+ /** Canonical message for a missing inventory record — the single source used by
22
+ * the inventory repository and mapped to the typed error below. */
23
+ export const INVENTORY_RECORD_NOT_FOUND_MESSAGE = "No inventory record found for this entity.";
24
+ /** Raised when an inventory reserve/release targets an entity with no inventory
25
+ * record. Consumers (e.g. order status transitions that tolerate a missing
26
+ * record) discriminate on `code === "INVENTORY_RECORD_NOT_FOUND"`, never the
27
+ * message string. */
28
+ export class CommerceInventoryRecordNotFoundError extends Error {
29
+ details;
30
+ code = "INVENTORY_RECORD_NOT_FOUND";
31
+ constructor(message = INVENTORY_RECORD_NOT_FOUND_MESSAGE, details) {
32
+ super(message);
33
+ this.details = details;
34
+ this.name = "CommerceInventoryRecordNotFoundError";
35
+ }
36
+ }
21
37
  export class CommerceForbiddenError extends Error {
22
38
  details;
23
39
  code = "FORBIDDEN";
@@ -1,12 +1,32 @@
1
- /**
2
- * Minimal interface for enqueueing background jobs.
3
- * The full DrizzleJobsAdapter implements this; hooks receive
4
- * it on HookContext.jobs so they can defer work without caring
5
- * about the underlying storage.
6
- */
1
+ import type { JobProcessingOrder, TaskContext, TaskDefinition } from "./types.js";
2
+ /** Enqueue-only surface exposed to hooks and services. */
7
3
  export interface JobsAdapter {
8
4
  enqueue(taskSlug: string, input: Record<string, unknown>, options: EnqueueOptions): Promise<string>;
9
5
  }
6
+ export interface RunJobsOptions {
7
+ queue?: string;
8
+ limit?: number;
9
+ }
10
+ export interface RunJobsResult {
11
+ processed: number;
12
+ failed: number;
13
+ }
14
+ export interface ExecutionEngineSetup {
15
+ tasks: ReadonlyMap<string, TaskDefinition>;
16
+ context: TaskContext;
17
+ processingOrder?: JobProcessingOrder;
18
+ }
19
+ export type ExecutionDriver = {
20
+ mode: "pull";
21
+ run(options?: RunJobsOptions): Promise<RunJobsResult>;
22
+ } | {
23
+ mode: "push";
24
+ };
25
+ /** Full job-engine contract selected through `config.jobs.adapter`. */
26
+ export interface ExecutionEngine extends JobsAdapter {
27
+ readonly execution: ExecutionDriver;
28
+ register(setup: ExecutionEngineSetup): void;
29
+ }
10
30
  export interface EnqueueOptions {
11
31
  organizationId: string;
12
32
  queue?: string;
@@ -16,8 +36,7 @@ export interface EnqueueOptions {
16
36
  supersedes?: boolean;
17
37
  }
18
38
  /**
19
- * No-op adapter used when no jobs backend is configured.
20
- * All enqueue calls silently succeed and return a placeholder ID.
39
+ * No-op enqueue surface used by isolated hook contexts.
21
40
  */
22
41
  export declare class NullJobsAdapter implements JobsAdapter {
23
42
  enqueue(_taskSlug: string, _input: Record<string, unknown>, _options: EnqueueOptions): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAC3C,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC;CAGnB"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,OAAO,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACvD,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,uEAAuE;AACvE,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAC3C,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC;CAGnB"}
@@ -1,6 +1,5 @@
1
1
  /**
2
- * No-op adapter used when no jobs backend is configured.
3
- * All enqueue calls silently succeed and return a placeholder ID.
2
+ * No-op enqueue surface used by isolated hook contexts.
4
3
  */
5
4
  export class NullJobsAdapter {
6
5
  async enqueue(_taskSlug, _input, _options) {
@@ -1,15 +1,25 @@
1
1
  import type { DrizzleDatabase } from "../database/drizzle-db.js";
2
2
  import type { TaskDefinition } from "./types.js";
3
- import type { JobsAdapter, EnqueueOptions } from "./adapter.js";
3
+ import type { EnqueueOptions, ExecutionEngine, ExecutionEngineSetup, RunJobsOptions } from "./adapter.js";
4
4
  /**
5
5
  * PostgreSQL-backed job queue adapter using the application's own database.
6
6
  * Stores jobs in the `commerce_jobs` table. Supports concurrency keys
7
7
  * and supersede semantics for deduplication.
8
8
  */
9
- export declare class DrizzleJobsAdapter implements JobsAdapter {
9
+ export declare class DrizzleJobsAdapter implements ExecutionEngine {
10
10
  private db;
11
11
  private tasks;
12
- constructor(db: DrizzleDatabase, tasks: Map<string, TaskDefinition>);
12
+ private setup;
13
+ private lastStaleJobReaperAt;
14
+ readonly execution: {
15
+ mode: "pull";
16
+ run: (options?: RunJobsOptions) => Promise<{
17
+ processed: number;
18
+ failed: number;
19
+ }>;
20
+ };
21
+ constructor(db: DrizzleDatabase, tasks?: Map<string, TaskDefinition>);
22
+ register(setup: ExecutionEngineSetup): void;
13
23
  enqueue(taskSlug: string, input: Record<string, unknown>, options: EnqueueOptions): Promise<string>;
14
24
  }
15
25
  //# sourceMappingURL=drizzle-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/drizzle-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAIhE;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IAElD,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;gBADL,EAAE,EAAE,eAAe,EACnB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAGtC,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC;CA0CnB"}
1
+ {"version":3,"file":"drizzle-adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/drizzle-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,cAAc,EACf,MAAM,cAAc,CAAC;AAUtB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IA4CtD,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IA5Cf,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,oBAAoB,CAAK;IAEjC,QAAQ,CAAC,SAAS;;wBAEK,cAAc;;;;MAmCnC;gBAGQ,EAAE,EAAE,eAAe,EACnB,KAAK,GAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAa;IAGxD,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI;IAKrC,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC;CA+CnB"}
@@ -1,6 +1,8 @@
1
1
  import { eq, and } from "drizzle-orm";
2
2
  import { OrgResolutionError } from "../errors.js";
3
3
  import { commerceJobs } from "./schema.js";
4
+ import { runPendingJobs } from "./runner.js";
5
+ import { getJobReapThresholdMs, getJobsReaperIntervalMs, runStaleJobReaper, } from "./reaper.js";
4
6
  /**
5
7
  * PostgreSQL-backed job queue adapter using the application's own database.
6
8
  * Stores jobs in the `commerce_jobs` table. Supports concurrency keys
@@ -9,23 +11,62 @@ import { commerceJobs } from "./schema.js";
9
11
  export class DrizzleJobsAdapter {
10
12
  db;
11
13
  tasks;
12
- constructor(db, tasks) {
14
+ setup;
15
+ lastStaleJobReaperAt = 0;
16
+ execution = {
17
+ mode: "pull",
18
+ run: async (options = {}) => {
19
+ if (!this.setup) {
20
+ throw new Error("DrizzleJobsAdapter must be registered before running jobs.");
21
+ }
22
+ const now = Date.now();
23
+ if (now - this.lastStaleJobReaperAt >= getJobsReaperIntervalMs()) {
24
+ this.lastStaleJobReaperAt = now;
25
+ try {
26
+ await runStaleJobReaper(this.db, getJobReapThresholdMs(), this.setup.context.logger);
27
+ }
28
+ catch (error) {
29
+ this.setup.context.logger.error("Stale job reaper failed", {
30
+ error: error instanceof Error ? error.message : String(error),
31
+ });
32
+ }
33
+ }
34
+ return runPendingJobs({
35
+ db: this.db,
36
+ tasks: new Map(this.setup.tasks),
37
+ logger: this.setup.context.logger,
38
+ services: this.setup.context.services,
39
+ ...(options.queue !== undefined ? { queue: options.queue } : {}),
40
+ ...(options.limit !== undefined ? { limit: options.limit } : {}),
41
+ ...(this.setup.processingOrder !== undefined
42
+ ? { processingOrder: this.setup.processingOrder }
43
+ : {}),
44
+ });
45
+ },
46
+ };
47
+ constructor(db, tasks = new Map()) {
13
48
  this.db = db;
14
49
  this.tasks = tasks;
15
50
  }
51
+ register(setup) {
52
+ this.setup = setup;
53
+ this.tasks = new Map(setup.tasks);
54
+ }
16
55
  async enqueue(taskSlug, input, options) {
17
56
  const organizationId = options.organizationId.trim();
18
57
  if (!organizationId) {
19
58
  throw new OrgResolutionError("Jobs enqueue requires a non-empty organizationId.");
20
59
  }
60
+ const task = this.tasks.get(taskSlug);
61
+ const concurrencyKey = options.concurrencyKey ?? task?.concurrency?.key(input);
62
+ const supersedes = options.supersedes ?? task?.concurrency?.supersedes;
21
63
  // If supersedes is set, delete existing pending jobs with the same concurrency key
22
- if (options.concurrencyKey && options.supersedes) {
64
+ if (concurrencyKey && supersedes) {
23
65
  await this.db
24
66
  .delete(commerceJobs)
25
- .where(and(eq(commerceJobs.concurrencyKey, options.concurrencyKey), eq(commerceJobs.status, "pending")));
67
+ .where(and(eq(commerceJobs.organizationId, organizationId), eq(commerceJobs.taskSlug, taskSlug), eq(commerceJobs.concurrencyKey, concurrencyKey), eq(commerceJobs.status, "pending")));
26
68
  }
27
69
  // Look up task definition for default retry config
28
- const task = this.tasks.get(taskSlug);
29
70
  const maxAttempts = options.maxAttempts ?? task?.retries?.attempts ?? 1;
30
71
  const rows = await this.db
31
72
  .insert(commerceJobs)
@@ -38,7 +79,7 @@ export class DrizzleJobsAdapter {
38
79
  waitUntil: options.delayMs
39
80
  ? new Date(Date.now() + options.delayMs)
40
81
  : null,
41
- concurrencyKey: options.concurrencyKey ?? null,
82
+ concurrencyKey: concurrencyKey ?? null,
42
83
  })
43
84
  .returning({ id: commerceJobs.id });
44
85
  return rows[0].id;
@@ -1,11 +1,12 @@
1
1
  import type { DrizzleDatabase } from "../database/drizzle-db.js";
2
2
  import type { Logger, ServiceContainer } from "../hooks/types.js";
3
- import type { TaskDefinition } from "./types.js";
3
+ import type { JobProcessingOrder, TaskDefinition } from "./types.js";
4
4
  export interface RunPendingJobsArgs {
5
5
  db: DrizzleDatabase;
6
6
  tasks: Map<string, TaskDefinition>;
7
7
  queue?: string;
8
8
  limit?: number;
9
+ processingOrder?: JobProcessingOrder;
9
10
  logger: Logger;
10
11
  services: ServiceContainer;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,eAAe,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAmIhD"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGrE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,eAAe,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AA4CD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkNhD"}