@porulle/core 0.9.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 (103) hide show
  1. package/dist/config/defaults.js +1 -1
  2. package/dist/config/types.d.ts +4 -3
  3. package/dist/config/types.d.ts.map +1 -1
  4. package/dist/generated/plugin-manifest.d.ts +3 -0
  5. package/dist/generated/plugin-manifest.d.ts.map +1 -1
  6. package/dist/generated/plugin-manifest.js +1 -0
  7. package/dist/index.d.ts +5 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/interfaces/rest/router.d.ts.map +1 -1
  11. package/dist/interfaces/rest/router.js +2 -0
  12. package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
  13. package/dist/interfaces/rest/routes/checkout.js +1 -0
  14. package/dist/interfaces/rest/schemas/catalog.d.ts +391 -0
  15. package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
  16. package/dist/interfaces/rest/schemas/responses.d.ts +51 -0
  17. package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
  18. package/dist/interfaces/rest/schemas/search.d.ts +17 -0
  19. package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
  20. package/dist/kernel/database/scoped-db.d.ts.map +1 -1
  21. package/dist/kernel/database/scoped-db.js +21 -23
  22. package/dist/kernel/errors.d.ts +12 -0
  23. package/dist/kernel/errors.d.ts.map +1 -1
  24. package/dist/kernel/errors.js +16 -0
  25. package/dist/kernel/jobs/adapter.d.ts +27 -8
  26. package/dist/kernel/jobs/adapter.d.ts.map +1 -1
  27. package/dist/kernel/jobs/adapter.js +1 -2
  28. package/dist/kernel/jobs/drizzle-adapter.d.ts +13 -3
  29. package/dist/kernel/jobs/drizzle-adapter.d.ts.map +1 -1
  30. package/dist/kernel/jobs/drizzle-adapter.js +46 -5
  31. package/dist/kernel/jobs/runner.d.ts +2 -1
  32. package/dist/kernel/jobs/runner.d.ts.map +1 -1
  33. package/dist/kernel/jobs/runner.js +100 -15
  34. package/dist/kernel/jobs/types.d.ts +13 -0
  35. package/dist/kernel/jobs/types.d.ts.map +1 -1
  36. package/dist/kernel/plugin/manifest.d.ts +2 -0
  37. package/dist/kernel/plugin/manifest.d.ts.map +1 -1
  38. package/dist/kernel/plugin/manifest.js +9 -0
  39. package/dist/modules/catalog/entity-service.d.ts +1 -0
  40. package/dist/modules/catalog/entity-service.d.ts.map +1 -1
  41. package/dist/modules/catalog/entity-service.js +15 -1
  42. package/dist/modules/catalog/repository/index.d.ts +2 -2
  43. package/dist/modules/catalog/repository/index.d.ts.map +1 -1
  44. package/dist/modules/catalog/repository/index.js +9 -1
  45. package/dist/modules/catalog/schema.d.ts +51 -0
  46. package/dist/modules/catalog/schema.d.ts.map +1 -1
  47. package/dist/modules/catalog/schema.js +12 -1
  48. package/dist/modules/catalog/schemas.d.ts +3 -1
  49. package/dist/modules/catalog/schemas.d.ts.map +1 -1
  50. package/dist/modules/channels/adapter.d.ts +117 -0
  51. package/dist/modules/channels/adapter.d.ts.map +1 -0
  52. package/dist/modules/channels/adapter.js +3 -0
  53. package/dist/modules/inventory/repository/index.js +4 -4
  54. package/dist/modules/inventory/service.d.ts.map +1 -1
  55. package/dist/modules/inventory/service.js +7 -3
  56. package/dist/modules/orders/service.d.ts.map +1 -1
  57. package/dist/modules/orders/service.js +7 -4
  58. package/dist/modules/orders/stale-order-cleanup.d.ts.map +1 -1
  59. package/dist/modules/orders/stale-order-cleanup.js +25 -16
  60. package/dist/modules/promotions/repository/index.d.ts +1 -1
  61. package/dist/modules/promotions/repository/index.d.ts.map +1 -1
  62. package/dist/modules/promotions/repository/index.js +6 -3
  63. package/dist/modules/promotions/service.d.ts +1 -0
  64. package/dist/modules/promotions/service.d.ts.map +1 -1
  65. package/dist/modules/promotions/service.js +1 -1
  66. package/dist/modules/webhooks/repository/index.d.ts +1 -1
  67. package/dist/modules/webhooks/repository/index.d.ts.map +1 -1
  68. package/dist/modules/webhooks/repository/index.js +16 -10
  69. package/dist/runtime/kernel.d.ts.map +1 -1
  70. package/dist/runtime/kernel.js +14 -2
  71. package/dist/runtime/server.d.ts +1 -4
  72. package/dist/runtime/server.d.ts.map +1 -1
  73. package/dist/runtime/server.js +16 -34
  74. package/package.json +1 -1
  75. package/src/config/defaults.ts +1 -1
  76. package/src/config/types.ts +7 -3
  77. package/src/generated/plugin-capabilities.d.ts +1 -0
  78. package/src/generated/plugin-manifest.ts +1 -0
  79. package/src/generated/plugin-repositories.d.ts +1 -0
  80. package/src/index.ts +31 -1
  81. package/src/interfaces/rest/router.ts +2 -0
  82. package/src/interfaces/rest/routes/checkout.ts +1 -0
  83. package/src/kernel/database/scoped-db.ts +25 -26
  84. package/src/kernel/errors.ts +20 -0
  85. package/src/kernel/jobs/adapter.ts +39 -8
  86. package/src/kernel/jobs/drizzle-adapter.ts +72 -9
  87. package/src/kernel/jobs/runner.ts +194 -72
  88. package/src/kernel/jobs/types.ts +25 -0
  89. package/src/kernel/plugin/manifest.ts +12 -0
  90. package/src/modules/catalog/entity-service.ts +9 -1
  91. package/src/modules/catalog/repository/index.ts +13 -3
  92. package/src/modules/catalog/schema.ts +33 -18
  93. package/src/modules/catalog/schemas.ts +3 -1
  94. package/src/modules/channels/adapter.ts +139 -0
  95. package/src/modules/inventory/repository/index.ts +4 -4
  96. package/src/modules/inventory/service.ts +12 -2
  97. package/src/modules/orders/service.ts +8 -12
  98. package/src/modules/orders/stale-order-cleanup.ts +35 -24
  99. package/src/modules/promotions/repository/index.ts +6 -2
  100. package/src/modules/promotions/service.ts +2 -0
  101. package/src/modules/webhooks/repository/index.ts +16 -14
  102. package/src/runtime/kernel.ts +16 -2
  103. package/src/runtime/server.ts +22 -42
@@ -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":"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"}
@@ -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"}
@@ -1 +1 @@
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;AA2C3D,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,oBAAoB,GAAG,GAAG,CAwHpF"}
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"}
@@ -26,28 +26,39 @@ function tableHasOrganizationId(table) {
26
26
  }
27
27
  }
28
28
  /**
29
- * Pre-apply the org predicate to a WHERE-able builder (UPDATE/DELETE) and wrap
30
- * its `.where()` so a caller-supplied condition is AND-ed with the org filter
31
- * rather than replacing it. Pre-applying `orgEq` immediately means a builder
32
- * executed with NO caller `.where()` (e.g. `update(t).set(...)`) is still
33
- * constrained to the orgit can never touch another tenant's rows.
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`.
34
35
  */
35
- function scopeWhereBuilder(builder, orgEq) {
36
- const scoped = builder.where(orgEq);
37
- return new Proxy(scoped, {
36
+ function wrapWhereable(builder, orgEq) {
37
+ return new Proxy(builder, {
38
38
  get(st, sp, sr) {
39
39
  const sv = Reflect.get(st, sp, sr);
40
40
  if (sp === "where" && typeof sv === "function") {
41
41
  return (condition, ...wRest) => {
42
42
  const c = condition;
43
43
  const merged = c ? and(orgEq, c) : orgEq;
44
- return sv.call(st, merged, ...wRest);
44
+ const next = sv.call(st, merged, ...wRest);
45
+ return wrapWhereable(next, orgEq);
45
46
  };
46
47
  }
47
48
  return typeof sv === "function" ? sv.bind(st) : sv;
48
49
  },
49
50
  });
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
+ }
51
62
  export function createScopedDb(rawDb, orgSource) {
52
63
  if (!rawDb || typeof rawDb !== "object")
53
64
  return rawDb;
@@ -100,20 +111,7 @@ export function createScopedDb(rawDb, orgSource) {
100
111
  return chain;
101
112
  const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
102
113
  const inner = chain;
103
- const scoped = inner.where(orgEq);
104
- return new Proxy(scoped, {
105
- get(st, sp, sr) {
106
- const sv = Reflect.get(st, sp, sr);
107
- if (sp === "where" && typeof sv === "function") {
108
- return (condition, ...wRest) => {
109
- const c = condition;
110
- const merged = c ? and(orgEq, c) : orgEq;
111
- return sv.call(st, merged, ...wRest);
112
- };
113
- }
114
- return typeof sv === "function" ? sv.bind(st) : sv;
115
- },
116
- });
114
+ return wrapWhereable(inner.where(orgEq), orgEq);
117
115
  };
118
116
  }
119
117
  return typeof sbVal === "function" ? sbVal.bind(sbTarget) : sbVal;
@@ -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"}
@@ -1,5 +1,34 @@
1
1
  import { eq, and, sql } from "drizzle-orm";
2
2
  import { commerceJobs } from "./schema.js";
3
+ function isExclusiveTask(task) {
4
+ return Boolean(task?.concurrency && task.concurrency.exclusive !== false);
5
+ }
6
+ function compareByProcessingOrder(processingOrder) {
7
+ if (typeof processingOrder === "function") {
8
+ return (left, right) => processingOrder({
9
+ ...left,
10
+ input: left.input,
11
+ }, {
12
+ ...right,
13
+ input: right.input,
14
+ });
15
+ }
16
+ const field = processingOrder?.field ?? "createdAt";
17
+ const direction = processingOrder?.direction === "desc" ? -1 : 1;
18
+ return (left, right) => {
19
+ const leftValue = left[field];
20
+ const rightValue = right[field];
21
+ const compared = leftValue instanceof Date && rightValue instanceof Date
22
+ ? leftValue.getTime() - rightValue.getTime()
23
+ : typeof leftValue === "number" && typeof rightValue === "number"
24
+ ? leftValue - rightValue
25
+ : String(leftValue).localeCompare(String(rightValue));
26
+ if (compared !== 0)
27
+ return compared * direction;
28
+ return (left.createdAt.getTime() - right.createdAt.getTime() ||
29
+ left.id.localeCompare(right.id));
30
+ };
31
+ }
3
32
  /**
4
33
  * Claims and processes pending jobs from the `commerce_jobs` table.
5
34
  *
@@ -9,18 +38,38 @@ import { commerceJobs } from "./schema.js";
9
38
  * claim transaction.
10
39
  */
11
40
  export async function runPendingJobs(args) {
12
- const { db, tasks, queue = "default", limit = 10, logger, services, } = args;
13
- let processed = 0;
14
- let failed = 0;
41
+ const { db, tasks, queue = "default", limit = 10, processingOrder, logger, services, } = args;
15
42
  // Phase 1: Claim jobs atomically
16
43
  const claimed = await db.transaction(async (tx) => {
17
- const pending = await tx
44
+ const processing = await tx
45
+ .select({ concurrencyKey: commerceJobs.concurrencyKey })
46
+ .from(commerceJobs)
47
+ .where(eq(commerceJobs.status, "processing"));
48
+ const processingKeys = new Set(processing.flatMap((job) => job.concurrencyKey ? [job.concurrencyKey] : []));
49
+ const candidates = await tx
18
50
  .select()
19
51
  .from(commerceJobs)
20
52
  .where(and(eq(commerceJobs.status, "pending"), eq(commerceJobs.queue, queue), sql `(${commerceJobs.waitUntil} IS NULL OR ${commerceJobs.waitUntil} <= now())`))
21
- .orderBy(commerceJobs.createdAt)
22
- .limit(limit)
23
- .for("update", { skipLocked: true });
53
+ .orderBy(commerceJobs.createdAt);
54
+ candidates.sort(compareByProcessingOrder(processingOrder));
55
+ const pending = [];
56
+ for (const candidate of candidates) {
57
+ if (pending.length >= limit)
58
+ break;
59
+ if (candidate.concurrencyKey &&
60
+ isExclusiveTask(tasks.get(candidate.taskSlug)) &&
61
+ processingKeys.has(candidate.concurrencyKey)) {
62
+ continue;
63
+ }
64
+ const [locked] = await tx
65
+ .select()
66
+ .from(commerceJobs)
67
+ .where(and(eq(commerceJobs.id, candidate.id), eq(commerceJobs.status, "pending")))
68
+ .limit(1)
69
+ .for("update", { skipLocked: true });
70
+ if (locked)
71
+ pending.push(locked);
72
+ }
24
73
  for (const job of pending) {
25
74
  await tx
26
75
  .update(commerceJobs)
@@ -31,10 +80,42 @@ export async function runPendingJobs(args) {
31
80
  })
32
81
  .where(eq(commerceJobs.id, job.id));
33
82
  }
34
- return pending;
83
+ const oldestByKey = new Map();
84
+ const jobsToRun = [];
85
+ const jobsToRelease = [];
86
+ for (const job of pending) {
87
+ if (!job.concurrencyKey || !isExclusiveTask(tasks.get(job.taskSlug))) {
88
+ jobsToRun.push(job);
89
+ continue;
90
+ }
91
+ const oldest = oldestByKey.get(job.concurrencyKey);
92
+ if (!oldest) {
93
+ oldestByKey.set(job.concurrencyKey, job);
94
+ continue;
95
+ }
96
+ if (job.createdAt < oldest.createdAt) {
97
+ oldestByKey.set(job.concurrencyKey, job);
98
+ jobsToRelease.push(oldest);
99
+ }
100
+ else {
101
+ jobsToRelease.push(job);
102
+ }
103
+ }
104
+ jobsToRun.push(...oldestByKey.values());
105
+ for (const job of jobsToRelease) {
106
+ await tx
107
+ .update(commerceJobs)
108
+ .set({
109
+ status: "pending",
110
+ processingStartedAt: null,
111
+ updatedAt: new Date(),
112
+ })
113
+ .where(eq(commerceJobs.id, job.id));
114
+ }
115
+ return jobsToRun.sort(compareByProcessingOrder(processingOrder));
35
116
  });
36
117
  // Phase 2: Execute each claimed job outside the claim transaction
37
- for (const job of claimed) {
118
+ const outcomes = await Promise.all(claimed.map(async (job) => {
38
119
  const task = tasks.get(job.taskSlug);
39
120
  if (!task) {
40
121
  logger.warn("Unknown task slug — job marked as failed. Register the task handler in config.jobs.tasks.", {
@@ -50,8 +131,7 @@ export async function runPendingJobs(args) {
50
131
  completedAt: new Date(),
51
132
  })
52
133
  .where(eq(commerceJobs.id, job.id));
53
- failed++;
54
- continue;
134
+ return "failed";
55
135
  }
56
136
  try {
57
137
  const result = await task.handler({
@@ -72,7 +152,7 @@ export async function runPendingJobs(args) {
72
152
  completedAt: new Date(),
73
153
  })
74
154
  .where(eq(commerceJobs.id, job.id));
75
- processed++;
155
+ return "processed";
76
156
  }
77
157
  catch (err) {
78
158
  logger.error("Job handler failed", {
@@ -93,7 +173,7 @@ export async function runPendingJobs(args) {
93
173
  completedAt: new Date(),
94
174
  })
95
175
  .where(eq(commerceJobs.id, job.id));
96
- failed++;
176
+ return "failed";
97
177
  }
98
178
  else {
99
179
  // Compute backoff delay
@@ -108,11 +188,16 @@ export async function runPendingJobs(args) {
108
188
  error: err instanceof Error ? err.message : String(err),
109
189
  attempts,
110
190
  waitUntil: new Date(Date.now() + delay),
191
+ processingStartedAt: null,
111
192
  updatedAt: new Date(),
112
193
  })
113
194
  .where(eq(commerceJobs.id, job.id));
195
+ return "retrying";
114
196
  }
115
197
  }
116
- }
117
- return { processed, failed };
198
+ }));
199
+ return {
200
+ processed: outcomes.filter((outcome) => outcome === "processed").length,
201
+ failed: outcomes.filter((outcome) => outcome === "failed").length,
202
+ };
118
203
  }
@@ -16,6 +16,19 @@ export interface TaskRetryConfig {
16
16
  delay: number;
17
17
  };
18
18
  }
19
+ export interface JobProcessingOrderRecord {
20
+ id: string;
21
+ taskSlug: string;
22
+ input: Record<string, unknown>;
23
+ attempts: number;
24
+ createdAt: Date;
25
+ updatedAt: Date;
26
+ }
27
+ export type JobProcessingOrderField = "createdAt" | "updatedAt" | "attempts" | "taskSlug";
28
+ export type JobProcessingOrder = {
29
+ field: JobProcessingOrderField;
30
+ direction?: "asc" | "desc";
31
+ } | ((left: JobProcessingOrderRecord, right: JobProcessingOrderRecord) => number);
19
32
  /** Present when the handler is invoked by `runPendingJobs` (not for ad-hoc calls). */
20
33
  export interface TaskJobMeta {
21
34
  attemptNumber: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,eAAO,MAAM,sBAAsB;;;CAGzB,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,sFAAsF;AACtF,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc,CAC7B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,CAAC,EAAE,WAAW,CAAC;KACnB,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;CACH"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,eAAO,MAAM,sBAAsB;;;CAGzB,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAC/B,WAAW,GACX,WAAW,GACX,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,MAAM,kBAAkB,GAC1B;IACE,KAAK,EAAE,uBAAuB,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC5B,GACD,CAAC,CACC,IAAI,EAAE,wBAAwB,EAC9B,KAAK,EAAE,wBAAwB,KAC5B,MAAM,CAAC,CAAC;AAEjB,sFAAsF;AACtF,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc,CAC7B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,CAAC,EAAE,WAAW,CAAC;KACnB,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;CACH"}
@@ -1,6 +1,7 @@
1
1
  import type { RouteConfig } from "@hono/zod-openapi";
2
2
  import type { PluginDb } from "../database/plugin-types.js";
3
3
  import type { CommerceConfig, CommercePlugin, PluginPermission } from "../../config/types.js";
4
+ import type { TaskDefinition } from "../jobs/types.js";
4
5
  export interface PluginLogger {
5
6
  info(message: string, data?: unknown): void;
6
7
  warn(message: string, data?: unknown): void;
@@ -76,6 +77,7 @@ export interface CommercePluginManifest {
76
77
  hooks?: () => PluginHookRegistration[];
77
78
  routes?: (ctx: PluginContext) => PluginRouteRegistration[];
78
79
  analyticsModels?: () => unknown[];
80
+ jobs?: () => TaskDefinition[];
79
81
  /**
80
82
  * Named API-key scopes this plugin mints credentials under (issue #51),
81
83
  * merged into `config.auth.apiKeyScopes`. User-defined scopes with the
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/kernel/plugin/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/kernel/plugin/manifest.ts"],"names":[],"mappings":"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"}