@hszrdm/core 1.4.0 → 1.6.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 (182) hide show
  1. package/.medusa/server/src/admin/index.js +6361 -3789
  2. package/.medusa/server/src/admin/index.mjs +6361 -3789
  3. package/.medusa/server/src/api/admin/back-in-stock/route.d.ts +2 -0
  4. package/.medusa/server/src/api/admin/back-in-stock/route.js +70 -0
  5. package/.medusa/server/src/api/admin/core-carts/[id]/items/[itemId]/route.d.ts +3 -0
  6. package/.medusa/server/src/api/admin/core-carts/[id]/items/[itemId]/route.js +64 -0
  7. package/.medusa/server/src/api/admin/core-carts/[id]/items/route.d.ts +2 -0
  8. package/.medusa/server/src/api/admin/core-carts/[id]/items/route.js +40 -0
  9. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/[code]/route.d.ts +2 -0
  10. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/[code]/route.js +40 -0
  11. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/route.d.ts +2 -0
  12. package/.medusa/server/src/api/admin/core-carts/[id]/promotions/route.js +41 -0
  13. package/.medusa/server/src/api/admin/core-carts/[id]/route.d.ts +2 -0
  14. package/.medusa/server/src/api/admin/core-carts/[id]/route.js +28 -0
  15. package/.medusa/server/src/api/admin/core-carts/customer/[id]/route.d.ts +2 -0
  16. package/.medusa/server/src/api/admin/core-carts/customer/[id]/route.js +34 -0
  17. package/.medusa/server/src/api/admin/core-carts/route.d.ts +3 -0
  18. package/.medusa/server/src/api/admin/core-carts/route.js +69 -0
  19. package/.medusa/server/src/api/admin/customer-activation/route.d.ts +2 -0
  20. package/.medusa/server/src/api/admin/customer-activation/route.js +97 -0
  21. package/.medusa/server/src/api/admin/customer-import/route.d.ts +2 -0
  22. package/.medusa/server/src/api/admin/customer-import/route.js +166 -0
  23. package/.medusa/server/src/api/admin/order-export/route.d.ts +2 -0
  24. package/.medusa/server/src/api/admin/order-export/route.js +88 -0
  25. package/.medusa/server/src/api/admin/product-migration/inventory/route.d.ts +3 -0
  26. package/.medusa/server/src/api/admin/product-migration/inventory/route.js +164 -0
  27. package/.medusa/server/src/api/admin/product-migration/price-list-prices/route.d.ts +3 -0
  28. package/.medusa/server/src/api/admin/product-migration/price-list-prices/route.js +204 -0
  29. package/.medusa/server/src/api/admin/product-migration/products/route.d.ts +2 -0
  30. package/.medusa/server/src/api/admin/product-migration/products/route.js +24 -0
  31. package/.medusa/server/src/api/admin/product-reviews/[id]/route.js +36 -4
  32. package/.medusa/server/src/api/admin/product-reviews/settings/route.d.ts +3 -0
  33. package/.medusa/server/src/api/admin/product-reviews/settings/route.js +63 -0
  34. package/.medusa/server/src/api/admin/shared-cart/settings/route.d.ts +5 -0
  35. package/.medusa/server/src/api/admin/shared-cart/settings/route.js +31 -0
  36. package/.medusa/server/src/api/admin/system-runtime/route.d.ts +2 -0
  37. package/.medusa/server/src/api/admin/system-runtime/route.js +18 -0
  38. package/.medusa/server/src/api/hooks/packeta/status/route.d.ts +2 -0
  39. package/.medusa/server/src/api/hooks/packeta/status/route.js +55 -0
  40. package/.medusa/server/src/api/middlewares.js +24 -1
  41. package/.medusa/server/src/api/store/abandoned-cart/recover/route.d.ts +2 -0
  42. package/.medusa/server/src/api/store/abandoned-cart/recover/route.js +37 -0
  43. package/.medusa/server/src/api/store/back-in-stock/route.d.ts +8 -0
  44. package/.medusa/server/src/api/store/back-in-stock/route.js +124 -0
  45. package/.medusa/server/src/api/store/core-carts/me/active/route.d.ts +2 -0
  46. package/.medusa/server/src/api/store/core-carts/me/active/route.js +54 -0
  47. package/.medusa/server/src/api/store/customer-activation/complete/route.d.ts +2 -0
  48. package/.medusa/server/src/api/store/customer-activation/complete/route.js +96 -0
  49. package/.medusa/server/src/api/store/customer-activation/route.d.ts +2 -0
  50. package/.medusa/server/src/api/store/customer-activation/route.js +34 -0
  51. package/.medusa/server/src/api/store/products/[id]/reviews/route.d.ts +1 -0
  52. package/.medusa/server/src/api/store/products/[id]/reviews/route.js +76 -34
  53. package/.medusa/server/src/api/store/review-request/route.d.ts +2 -0
  54. package/.medusa/server/src/api/store/review-request/route.js +60 -0
  55. package/.medusa/server/src/api/store/shared-carts/[token]/route.d.ts +2 -0
  56. package/.medusa/server/src/api/store/shared-carts/[token]/route.js +52 -0
  57. package/.medusa/server/src/api/store/shared-carts/route.d.ts +13 -0
  58. package/.medusa/server/src/api/store/shared-carts/route.js +78 -0
  59. package/.medusa/server/src/core/abandoned-cart.d.ts +64 -0
  60. package/.medusa/server/src/core/abandoned-cart.js +197 -0
  61. package/.medusa/server/src/core/admin-cart-management.d.ts +18 -0
  62. package/.medusa/server/src/core/admin-cart-management.js +102 -0
  63. package/.medusa/server/src/core/admin-cart-visibility.d.ts +94 -0
  64. package/.medusa/server/src/core/admin-cart-visibility.js +192 -0
  65. package/.medusa/server/src/core/back-in-stock.d.ts +51 -0
  66. package/.medusa/server/src/core/back-in-stock.js +107 -0
  67. package/.medusa/server/src/core/cart-observability.d.ts +23 -0
  68. package/.medusa/server/src/core/cart-observability.js +54 -0
  69. package/.medusa/server/src/core/checkout-contract.d.ts +1 -0
  70. package/.medusa/server/src/core/checkout-contract.js +2 -1
  71. package/.medusa/server/src/core/customer-account-contract.d.ts +3 -0
  72. package/.medusa/server/src/core/customer-account-contract.js +4 -1
  73. package/.medusa/server/src/core/customer-activation.d.ts +120 -0
  74. package/.medusa/server/src/core/customer-activation.js +169 -0
  75. package/.medusa/server/src/core/customer-cart-resume.d.ts +21 -0
  76. package/.medusa/server/src/core/customer-cart-resume.js +72 -0
  77. package/.medusa/server/src/core/customer-email.d.ts +1 -1
  78. package/.medusa/server/src/core/customer-email.js +4 -1
  79. package/.medusa/server/src/core/native-migration-export.d.ts +6 -0
  80. package/.medusa/server/src/core/native-migration-export.js +105 -0
  81. package/.medusa/server/src/core/order-export.d.ts +11 -0
  82. package/.medusa/server/src/core/order-export.js +297 -0
  83. package/.medusa/server/src/core/review-request.d.ts +61 -0
  84. package/.medusa/server/src/core/review-request.js +105 -0
  85. package/.medusa/server/src/core/review-reward.d.ts +94 -0
  86. package/.medusa/server/src/core/review-reward.js +124 -0
  87. package/.medusa/server/src/core/runtime-health.d.ts +39 -0
  88. package/.medusa/server/src/core/runtime-health.js +250 -0
  89. package/.medusa/server/src/core/storefront-core-config.d.ts +10 -0
  90. package/.medusa/server/src/core/storefront-core-config.js +26 -1
  91. package/.medusa/server/src/core/version.d.ts +2 -2
  92. package/.medusa/server/src/core/version.js +2 -2
  93. package/.medusa/server/src/jobs/abandoned-cart-recovery.d.ts +23 -0
  94. package/.medusa/server/src/jobs/abandoned-cart-recovery.js +137 -0
  95. package/.medusa/server/src/jobs/back-in-stock-reconciliation.d.ts +15 -0
  96. package/.medusa/server/src/jobs/back-in-stock-reconciliation.js +90 -0
  97. package/.medusa/server/src/jobs/dpd-statusdata-sync.d.ts +17 -0
  98. package/.medusa/server/src/jobs/dpd-statusdata-sync.js +107 -0
  99. package/.medusa/server/src/jobs/mpl-push-tracking.d.ts +19 -0
  100. package/.medusa/server/src/jobs/mpl-push-tracking.js +183 -0
  101. package/.medusa/server/src/jobs/mpl-status-sync.d.ts +8 -2
  102. package/.medusa/server/src/jobs/mpl-status-sync.js +12 -7
  103. package/.medusa/server/src/jobs/product-review-request-dispatch.d.ts +28 -0
  104. package/.medusa/server/src/jobs/product-review-request-dispatch.js +84 -0
  105. package/.medusa/server/src/jobs/runtime-heartbeat.d.ts +12 -0
  106. package/.medusa/server/src/jobs/runtime-heartbeat.js +13 -0
  107. package/.medusa/server/src/jobs/shipping-status-sync.d.ts +8 -2
  108. package/.medusa/server/src/jobs/shipping-status-sync.js +11 -14
  109. package/.medusa/server/src/lib/modules/shipping/idempotency.js +3 -3
  110. package/.medusa/server/src/lib/modules/shipping/index.d.ts +1 -0
  111. package/.medusa/server/src/lib/modules/shipping/index.js +2 -1
  112. package/.medusa/server/src/lib/modules/shipping/tracking.d.ts +48 -0
  113. package/.medusa/server/src/lib/modules/shipping/tracking.js +368 -0
  114. package/.medusa/server/src/lib/modules/shipping/webhooks.d.ts +6 -9
  115. package/.medusa/server/src/lib/modules/shipping/webhooks.js +24 -137
  116. package/.medusa/server/src/modules/back-in-stock/index.d.ts +23 -0
  117. package/.medusa/server/src/modules/back-in-stock/index.js +16 -0
  118. package/.medusa/server/src/modules/back-in-stock/migrations/Migration20261101202000.d.ts +5 -0
  119. package/.medusa/server/src/modules/back-in-stock/migrations/Migration20261101202000.js +18 -0
  120. package/.medusa/server/src/modules/back-in-stock/models/back-in-stock-subscription.d.ts +13 -0
  121. package/.medusa/server/src/modules/back-in-stock/models/back-in-stock-subscription.js +23 -0
  122. package/.medusa/server/src/modules/back-in-stock/service.d.ts +22 -0
  123. package/.medusa/server/src/modules/back-in-stock/service.js +12 -0
  124. package/.medusa/server/src/modules/email-center/abandoned-cart-registration.d.ts +1 -0
  125. package/.medusa/server/src/modules/email-center/abandoned-cart-registration.js +27 -0
  126. package/.medusa/server/src/modules/email-center/back-in-stock-registration.d.ts +1 -0
  127. package/.medusa/server/src/modules/email-center/back-in-stock-registration.js +27 -0
  128. package/.medusa/server/src/modules/email-center/defaults.js +7 -1
  129. package/.medusa/server/src/modules/email-center/index.d.ts +2 -0
  130. package/.medusa/server/src/modules/email-center/index.js +3 -1
  131. package/.medusa/server/src/modules/integration-settings/abandoned-cart-registration.d.ts +1 -0
  132. package/.medusa/server/src/modules/integration-settings/abandoned-cart-registration.js +30 -0
  133. package/.medusa/server/src/modules/integration-settings/index.d.ts +1 -0
  134. package/.medusa/server/src/modules/integration-settings/index.js +2 -1
  135. package/.medusa/server/src/modules/integration-settings/storefront-public-registration.js +15 -1
  136. package/.medusa/server/src/modules/product-review/index.d.ts +14 -0
  137. package/.medusa/server/src/modules/product-review/migrations/Migration20261101113000.d.ts +5 -0
  138. package/.medusa/server/src/modules/product-review/migrations/Migration20261101113000.js +28 -0
  139. package/.medusa/server/src/modules/product-review/migrations/Migration20261101114500.d.ts +5 -0
  140. package/.medusa/server/src/modules/product-review/migrations/Migration20261101114500.js +20 -0
  141. package/.medusa/server/src/modules/product-review/migrations/Migration20261101121500.d.ts +5 -0
  142. package/.medusa/server/src/modules/product-review/migrations/Migration20261101121500.js +18 -0
  143. package/.medusa/server/src/modules/product-review/models/product-review-settings.d.ts +15 -0
  144. package/.medusa/server/src/modules/product-review/models/product-review-settings.js +19 -0
  145. package/.medusa/server/src/modules/product-review/models/product-review.d.ts +6 -2
  146. package/.medusa/server/src/modules/product-review/models/product-review.js +7 -3
  147. package/.medusa/server/src/modules/product-review/service.d.ts +22 -1
  148. package/.medusa/server/src/modules/product-review/service.js +3 -2
  149. package/.medusa/server/src/modules/shared-cart/index.d.ts +21 -0
  150. package/.medusa/server/src/modules/shared-cart/index.js +13 -0
  151. package/.medusa/server/src/modules/shared-cart/migrations/Migration20261102010000.d.ts +5 -0
  152. package/.medusa/server/src/modules/shared-cart/migrations/Migration20261102010000.js +16 -0
  153. package/.medusa/server/src/modules/shared-cart/models/shared-cart.d.ts +10 -0
  154. package/.medusa/server/src/modules/shared-cart/models/shared-cart.js +17 -0
  155. package/.medusa/server/src/modules/shared-cart/service.d.ts +14 -0
  156. package/.medusa/server/src/modules/shared-cart/service.js +11 -0
  157. package/.medusa/server/src/modules/shared-cart/settings.d.ts +7 -0
  158. package/.medusa/server/src/modules/shared-cart/settings.js +64 -0
  159. package/.medusa/server/src/providers/dpd/index.d.ts +2 -0
  160. package/.medusa/server/src/providers/dpd/index.js +3 -1
  161. package/.medusa/server/src/providers/dpd/statusdata-ftp.d.ts +16 -0
  162. package/.medusa/server/src/providers/dpd/statusdata-ftp.js +268 -0
  163. package/.medusa/server/src/providers/dpd/statusdata.d.ts +14 -0
  164. package/.medusa/server/src/providers/dpd/statusdata.js +161 -0
  165. package/.medusa/server/src/providers/mpl/client.d.ts +3 -1
  166. package/.medusa/server/src/providers/mpl/client.js +154 -2
  167. package/.medusa/server/src/providers/mpl/service.js +31 -20
  168. package/.medusa/server/src/providers/mpl/types.d.ts +25 -0
  169. package/.medusa/server/src/providers/mpl/types.js +1 -1
  170. package/.medusa/server/src/providers/packeta/index.d.ts +1 -0
  171. package/.medusa/server/src/providers/packeta/index.js +2 -1
  172. package/.medusa/server/src/providers/packeta/push-tracking.d.ts +8 -0
  173. package/.medusa/server/src/providers/packeta/push-tracking.js +96 -0
  174. package/.medusa/server/src/providers/packeta/service.js +22 -2
  175. package/.medusa/server/src/scripts/core-init.d.ts +1 -1
  176. package/.medusa/server/src/scripts/core-init.js +3 -2
  177. package/.medusa/server/src/subscribers/back-in-stock-inventory-changed.d.ts +7 -0
  178. package/.medusa/server/src/subscribers/back-in-stock-inventory-changed.js +65 -0
  179. package/.medusa/server/src/workflows/link-migrated-customer.d.ts +8 -0
  180. package/.medusa/server/src/workflows/link-migrated-customer.js +17 -0
  181. package/README.md +1 -1
  182. package/package.json +30 -8
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.default = backInStockReconciliation;
5
+ exports.runBatch = runBatch;
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const back_in_stock_1 = require("../core/back-in-stock");
8
+ const back_in_stock_2 = require("../modules/back-in-stock");
9
+ const SUBSCRIPTION_PAGE_SIZE = 1_000;
10
+ const VARIANT_BATCH_SIZE = 250;
11
+ async function backInStockReconciliation(container) {
12
+ const locking = container.resolve("locking");
13
+ try {
14
+ return await locking.execute("job:back-in-stock-reconciliation", () => runBatch(container), { timeout: 1, expire: 840 });
15
+ }
16
+ catch (error) {
17
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
18
+ logger.info(JSON.stringify({
19
+ event: "scheduled_job_skipped_locked",
20
+ job: "back-in-stock-reconciliation",
21
+ message: error instanceof Error ? error.message : String(error),
22
+ }));
23
+ }
24
+ }
25
+ async function runBatch(container) {
26
+ const service = container.resolve(back_in_stock_2.BACK_IN_STOCK_MODULE);
27
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
28
+ const locking = container.resolve("locking");
29
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
30
+ // Build the active waiting-list snapshot before changing any subscription
31
+ // statuses. This avoids offset pagination skipping rows as notifications turn
32
+ // active records into notified records during the dispatch phase.
33
+ const variantIds = new Set();
34
+ let scanned = 0;
35
+ for (let skip = 0;; skip += SUBSCRIPTION_PAGE_SIZE) {
36
+ const subscriptions = await service.listBackInStockSubscriptions({ status: "active" }, { take: SUBSCRIPTION_PAGE_SIZE, skip, order: { created_at: "ASC" } });
37
+ scanned += subscriptions.length;
38
+ for (const subscription of subscriptions) {
39
+ const variantId = String(subscription.variant_id || "").trim();
40
+ if (variantId)
41
+ variantIds.add(variantId);
42
+ }
43
+ if (subscriptions.length < SUBSCRIPTION_PAGE_SIZE)
44
+ break;
45
+ }
46
+ const ids = [...variantIds];
47
+ let sent = 0;
48
+ for (let offset = 0; offset < ids.length; offset += VARIANT_BATCH_SIZE) {
49
+ const batchIds = ids.slice(offset, offset + VARIANT_BATCH_SIZE);
50
+ const { data: variants } = await query.graph({
51
+ entity: "product_variant",
52
+ fields: [
53
+ "id",
54
+ "title",
55
+ "sku",
56
+ "manage_inventory",
57
+ "allow_backorder",
58
+ "metadata",
59
+ "product.id",
60
+ "product.title",
61
+ "product.handle",
62
+ "product.metadata",
63
+ ],
64
+ filters: { id: batchIds },
65
+ });
66
+ for (const variant of variants) {
67
+ try {
68
+ const result = await locking.execute(`back-in-stock:variant:${variant.id}`, () => (0, back_in_stock_1.dispatchBackInStockVariant)({
69
+ container: container,
70
+ query,
71
+ variant,
72
+ }), { timeout: 1, expire: 300 });
73
+ sent += result.sent;
74
+ }
75
+ catch (error) {
76
+ logger.info(JSON.stringify({
77
+ event: "back_in_stock_variant_skipped_or_failed",
78
+ variant_id: variant.id,
79
+ message: error instanceof Error ? error.message : String(error),
80
+ }));
81
+ }
82
+ }
83
+ }
84
+ return { scanned, variants: ids.length, sent };
85
+ }
86
+ exports.config = {
87
+ name: "back-in-stock-reconciliation",
88
+ schedule: "*/15 * * * *",
89
+ };
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFjay1pbi1zdG9jay1yZWNvbmNpbGlhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9qb2JzL2JhY2staW4tc3RvY2stcmVjb25jaWxpYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBWUEsNENBZ0JDO0FBRUQsNEJBdUVDO0FBcEdELHFEQUFxRTtBQUNyRSx5REFBMkY7QUFDM0YsNERBQXdGO0FBRXhGLE1BQU0sc0JBQXNCLEdBQUcsS0FBSyxDQUFBO0FBQ3BDLE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxDQUFBO0FBTWYsS0FBSyxVQUFVLHlCQUF5QixDQUFDLFNBQTBCO0lBQ2hGLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFZLENBQUE7SUFDdkQsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQzFCLGtDQUFrQyxFQUNsQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQ3pCLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQzVCLENBQUE7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pCLEtBQUssRUFBRSw4QkFBOEI7WUFDckMsR0FBRyxFQUFFLDhCQUE4QjtZQUNuQyxPQUFPLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNoRSxDQUFDLENBQUMsQ0FBQTtJQUNMLENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFVLFFBQVEsQ0FBQyxT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
@@ -0,0 +1,17 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types";
2
+ export default function dpdStatusdataSync(container: MedusaContainer): Promise<{
3
+ files: number;
4
+ processedFiles: number;
5
+ records: number;
6
+ matched: number;
7
+ } | undefined>;
8
+ export declare function runBatch(container: MedusaContainer): Promise<{
9
+ files: number;
10
+ processedFiles: number;
11
+ records: number;
12
+ matched: number;
13
+ }>;
14
+ export declare const config: {
15
+ name: string;
16
+ schedule: string;
17
+ };
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.default = dpdStatusdataSync;
5
+ exports.runBatch = runBatch;
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const dpd_1 = require("../providers/dpd");
8
+ const integration_operation_1 = require("../modules/integration-operation");
9
+ const state_1 = require("../modules/integration-operation/state");
10
+ const shipping_1 = require("../lib/modules/shipping");
11
+ async function dpdStatusdataSync(container) {
12
+ if (process.env.DPD_STATUSDATA_ENABLED !== "true")
13
+ return;
14
+ const locking = container.resolve("locking");
15
+ try {
16
+ return await locking.execute("job:dpd-statusdata-sync", () => runBatch(container), { timeout: 1, expire: 14 * 60 });
17
+ }
18
+ catch (error) {
19
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
20
+ logger.info(JSON.stringify({
21
+ event: "scheduled_job_skipped_locked",
22
+ job: "dpd-statusdata-sync",
23
+ message: error instanceof Error ? error.message : String(error),
24
+ }));
25
+ }
26
+ }
27
+ async function runBatch(container) {
28
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
29
+ const orderService = container.resolve("order");
30
+ const operationStore = container.resolve(integration_operation_1.INTEGRATION_OPERATION_MODULE);
31
+ const client = new dpd_1.DpdStatusdataFtpClient((0, dpd_1.dpdStatusdataFtpConfigFromEnv)());
32
+ const files = (await client.listFiles()).sort();
33
+ let processedFiles = 0;
34
+ let records = 0;
35
+ let matched = 0;
36
+ for (const filename of files) {
37
+ const acquired = await (0, state_1.acquireOperation)(operationStore, {
38
+ provider: "dpd",
39
+ operation_type: "statusdata.file",
40
+ entity_type: "statusdata_file",
41
+ entity_id: filename,
42
+ idempotency_key: `dpd:statusdata:file:${filename}`,
43
+ reference_data: {
44
+ replay_safe: true,
45
+ filename,
46
+ },
47
+ });
48
+ if (!acquired.acquired) {
49
+ if (acquired.operation.status === "succeeded")
50
+ continue;
51
+ logger.info(`[dpd-statusdata-sync] ${filename}: a fájl már feldolgozás alatt áll.`);
52
+ continue;
53
+ }
54
+ try {
55
+ const content = await client.readFile(filename);
56
+ const parsed = (0, dpd_1.parseDpdStatusdata)(content);
57
+ let fileMatched = 0;
58
+ let fileUnmatched = 0;
59
+ for (const record of parsed) {
60
+ const result = await (0, shipping_1.applyNormalizedTrackingEvent)({
61
+ orderService,
62
+ operationStore,
63
+ event: (0, dpd_1.dpdStatusdataEvent)(record),
64
+ });
65
+ if (result)
66
+ fileMatched += 1;
67
+ else
68
+ fileUnmatched += 1;
69
+ }
70
+ if (fileUnmatched > 0) {
71
+ // Keep the file replayable. Rows already applied above are independently
72
+ // idempotent, so a later retry only has to match the previously missing rows.
73
+ throw new Error(`${fileUnmatched} DPD Statusdata eseményhez még nem található rendelés.`);
74
+ }
75
+ await (0, state_1.operationSucceeded)(operationStore, acquired.operation, filename, {
76
+ replay_safe: true,
77
+ filename,
78
+ record_count: parsed.length,
79
+ matched_count: fileMatched,
80
+ processed_at: new Date().toISOString(),
81
+ });
82
+ processedFiles += 1;
83
+ records += parsed.length;
84
+ matched += fileMatched;
85
+ }
86
+ catch (error) {
87
+ await (0, state_1.operationFailed)(operationStore, acquired.operation, error, false, filename, {
88
+ replay_safe: true,
89
+ filename,
90
+ });
91
+ logger.warn(`[dpd-statusdata-sync] ${filename}: ${error instanceof Error ? error.message : String(error)}`);
92
+ }
93
+ }
94
+ return {
95
+ files: files.length,
96
+ processedFiles,
97
+ records,
98
+ matched,
99
+ };
100
+ }
101
+ // DPD Hungary generates Statusdata when statuses changed (hourly). Poll the
102
+ // dedicated FTP every 15 minutes so a newly generated file is picked up quickly.
103
+ exports.config = {
104
+ name: "dpd-statusdata-sync",
105
+ schedule: "*/15 * * * *",
106
+ };
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHBkLXN0YXR1c2RhdGEtc3luYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9qb2JzL2RwZC1zdGF0dXNkYXRhLXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBc0JBLG9DQXlCQztBQUVELDRCQStGQztBQS9JRCxxREFBcUU7QUFDckUsMENBS3lCO0FBQ3pCLDRFQUd5QztBQUN6QyxrRUFJK0M7QUFDL0Msc0RBR2dDO0FBRWpCLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxTQUEwQjtJQUN4RSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLEtBQUssTUFBTTtRQUFFLE9BQU07SUFFekQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBTTFDLENBQUE7SUFFRCxJQUFJLENBQUM7UUFDSCxPQUFPLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FDMUIseUJBQXlCLEVBQ3pCLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFDekIsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQ2hDLENBQUE7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pCLEtBQUssRUFBRSw4QkFBOEI7WUFDckMsR0FBRyxFQUFFLHFCQUFxQjtZQUMxQixPQUFPLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNoRSxDQUFDLENBQUMsQ0FBQTtJQUNMLENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFV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
@@ -0,0 +1,19 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types";
2
+ export default function mplPushTracking(container: MedusaContainer): Promise<{
3
+ records: number;
4
+ applied: number;
5
+ malformed: number;
6
+ unmatched: number;
7
+ lastRead: string | null;
8
+ } | undefined>;
9
+ export declare function runBatch(container: MedusaContainer): Promise<{
10
+ records: number;
11
+ applied: number;
12
+ malformed: number;
13
+ unmatched: number;
14
+ lastRead: string | null;
15
+ }>;
16
+ export declare const config: {
17
+ name: string;
18
+ schedule: string;
19
+ };
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.default = mplPushTracking;
5
+ exports.runBatch = runBatch;
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const mpl_1 = require("../providers/mpl");
8
+ const integration_operation_1 = require("../modules/integration-operation");
9
+ const shipping_1 = require("../lib/modules/shipping");
10
+ const STATE_KEY = "mpl:tracking:push:subscription";
11
+ const TOKEN_RENEW_AFTER_MS = 23 * 60 * 60 * 1000;
12
+ async function mplPushTracking(container) {
13
+ if (process.env.MPL_ENABLED !== "true" ||
14
+ process.env.MPL_PUSH_TRACKING_ENABLED !== "true") {
15
+ return;
16
+ }
17
+ const locking = container.resolve("locking");
18
+ try {
19
+ return await locking.execute("job:mpl-push-tracking", () => runBatch(container), { timeout: 1, expire: 14 * 60 });
20
+ }
21
+ catch (error) {
22
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
23
+ logger.info(JSON.stringify({
24
+ event: "scheduled_job_skipped_locked",
25
+ job: "mpl-push-tracking",
26
+ message: error instanceof Error ? error.message : String(error),
27
+ }));
28
+ }
29
+ }
30
+ async function runBatch(container) {
31
+ const operationStore = container.resolve(integration_operation_1.INTEGRATION_OPERATION_MODULE);
32
+ const orderService = container.resolve("order");
33
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
34
+ const state = await loadOrCreateState(operationStore);
35
+ const reference = state.reference_data && typeof state.reference_data === "object"
36
+ ? state.reference_data
37
+ : {};
38
+ let subscriptionToken = text(reference.subscription_token);
39
+ let subscribedAt = dateValue(reference.subscribed_at);
40
+ let lastRead = text(reference.last_read) || undefined;
41
+ const tokenExpired = !subscriptionToken || !subscribedAt ||
42
+ Date.now() - subscribedAt.getTime() >= TOKEN_RENEW_AFTER_MS;
43
+ if (tokenExpired) {
44
+ subscriptionToken = await mpl_1.mplService.client.subscribePushTracking();
45
+ subscribedAt = new Date();
46
+ // lastRead is intentionally preserved across subscription renewal. MPL keeps
47
+ // events for 24 hours and officially supports reconnecting with lastRead.
48
+ }
49
+ const records = await mpl_1.mplService.client.readPushTracking(subscriptionToken, lastRead);
50
+ let applied = 0;
51
+ let malformed = 0;
52
+ let unmatched = 0;
53
+ let newestLastRead = lastRead;
54
+ let blockedPackageId;
55
+ let blockedInsertedAt;
56
+ for (const record of records) {
57
+ const packageId = text(record.PackageId);
58
+ const insertedAt = text(record.InsertedAt) || undefined;
59
+ if (!packageId) {
60
+ malformed += 1;
61
+ logger.warn("[mpl-push-tracking] MPL PUSH rekord PackageId nélkül; a rekord kihagyva.");
62
+ // A malformed provider record can never be correlated. Advancing over it
63
+ // prevents one invalid record from permanently blocking the stream.
64
+ newestLastRead = laterTimestamp(newestLastRead, insertedAt) || newestLastRead;
65
+ continue;
66
+ }
67
+ const occurredAt = text(record.EventDateTime) || undefined;
68
+ const status = (0, shipping_1.mapMplPushStatus)(record.PackageStatus, record.PackageStatusText);
69
+ const result = await (0, shipping_1.applyNormalizedTrackingEvent)({
70
+ orderService,
71
+ operationStore,
72
+ event: {
73
+ carrier: "mpl",
74
+ shipmentIdentifiers: [packageId],
75
+ status,
76
+ rawStatus: text(record.PackageStatus) || null,
77
+ statusText: text(record.PackageStatusText) || null,
78
+ occurredAt: occurredAt || insertedAt || null,
79
+ eventId: text(record.TrackingRecordId) || null,
80
+ source: "push",
81
+ trackingNumber: packageId,
82
+ extra: {
83
+ lastEvent: text(record.PackageStatusText) || undefined,
84
+ lastEventCategory: text(record.PackageStatus) || undefined,
85
+ lastEventAt: occurredAt || insertedAt,
86
+ trackingSource: "push",
87
+ eventPlace: text(record.EventPlace) || undefined,
88
+ insertedAt,
89
+ },
90
+ },
91
+ });
92
+ if (!result) {
93
+ // Do not checkpoint past an event whose order is not visible yet. On the
94
+ // next reconnect MPL replays it from lastRead; the failed event operation
95
+ // itself is retry-safe through the existing idempotency machinery.
96
+ unmatched += 1;
97
+ blockedPackageId = packageId;
98
+ blockedInsertedAt = insertedAt;
99
+ break;
100
+ }
101
+ applied += 1;
102
+ newestLastRead = laterTimestamp(newestLastRead, insertedAt) || newestLastRead;
103
+ }
104
+ await operationStore.updateIntegrationOperations({
105
+ id: state.id,
106
+ status: "succeeded",
107
+ error_summary: unmatched
108
+ ? "Az MPL PUSH cursor egy még nem párosítható esemény előtt megállt; a következő futás újrapróbálja."
109
+ : null,
110
+ completed_at: new Date(),
111
+ reference_data: {
112
+ replay_safe: true,
113
+ subscription_token: subscriptionToken,
114
+ subscribed_at: subscribedAt?.toISOString() || new Date().toISOString(),
115
+ last_read: newestLastRead || null,
116
+ last_poll_at: new Date().toISOString(),
117
+ last_record_count: records.length,
118
+ last_applied_count: applied,
119
+ last_malformed_count: malformed,
120
+ last_unmatched_count: unmatched,
121
+ blocked_package_id: blockedPackageId || null,
122
+ blocked_inserted_at: blockedInsertedAt || null,
123
+ },
124
+ });
125
+ return {
126
+ records: records.length,
127
+ applied,
128
+ malformed,
129
+ unmatched,
130
+ lastRead: newestLastRead || null,
131
+ };
132
+ }
133
+ async function loadOrCreateState(store) {
134
+ const [existing] = await store.listIntegrationOperations({ idempotency_key: STATE_KEY }, { take: 1 });
135
+ if (existing)
136
+ return existing;
137
+ try {
138
+ return await store.createIntegrationOperations({
139
+ provider: "mpl",
140
+ operation_type: "tracking.push.subscription",
141
+ entity_type: "tracking_subscription",
142
+ entity_id: "global",
143
+ idempotency_key: STATE_KEY,
144
+ status: "succeeded",
145
+ attempts: 1,
146
+ error_summary: null,
147
+ next_attempt_at: null,
148
+ completed_at: new Date(),
149
+ reference_data: { replay_safe: true },
150
+ });
151
+ }
152
+ catch (error) {
153
+ const [raced] = await store.listIntegrationOperations({ idempotency_key: STATE_KEY }, { take: 1 });
154
+ if (raced)
155
+ return raced;
156
+ throw error;
157
+ }
158
+ }
159
+ function text(value) {
160
+ return value == null ? "" : String(value).trim();
161
+ }
162
+ function dateValue(value) {
163
+ const date = value ? new Date(String(value)) : null;
164
+ return date && !Number.isNaN(date.getTime()) ? date : null;
165
+ }
166
+ function laterTimestamp(left, right) {
167
+ if (!right)
168
+ return left;
169
+ if (!left)
170
+ return right;
171
+ const leftTime = Date.parse(left);
172
+ const rightTime = Date.parse(right);
173
+ if (!Number.isFinite(leftTime))
174
+ return right;
175
+ if (!Number.isFinite(rightTime))
176
+ return left;
177
+ return rightTime > leftTime ? right : left;
178
+ }
179
+ exports.config = {
180
+ name: "mpl-push-tracking",
181
+ schedule: "*/15 * * * *",
182
+ };
183
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBsLXB1c2gtdHJhY2tpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvam9icy9tcGwtcHVzaC10cmFja2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFnQkEsa0NBOEJDO0FBRUQsNEJBa0hDO0FBaktELHFEQUFxRTtBQUNyRSwwQ0FBNkM7QUFDN0MsNEVBR3lDO0FBQ3pDLHNEQUlnQztBQUVoQyxNQUFNLFNBQVMsR0FBRyxnQ0FBZ0MsQ0FBQTtBQUNsRCxNQUFNLG9CQUFvQixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQTtBQUVqQyxLQUFLLFVBQVUsZUFBZSxDQUFDLFNBQTBCO0lBQ3RFLElBQ0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEtBQUssTUFBTTtRQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixLQUFLLE1BQU0sRUFDaEQsQ0FBQztRQUNELE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBTTFDLENBQUE7SUFFRCxJQUFJLENBQUM7UUFDSCxPQUFPLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FDMUIsdUJBQXVCLEVBQ3ZCLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFDekIsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQ2hDLENBQUE7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pCLEtBQUssRUFBRSw4QkFBOEI7WUFDckMsR0FBRyxFQUFFLG1CQUFtQjtZQUN4QixPQUFPLEVB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
@@ -1,6 +1,12 @@
1
1
  import type { MedusaContainer } from "@medusajs/framework/types";
2
- export default function mplStatusSync(container: MedusaContainer): Promise<void>;
3
- export declare function runBatch(container: MedusaContainer): Promise<void>;
2
+ export default function mplStatusSync(container: MedusaContainer): Promise<{
3
+ scanned: number;
4
+ refreshed: number;
5
+ } | undefined>;
6
+ export declare function runBatch(container: MedusaContainer): Promise<{
7
+ scanned: number;
8
+ refreshed: number;
9
+ }>;
4
10
  export declare const config: {
5
11
  name: string;
6
12
  schedule: string;
@@ -7,14 +7,13 @@ const utils_1 = require("@medusajs/framework/utils");
7
7
  const shipping_1 = require("../lib/modules/shipping");
8
8
  const TERMINAL = new Set(["DELIVERED", "RETURNED", "CANCELLED"]);
9
9
  const PAGE_SIZE = 200;
10
- const MAX_ORDERS_SCANNED = 2000;
11
10
  async function mplStatusSync(container) {
12
11
  if (process.env.MPL_ENABLED !== "true" || process.env.MPL_TRACKING_ENABLED !== "true") {
13
12
  return;
14
13
  }
15
14
  const locking = container.resolve("locking");
16
15
  try {
17
- return await locking.execute("job:mpl-status-sync", () => runBatch(container), { timeout: 1, expire: 3 * 60 * 60 + 50 * 60 });
16
+ return await locking.execute("job:mpl-status-sync", () => runBatch(container), { timeout: 1, expire: 55 * 60 });
18
17
  }
19
18
  catch (error) {
20
19
  const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
@@ -27,9 +26,12 @@ async function mplStatusSync(container) {
27
26
  }
28
27
  async function runBatch(container) {
29
28
  const orderService = container.resolve("order");
30
- for (let skip = 0; skip < MAX_ORDERS_SCANNED; skip += PAGE_SIZE) {
29
+ let scanned = 0;
30
+ let refreshed = 0;
31
+ for (let skip = 0;; skip += PAGE_SIZE) {
31
32
  const orders = await orderService.listOrders({}, { take: PAGE_SIZE, skip, order: { created_at: "DESC" } });
32
33
  for (const order of orders) {
34
+ scanned += 1;
33
35
  if ((0, shipping_1.carrierForOrder)(order) !== "mpl")
34
36
  continue;
35
37
  const shipment = order.metadata?.mpl;
@@ -42,8 +44,9 @@ async function runBatch(container) {
42
44
  orderService,
43
45
  orderId: order.id,
44
46
  action: "status",
45
- actorId: "mpl-four-hour-status-sync",
47
+ actorId: "mpl-hourly-status-sync",
46
48
  });
49
+ refreshed += 1;
47
50
  }
48
51
  catch (error) {
49
52
  console.error(`[mpl-status-sync] ${order.id}:`, error instanceof Error ? error.message : error);
@@ -52,7 +55,9 @@ async function runBatch(container) {
52
55
  if (orders.length < PAGE_SIZE)
53
56
  break;
54
57
  }
58
+ return { scanned, refreshed };
55
59
  }
56
- // Magyar Posta tracking guidance discourages frequent repeated queries for the same item.
57
- exports.config = { name: "mpl-status-sync", schedule: "15 */4 * * *" };
58
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBsLXN0YXR1cy1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2pvYnMvbXBsLXN0YXR1cy1zeW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVlBLGdDQTZCQztBQUVELDRCQXFDQztBQS9FRCxxREFBcUU7QUFDckUsc0RBSWdDO0FBRWhDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFBO0FBQ2hFLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQTtBQUNyQixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQTtBQUVoQixLQUFLLFVBQVUsYUFBYSxDQUFDLFNBQTBCO0lBQ3BFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEtBQUssTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDdEYsT0FBTTtJQUNSLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FNMUMsQ0FBQTtJQUVELElBQUksQ0FBQztRQUNILE9BQU8sTUFBTSxPQUFPLENBQUMsT0FBTyxDQUMxQixxQkFBcUIsRUFDckIsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUN6QixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FDOUMsQ0FBQTtJQUNILENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNsRSxNQUFNLENBQUMsSUFBSSxDQUNULElBQUksQ0FBQyxTQUFTLENBQUM7WUFDYixLQUFLLEVBQUUsOEJBQThCO1lBQ3JDLEdBQUcsRUFBRSxpQkFBaUI7WUFDdEIsT0FBTyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDaEUsQ0FBQyxDQUNILENBQUE7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVNLEtBQUssVUFBVSxRQUFRLENBQUMsU0FBMEI7SUFDdkQsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQW9DLENBQUE7SUFFbEYsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLGtCQUFrQixFQUFFLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNoRSxNQUFNLE1BQU0sR0FBRyxNQUFNLFlBQVksQ0FBQyxVQUFVLENBQzFDLEVBQUUsRUFDRixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUN6RCxDQUFBO1FBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLElBQUEsMEJBQWUsRUFBQyxLQUFLLENBQUMsS0FBSyxLQUFLO2dCQUFFLFNBQVE7WUFFOUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUEwQyxDQUFBO1lBQzNFLElBQ0UsQ0FBQyxRQUFRLEVBQUUsY0FBYztnQkFDekIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUN6RCxDQUFDO2dCQUNELFNBQVE7WUFDVixDQUFDO1lBRUQsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBQSxnQ0FBcUIsRUFBQztvQkFDMUIsWUFBWTtvQkFDWixPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQ2pCLE1BQU0sRUFBRSxRQUFRO29CQUNoQixPQUFPLEVBQUUsMkJBQTJCO2lCQUNyQyxDQUFDLENBQUE7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLENBQUMsS0FBSyxDQUNYLHFCQUFxQixLQUFLLENBQUMsRUFBRSxHQUFHLEVBQ2hDLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FDL0MsQ0FBQTtZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLFNBQVM7WUFBRSxNQUFLO0lBQ3RDLENBQUM7QUFDSCxDQUFDO0FBRUQsMEZBQTBGO0FBQzdFLFFBQUEsTUFBTSxHQUFHLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsQ0FBQSJ9
60
+ // Magyar Posta PULL guidance says the same tracking ID must not be queried more
61
+ // often than once per hour. PUSH is the primary path; this hourly job is fallback.
62
+ exports.config = { name: "mpl-status-sync", schedule: "15 * * * *" };
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBsLXN0YXR1cy1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2pvYnMvbXBsLXN0YXR1cy1zeW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVdBLGdDQTZCQztBQUVELDRCQTJDQztBQXBGRCxxREFBcUU7QUFDckUsc0RBSWdDO0FBRWhDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFBO0FBQ2hFLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQTtBQUVOLEtBQUssVUFBVSxhQUFhLENBQUMsU0FBMEI7SUFDcEUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUN0RixPQUFNO0lBQ1IsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQU0xQyxDQUFBO0lBRUQsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQzFCLHFCQUFxQixFQUNyQixHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQ3pCLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUNoQyxDQUFBO0lBQ0gsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ2xFLE1BQU0sQ0FBQyxJQUFJLENBQ1QsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNiLEtBQUssRUFBRSw4QkFBOEI7WUFDckMsR0FBRyxFQUFFLGlCQUFpQjtZQUN0QixPQUFPLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNoRSxDQUFDLENBQ0gsQ0FBQTtJQUNILENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFVLFFBQVEsQ0FBQyxTQUEwQjtJQUN2RCxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBb0MsQ0FBQTtJQUNsRixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUE7SUFDZixJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUE7SUFFakIsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEdBQUksSUFBSSxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLE1BQU0sWUFBWSxDQUFDLFVBQVUsQ0FDMUMsRUFBRSxFQUNGLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQ3pELENBQUE7UUFFRCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDLENBQUE7WUFDWixJQUFJLElBQUEsMEJBQWUsRUFBQyxLQUFLLENBQUMsS0FBSyxLQUFLO2dCQUFFLFNBQVE7WUFFOUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUEwQyxDQUFBO1lBQzNFLElBQ0UsQ0FBQyxRQUFRLEVBQUUsY0FBYztnQkFDekIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUN6RCxDQUFDO2dCQUNELFNBQVE7WUFDVixDQUFDO1lBRUQsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBQSxnQ0FBcUIsRUFBQztvQkFDMUIsWUFBWTtvQkFDWixPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQ2pCLE1BQU0sRUFBRSxRQUFRO29CQUNoQixPQUFPLEVBQUUsd0JBQXdCO2lCQUNsQyxDQUFDLENBQUE7Z0JBQ0YsU0FBUyxJQUFJLENBQUMsQ0FBQTtZQUNoQixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLENBQUMsS0FBSyxDQUNYLHFCQUFxQixLQUFLLENBQUMsRUFBRSxHQUFHLEVBQ2hDLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FDL0MsQ0FBQTtZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLFNBQVM7WUFBRSxNQUFLO0lBQ3RDLENBQUM7SUFFRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFBO0FBQy9CLENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsbUZBQW1GO0FBQ3RFLFFBQUEsTUFBTSxHQUFHLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsQ0FBQSJ9
@@ -0,0 +1,28 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types";
2
+ import { type ReviewRequestTrigger } from "../core/review-request";
3
+ export default function productReviewRequestDispatch(container: MedusaContainer): Promise<{
4
+ scanned: number;
5
+ sent: number;
6
+ trigger?: undefined;
7
+ delayDays?: undefined;
8
+ } | {
9
+ scanned: number;
10
+ sent: number;
11
+ trigger: ReviewRequestTrigger;
12
+ delayDays: number;
13
+ } | undefined>;
14
+ export declare function runBatch(container: MedusaContainer): Promise<{
15
+ scanned: number;
16
+ sent: number;
17
+ trigger?: undefined;
18
+ delayDays?: undefined;
19
+ } | {
20
+ scanned: number;
21
+ sent: number;
22
+ trigger: ReviewRequestTrigger;
23
+ delayDays: number;
24
+ }>;
25
+ export declare const config: {
26
+ name: string;
27
+ schedule: string;
28
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.default = productReviewRequestDispatch;
5
+ exports.runBatch = runBatch;
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const product_review_1 = require("../modules/product-review");
8
+ const review_request_1 = require("../core/review-request");
9
+ const PAGE_SIZE = 100;
10
+ const MAX_ORDERS_SCANNED = 2000;
11
+ async function productReviewRequestDispatch(container) {
12
+ const locking = container.resolve("locking");
13
+ try {
14
+ return await locking.execute("job:product-review-request-dispatch", () => runBatch(container), { timeout: 1, expire: 3300 });
15
+ }
16
+ catch (error) {
17
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
18
+ logger.info(JSON.stringify({
19
+ event: "scheduled_job_skipped_locked",
20
+ job: "product-review-request-dispatch",
21
+ message: error instanceof Error ? error.message : String(error),
22
+ }));
23
+ }
24
+ }
25
+ async function runBatch(container) {
26
+ const reviewService = container.resolve(product_review_1.PRODUCT_REVIEW_MODULE);
27
+ const [settings] = await reviewService.listProductReviewSettings({}, { take: 1 });
28
+ if (!settings?.request_email_enabled)
29
+ return { scanned: 0, sent: 0 };
30
+ const trigger = normalizeTrigger(settings.request_trigger);
31
+ const delayDays = Math.max(0, Math.min(90, Math.trunc(Number(settings.request_delay_days) || 0)));
32
+ const orderService = container.resolve("order");
33
+ let scanned = 0;
34
+ let sent = 0;
35
+ for (let skip = 0; skip < MAX_ORDERS_SCANNED; skip += PAGE_SIZE) {
36
+ const orders = await orderService.listOrders({}, {
37
+ take: PAGE_SIZE,
38
+ skip,
39
+ order: { created_at: "DESC" },
40
+ relations: ["items", "customer", "fulfillments"],
41
+ });
42
+ for (const order of orders) {
43
+ scanned += 1;
44
+ if (!order.customer_id || !order.email)
45
+ continue;
46
+ if (order.canceled_at || String(order.status || "").toLowerCase() === "canceled")
47
+ continue;
48
+ if (order.metadata?.review_request_email_sent_at)
49
+ continue;
50
+ if (!Array.isArray(order.items) || !order.items.some((item) => item?.product_id))
51
+ continue;
52
+ const dueAt = (0, review_request_1.reviewRequestDueAt)(order, trigger, delayDays);
53
+ if (!dueAt || dueAt.getTime() > Date.now())
54
+ continue;
55
+ try {
56
+ const result = await (0, review_request_1.sendReviewRequestEmail)({ container: container, order: order });
57
+ if (result?.skipped)
58
+ continue;
59
+ await orderService.updateOrders([{
60
+ id: order.id,
61
+ metadata: {
62
+ ...(order.metadata || {}),
63
+ review_request_email_sent_at: new Date().toISOString(),
64
+ review_request_trigger: trigger,
65
+ review_request_delay_days: delayDays,
66
+ },
67
+ }]);
68
+ sent += 1;
69
+ }
70
+ catch (error) {
71
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
72
+ logger.warn(`[product-review-request-dispatch] ${order.id}: ${error instanceof Error ? error.message : String(error)}`);
73
+ }
74
+ }
75
+ if (orders.length < PAGE_SIZE)
76
+ break;
77
+ }
78
+ return { scanned, sent, trigger, delayDays };
79
+ }
80
+ function normalizeTrigger(value) {
81
+ return value === "order" || value === "fulfillment" || value === "delivery" ? value : "delivery";
82
+ }
83
+ exports.config = { name: "product-review-request-dispatch", schedule: "15 * * * *" };
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1yZXZpZXctcmVxdWVzdC1kaXNwYXRjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9qb2JzL3Byb2R1Y3QtcmV2aWV3LXJlcXVlc3QtZGlzcGF0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUJBLCtDQWtCQztBQUVELDRCQXVEQztBQTNGRCxxREFBcUU7QUFDckUsOERBQTRGO0FBQzVGLDJEQUE4RztBQUU5RyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUE7QUFDckIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUE7QUFXaEIsS0FBSyxVQUFVLDRCQUE0QixDQUFDLFNBQTBCO0lBQ25GLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUUxQyxDQUFBO0lBQ0QsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQzFCLHFDQUFxQyxFQUNyQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQ3pCLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQzdCLENBQUE7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pCLEtBQUssRUFBRSw4QkFBOEI7WUFDckMsR0FBRyxFQUFFLGlDQUFpQztZQUN0QyxPQUFPLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNoRSxDQUFDLENBQUMsQ0FBQTtJQUNMLENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFVLFFBQVEs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