@open-mercato/core 0.4.7-develop-0a657b411f → 0.4.7-develop-e249d3e7d0

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 (278) hide show
  1. package/dist/generated/entities/carrier_shipment/index.js +37 -0
  2. package/dist/generated/entities/carrier_shipment/index.js.map +7 -0
  3. package/dist/generated/entities/gateway_transaction/index.js +47 -0
  4. package/dist/generated/entities/gateway_transaction/index.js.map +7 -0
  5. package/dist/generated/entities/webhook_processed_event/index.js +17 -0
  6. package/dist/generated/entities/webhook_processed_event/index.js.map +7 -0
  7. package/dist/generated/entities.ids.generated.js +10 -1
  8. package/dist/generated/entities.ids.generated.js.map +2 -2
  9. package/dist/generated/entity-fields-registry.js +6 -0
  10. package/dist/generated/entity-fields-registry.js.map +2 -2
  11. package/dist/modules/data_sync/api/runs/[id]/cancel.js +14 -5
  12. package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
  13. package/dist/modules/data_sync/backend/data-sync/page.meta.js +2 -2
  14. package/dist/modules/data_sync/backend/data-sync/page.meta.js.map +1 -1
  15. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +37 -12
  16. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
  17. package/dist/modules/directory/api/get/tenants/lookup.js +1 -0
  18. package/dist/modules/directory/api/get/tenants/lookup.js.map +2 -2
  19. package/dist/modules/integrations/api/[id]/route.js +38 -11
  20. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  21. package/dist/modules/integrations/api/logs/route.js +52 -26
  22. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  23. package/dist/modules/integrations/api/route.js +37 -7
  24. package/dist/modules/integrations/api/route.js.map +2 -2
  25. package/dist/modules/integrations/api/umes-read.js +121 -0
  26. package/dist/modules/integrations/api/umes-read.js.map +7 -0
  27. package/dist/modules/integrations/backend/integrations/[id]/page.js +715 -183
  28. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  29. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +30 -9
  30. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  31. package/dist/modules/integrations/backend/integrations/detail-page-widgets.js +46 -0
  32. package/dist/modules/integrations/backend/integrations/detail-page-widgets.js.map +7 -0
  33. package/dist/modules/integrations/backend/integrations/page.js +78 -62
  34. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  35. package/dist/modules/integrations/backend/integrations/page.meta.js +2 -2
  36. package/dist/modules/integrations/backend/integrations/page.meta.js.map +1 -1
  37. package/dist/modules/integrations/setup.js +2 -2
  38. package/dist/modules/integrations/setup.js.map +2 -2
  39. package/dist/modules/payment_gateways/acl.js +12 -0
  40. package/dist/modules/payment_gateways/acl.js.map +7 -0
  41. package/dist/modules/payment_gateways/api/cancel/route.js +55 -0
  42. package/dist/modules/payment_gateways/api/cancel/route.js.map +7 -0
  43. package/dist/modules/payment_gateways/api/capture/route.js +55 -0
  44. package/dist/modules/payment_gateways/api/capture/route.js.map +7 -0
  45. package/dist/modules/payment_gateways/api/interceptors.js +24 -0
  46. package/dist/modules/payment_gateways/api/interceptors.js.map +7 -0
  47. package/dist/modules/payment_gateways/api/openapi.js +5 -0
  48. package/dist/modules/payment_gateways/api/openapi.js.map +7 -0
  49. package/dist/modules/payment_gateways/api/refund/route.js +56 -0
  50. package/dist/modules/payment_gateways/api/refund/route.js.map +7 -0
  51. package/dist/modules/payment_gateways/api/sessions/route.js +74 -0
  52. package/dist/modules/payment_gateways/api/sessions/route.js.map +7 -0
  53. package/dist/modules/payment_gateways/api/status/route.js +66 -0
  54. package/dist/modules/payment_gateways/api/status/route.js.map +7 -0
  55. package/dist/modules/payment_gateways/api/transactions/[id]/route.js +118 -0
  56. package/dist/modules/payment_gateways/api/transactions/[id]/route.js.map +7 -0
  57. package/dist/modules/payment_gateways/api/transactions/route.js +113 -0
  58. package/dist/modules/payment_gateways/api/transactions/route.js.map +7 -0
  59. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +136 -0
  60. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +7 -0
  61. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +496 -0
  62. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +7 -0
  63. package/dist/modules/payment_gateways/backend/payment-gateways/page.meta.js +23 -0
  64. package/dist/modules/payment_gateways/backend/payment-gateways/page.meta.js.map +7 -0
  65. package/dist/modules/payment_gateways/data/enrichers.js +5 -0
  66. package/dist/modules/payment_gateways/data/enrichers.js.map +7 -0
  67. package/dist/modules/payment_gateways/data/entities.js +131 -0
  68. package/dist/modules/payment_gateways/data/entities.js.map +7 -0
  69. package/dist/modules/payment_gateways/data/validators.js +57 -0
  70. package/dist/modules/payment_gateways/data/validators.js.map +7 -0
  71. package/dist/modules/payment_gateways/di.js +16 -0
  72. package/dist/modules/payment_gateways/di.js.map +7 -0
  73. package/dist/modules/payment_gateways/events.js +21 -0
  74. package/dist/modules/payment_gateways/events.js.map +7 -0
  75. package/dist/modules/payment_gateways/i18n/en.js +6 -0
  76. package/dist/modules/payment_gateways/i18n/en.js.map +7 -0
  77. package/dist/modules/payment_gateways/i18n/pl.js +6 -0
  78. package/dist/modules/payment_gateways/i18n/pl.js.map +7 -0
  79. package/dist/modules/payment_gateways/index.js +9 -0
  80. package/dist/modules/payment_gateways/index.js.map +7 -0
  81. package/dist/modules/payment_gateways/lib/gateway-service.js +378 -0
  82. package/dist/modules/payment_gateways/lib/gateway-service.js.map +7 -0
  83. package/dist/modules/payment_gateways/lib/queue.js +17 -0
  84. package/dist/modules/payment_gateways/lib/queue.js.map +7 -0
  85. package/dist/modules/payment_gateways/lib/status-machine.js +29 -0
  86. package/dist/modules/payment_gateways/lib/status-machine.js.map +7 -0
  87. package/dist/modules/payment_gateways/lib/webhook-processor.js +88 -0
  88. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +7 -0
  89. package/dist/modules/payment_gateways/lib/webhook-utils.js +42 -0
  90. package/dist/modules/payment_gateways/lib/webhook-utils.js.map +7 -0
  91. package/dist/modules/payment_gateways/migrations/Migration20260305122155.js +19 -0
  92. package/dist/modules/payment_gateways/migrations/Migration20260305122155.js.map +7 -0
  93. package/dist/modules/payment_gateways/setup.js +13 -0
  94. package/dist/modules/payment_gateways/setup.js.map +7 -0
  95. package/dist/modules/payment_gateways/widgets/injection-table.js +7 -0
  96. package/dist/modules/payment_gateways/widgets/injection-table.js.map +7 -0
  97. package/dist/modules/payment_gateways/workers/status-poller.js +44 -0
  98. package/dist/modules/payment_gateways/workers/status-poller.js.map +7 -0
  99. package/dist/modules/payment_gateways/workers/webhook-processor.js +20 -0
  100. package/dist/modules/payment_gateways/workers/webhook-processor.js.map +7 -0
  101. package/dist/modules/sales/data/enrichers.js +72 -0
  102. package/dist/modules/sales/data/enrichers.js.map +7 -0
  103. package/dist/modules/sales/lib/makeSalesLineRoute.js +3 -0
  104. package/dist/modules/sales/lib/makeSalesLineRoute.js.map +2 -2
  105. package/dist/modules/sales/widgets/injection/payment-gateway-config-field/widget.js +29 -0
  106. package/dist/modules/sales/widgets/injection/payment-gateway-config-field/widget.js.map +7 -0
  107. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +23 -0
  108. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +7 -0
  109. package/dist/modules/sales/widgets/injection-table.js +13 -1
  110. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  111. package/dist/modules/shipping_carriers/acl.js +10 -0
  112. package/dist/modules/shipping_carriers/acl.js.map +7 -0
  113. package/dist/modules/shipping_carriers/api/cancel/route.js +55 -0
  114. package/dist/modules/shipping_carriers/api/cancel/route.js.map +7 -0
  115. package/dist/modules/shipping_carriers/api/interceptors.js +21 -0
  116. package/dist/modules/shipping_carriers/api/interceptors.js.map +7 -0
  117. package/dist/modules/shipping_carriers/api/openapi.js +5 -0
  118. package/dist/modules/shipping_carriers/api/openapi.js.map +7 -0
  119. package/dist/modules/shipping_carriers/api/rates/route.js +55 -0
  120. package/dist/modules/shipping_carriers/api/rates/route.js.map +7 -0
  121. package/dist/modules/shipping_carriers/api/shipments/route.js +61 -0
  122. package/dist/modules/shipping_carriers/api/shipments/route.js.map +7 -0
  123. package/dist/modules/shipping_carriers/api/tracking/route.js +58 -0
  124. package/dist/modules/shipping_carriers/api/tracking/route.js.map +7 -0
  125. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +119 -0
  126. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +7 -0
  127. package/dist/modules/shipping_carriers/data/enrichers.js +82 -0
  128. package/dist/modules/shipping_carriers/data/enrichers.js.map +7 -0
  129. package/dist/modules/shipping_carriers/data/entities.js +80 -0
  130. package/dist/modules/shipping_carriers/data/entities.js.map +7 -0
  131. package/dist/modules/shipping_carriers/data/validators.js +49 -0
  132. package/dist/modules/shipping_carriers/data/validators.js.map +7 -0
  133. package/dist/modules/shipping_carriers/di.js +15 -0
  134. package/dist/modules/shipping_carriers/di.js.map +7 -0
  135. package/dist/modules/shipping_carriers/events.js +19 -0
  136. package/dist/modules/shipping_carriers/events.js.map +7 -0
  137. package/dist/modules/shipping_carriers/i18n/en.js +11 -0
  138. package/dist/modules/shipping_carriers/i18n/en.js.map +7 -0
  139. package/dist/modules/shipping_carriers/i18n/pl.js +11 -0
  140. package/dist/modules/shipping_carriers/i18n/pl.js.map +7 -0
  141. package/dist/modules/shipping_carriers/index.js +9 -0
  142. package/dist/modules/shipping_carriers/index.js.map +7 -0
  143. package/dist/modules/shipping_carriers/lib/adapter-registry.js +29 -0
  144. package/dist/modules/shipping_carriers/lib/adapter-registry.js.map +7 -0
  145. package/dist/modules/shipping_carriers/lib/adapter.js +1 -0
  146. package/dist/modules/shipping_carriers/lib/adapter.js.map +7 -0
  147. package/dist/modules/shipping_carriers/lib/queue.js +17 -0
  148. package/dist/modules/shipping_carriers/lib/queue.js.map +7 -0
  149. package/dist/modules/shipping_carriers/lib/shipping-service.js +155 -0
  150. package/dist/modules/shipping_carriers/lib/shipping-service.js.map +7 -0
  151. package/dist/modules/shipping_carriers/lib/status-sync.js +37 -0
  152. package/dist/modules/shipping_carriers/lib/status-sync.js.map +7 -0
  153. package/dist/modules/shipping_carriers/migrations/Migration20260305170000.js +16 -0
  154. package/dist/modules/shipping_carriers/migrations/Migration20260305170000.js.map +7 -0
  155. package/dist/modules/shipping_carriers/setup.js +13 -0
  156. package/dist/modules/shipping_carriers/setup.js.map +7 -0
  157. package/dist/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.js +25 -0
  158. package/dist/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.js.map +7 -0
  159. package/dist/modules/shipping_carriers/widgets/injection/tracking-column/widget.js +23 -0
  160. package/dist/modules/shipping_carriers/widgets/injection/tracking-column/widget.js.map +7 -0
  161. package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js +40 -0
  162. package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js.map +7 -0
  163. package/dist/modules/shipping_carriers/widgets/injection-table.js +24 -0
  164. package/dist/modules/shipping_carriers/widgets/injection-table.js.map +7 -0
  165. package/dist/modules/shipping_carriers/workers/status-poller.js +21 -0
  166. package/dist/modules/shipping_carriers/workers/status-poller.js.map +7 -0
  167. package/dist/modules/shipping_carriers/workers/webhook-processor.js +54 -0
  168. package/dist/modules/shipping_carriers/workers/webhook-processor.js.map +7 -0
  169. package/dist/modules/translations/api/get/locales.js +1 -0
  170. package/dist/modules/translations/api/get/locales.js.map +2 -2
  171. package/dist/modules/translations/api/put/locales.js +1 -0
  172. package/dist/modules/translations/api/put/locales.js.map +2 -2
  173. package/generated/entities/carrier_shipment/index.ts +17 -0
  174. package/generated/entities/gateway_transaction/index.ts +22 -0
  175. package/generated/entities/webhook_processed_event/index.ts +7 -0
  176. package/generated/entities.ids.generated.ts +10 -1
  177. package/generated/entity-fields-registry.ts +6 -0
  178. package/jest.config.cjs +1 -0
  179. package/package.json +5 -2
  180. package/src/modules/auth/i18n/de.json +1 -0
  181. package/src/modules/auth/i18n/en.json +1 -0
  182. package/src/modules/auth/i18n/es.json +1 -0
  183. package/src/modules/auth/i18n/pl.json +1 -0
  184. package/src/modules/data_sync/api/runs/[id]/cancel.ts +18 -5
  185. package/src/modules/data_sync/backend/data-sync/page.meta.ts +2 -2
  186. package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +50 -12
  187. package/src/modules/directory/api/get/tenants/lookup.ts +1 -0
  188. package/src/modules/integrations/AGENTS.md +31 -0
  189. package/src/modules/integrations/api/[id]/route.ts +38 -11
  190. package/src/modules/integrations/api/logs/route.ts +53 -27
  191. package/src/modules/integrations/api/route.ts +31 -1
  192. package/src/modules/integrations/api/umes-read.ts +177 -0
  193. package/src/modules/integrations/backend/integrations/[id]/page.tsx +902 -202
  194. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +43 -9
  195. package/src/modules/integrations/backend/integrations/detail-page-widgets.ts +74 -0
  196. package/src/modules/integrations/backend/integrations/page.meta.ts +2 -2
  197. package/src/modules/integrations/backend/integrations/page.tsx +65 -54
  198. package/src/modules/integrations/i18n/de.json +15 -0
  199. package/src/modules/integrations/i18n/en.json +15 -0
  200. package/src/modules/integrations/i18n/es.json +15 -0
  201. package/src/modules/integrations/i18n/pl.json +15 -0
  202. package/src/modules/integrations/setup.ts +2 -2
  203. package/src/modules/payment_gateways/acl.ts +8 -0
  204. package/src/modules/payment_gateways/api/cancel/route.ts +56 -0
  205. package/src/modules/payment_gateways/api/capture/route.ts +56 -0
  206. package/src/modules/payment_gateways/api/interceptors.ts +22 -0
  207. package/src/modules/payment_gateways/api/openapi.ts +1 -0
  208. package/src/modules/payment_gateways/api/refund/route.ts +57 -0
  209. package/src/modules/payment_gateways/api/sessions/route.ts +76 -0
  210. package/src/modules/payment_gateways/api/status/route.ts +69 -0
  211. package/src/modules/payment_gateways/api/transactions/[id]/route.ts +123 -0
  212. package/src/modules/payment_gateways/api/transactions/route.ts +120 -0
  213. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +161 -0
  214. package/src/modules/payment_gateways/backend/payment-gateways/page.meta.ts +19 -0
  215. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +660 -0
  216. package/src/modules/payment_gateways/data/enrichers.ts +8 -0
  217. package/src/modules/payment_gateways/data/entities.ts +106 -0
  218. package/src/modules/payment_gateways/data/validators.ts +67 -0
  219. package/src/modules/payment_gateways/di.ts +26 -0
  220. package/src/modules/payment_gateways/events.ts +17 -0
  221. package/src/modules/payment_gateways/i18n/de.json +77 -0
  222. package/src/modules/payment_gateways/i18n/en.json +77 -0
  223. package/src/modules/payment_gateways/i18n/en.ts +4 -0
  224. package/src/modules/payment_gateways/i18n/es.json +77 -0
  225. package/src/modules/payment_gateways/i18n/pl.json +77 -0
  226. package/src/modules/payment_gateways/i18n/pl.ts +4 -0
  227. package/src/modules/payment_gateways/index.ts +5 -0
  228. package/src/modules/payment_gateways/lib/gateway-service.ts +486 -0
  229. package/src/modules/payment_gateways/lib/queue.ts +19 -0
  230. package/src/modules/payment_gateways/lib/status-machine.ts +28 -0
  231. package/src/modules/payment_gateways/lib/webhook-processor.ts +133 -0
  232. package/src/modules/payment_gateways/lib/webhook-utils.ts +52 -0
  233. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +373 -0
  234. package/src/modules/payment_gateways/migrations/Migration20260305122155.ts +20 -0
  235. package/src/modules/payment_gateways/setup.ts +11 -0
  236. package/src/modules/payment_gateways/widgets/injection-table.ts +9 -0
  237. package/src/modules/payment_gateways/workers/status-poller.ts +58 -0
  238. package/src/modules/payment_gateways/workers/webhook-processor.ts +30 -0
  239. package/src/modules/sales/data/enrichers.ts +120 -0
  240. package/src/modules/sales/lib/makeSalesLineRoute.ts +3 -0
  241. package/src/modules/sales/widgets/injection/payment-gateway-config-field/widget.ts +28 -0
  242. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +22 -0
  243. package/src/modules/sales/widgets/injection-table.ts +12 -0
  244. package/src/modules/shipping_carriers/acl.ts +6 -0
  245. package/src/modules/shipping_carriers/api/cancel/route.ts +53 -0
  246. package/src/modules/shipping_carriers/api/interceptors.ts +19 -0
  247. package/src/modules/shipping_carriers/api/openapi.ts +1 -0
  248. package/src/modules/shipping_carriers/api/rates/route.ts +53 -0
  249. package/src/modules/shipping_carriers/api/shipments/route.ts +59 -0
  250. package/src/modules/shipping_carriers/api/tracking/route.ts +56 -0
  251. package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +134 -0
  252. package/src/modules/shipping_carriers/data/enrichers.ts +89 -0
  253. package/src/modules/shipping_carriers/data/entities.ts +60 -0
  254. package/src/modules/shipping_carriers/data/validators.ts +48 -0
  255. package/src/modules/shipping_carriers/di.ts +20 -0
  256. package/src/modules/shipping_carriers/events.ts +16 -0
  257. package/src/modules/shipping_carriers/i18n/de.json +7 -0
  258. package/src/modules/shipping_carriers/i18n/en.json +7 -0
  259. package/src/modules/shipping_carriers/i18n/en.ts +7 -0
  260. package/src/modules/shipping_carriers/i18n/es.json +7 -0
  261. package/src/modules/shipping_carriers/i18n/pl.json +7 -0
  262. package/src/modules/shipping_carriers/i18n/pl.ts +7 -0
  263. package/src/modules/shipping_carriers/index.ts +5 -0
  264. package/src/modules/shipping_carriers/lib/adapter-registry.ts +33 -0
  265. package/src/modules/shipping_carriers/lib/adapter.ts +93 -0
  266. package/src/modules/shipping_carriers/lib/queue.ts +19 -0
  267. package/src/modules/shipping_carriers/lib/shipping-service.ts +204 -0
  268. package/src/modules/shipping_carriers/lib/status-sync.ts +38 -0
  269. package/src/modules/shipping_carriers/migrations/Migration20260305170000.ts +14 -0
  270. package/src/modules/shipping_carriers/setup.ts +11 -0
  271. package/src/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.ts +24 -0
  272. package/src/modules/shipping_carriers/widgets/injection/tracking-column/widget.ts +22 -0
  273. package/src/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.tsx +44 -0
  274. package/src/modules/shipping_carriers/widgets/injection-table.ts +22 -0
  275. package/src/modules/shipping_carriers/workers/status-poller.ts +33 -0
  276. package/src/modules/shipping_carriers/workers/webhook-processor.ts +79 -0
  277. package/src/modules/translations/api/get/locales.ts +1 -0
  278. package/src/modules/translations/api/put/locales.ts +1 -0
@@ -0,0 +1,16 @@
1
+ import { createModuleEvents } from '@open-mercato/shared/modules/events'
2
+
3
+ const events = [
4
+ { id: 'shipping_carriers.shipment.created', label: 'Shipment Created', category: 'lifecycle', entity: 'shipment' },
5
+ { id: 'shipping_carriers.shipment.status_changed', label: 'Shipment Status Changed', category: 'lifecycle', entity: 'shipment' },
6
+ { id: 'shipping_carriers.shipment.delivered', label: 'Shipment Delivered', category: 'lifecycle', entity: 'shipment' },
7
+ { id: 'shipping_carriers.shipment.returned', label: 'Shipment Returned', category: 'lifecycle', entity: 'shipment' },
8
+ { id: 'shipping_carriers.shipment.cancelled', label: 'Shipment Cancelled', category: 'lifecycle', entity: 'shipment' },
9
+ { id: 'shipping_carriers.webhook.received', label: 'Shipping Webhook Received', category: 'system', excludeFromTriggers: true },
10
+ { id: 'shipping_carriers.webhook.failed', label: 'Shipping Webhook Failed', category: 'system', excludeFromTriggers: true },
11
+ ] as const
12
+
13
+ export const eventsConfig = createModuleEvents({ moduleId: 'shipping_carriers', events })
14
+ export const emitShippingEvent = eventsConfig.emit
15
+ export type ShippingEventId = typeof events[number]['id']
16
+ export default eventsConfig
@@ -0,0 +1,7 @@
1
+ {
2
+ "shipping_carriers.action.createShipment": "Sendung erstellen",
3
+ "shipping_carriers.column.shippingStatus": "Versandstatus",
4
+ "shipping_carriers.column.trackingStatus": "Tracking-Status",
5
+ "shipping_carriers.feature.manage": "Versanddienstleister-Vorgaenge verwalten",
6
+ "shipping_carriers.feature.view": "Sendungen der Versanddienstleister anzeigen"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "shipping_carriers.action.createShipment": "Create shipment",
3
+ "shipping_carriers.column.shippingStatus": "Shipping status",
4
+ "shipping_carriers.column.trackingStatus": "Tracking status",
5
+ "shipping_carriers.feature.manage": "Manage shipping carrier operations",
6
+ "shipping_carriers.feature.view": "View shipping carrier shipments"
7
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ 'shipping_carriers.feature.view': 'View shipping carrier shipments',
3
+ 'shipping_carriers.feature.manage': 'Manage shipping carrier operations',
4
+ 'shipping_carriers.column.trackingStatus': 'Tracking status',
5
+ 'shipping_carriers.column.shippingStatus': 'Shipping status',
6
+ 'shipping_carriers.action.createShipment': 'Create shipment',
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "shipping_carriers.action.createShipment": "Crear envio",
3
+ "shipping_carriers.column.shippingStatus": "Estado del envio",
4
+ "shipping_carriers.column.trackingStatus": "Estado del seguimiento",
5
+ "shipping_carriers.feature.manage": "Gestionar operaciones de transportistas",
6
+ "shipping_carriers.feature.view": "Ver envios de transportistas"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "shipping_carriers.action.createShipment": "Utworz przesylke",
3
+ "shipping_carriers.column.shippingStatus": "Status wysylki",
4
+ "shipping_carriers.column.trackingStatus": "Status sledzenia",
5
+ "shipping_carriers.feature.manage": "Zarzadzanie operacjami przewoznikow",
6
+ "shipping_carriers.feature.view": "Podglad przesylek przewoznikow"
7
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ 'shipping_carriers.feature.view': 'Podgląd przesyłek przewoźników',
3
+ 'shipping_carriers.feature.manage': 'Zarządzanie operacjami przewoźników',
4
+ 'shipping_carriers.column.trackingStatus': 'Status śledzenia',
5
+ 'shipping_carriers.column.shippingStatus': 'Status wysyłki',
6
+ 'shipping_carriers.action.createShipment': 'Utwórz przesyłkę',
7
+ }
@@ -0,0 +1,5 @@
1
+ export const metadata = {
2
+ id: 'shipping_carriers',
3
+ title: 'Shipping Carriers',
4
+ description: 'Shipping carrier adapter hub with rates, shipment creation, tracking, and webhooks.',
5
+ }
@@ -0,0 +1,33 @@
1
+ import type { ShippingAdapter } from './adapter'
2
+
3
+ const SHIPPING_ADAPTER_REGISTRY_KEY = Symbol.for('@open-mercato/shipping-carriers/adapter-registry')
4
+
5
+ type GlobalWithShippingRegistry = typeof globalThis & {
6
+ [SHIPPING_ADAPTER_REGISTRY_KEY]?: Map<string, ShippingAdapter>
7
+ }
8
+
9
+ function getAdapterRegistry(): Map<string, ShippingAdapter> {
10
+ const globalScope = globalThis as GlobalWithShippingRegistry
11
+ if (!globalScope[SHIPPING_ADAPTER_REGISTRY_KEY]) {
12
+ globalScope[SHIPPING_ADAPTER_REGISTRY_KEY] = new Map<string, ShippingAdapter>()
13
+ }
14
+ return globalScope[SHIPPING_ADAPTER_REGISTRY_KEY]
15
+ }
16
+
17
+ export function registerShippingAdapter(adapter: ShippingAdapter): () => void {
18
+ const adapterRegistry = getAdapterRegistry()
19
+ adapterRegistry.set(adapter.providerKey, adapter)
20
+ return () => adapterRegistry.delete(adapter.providerKey)
21
+ }
22
+
23
+ export function getShippingAdapter(providerKey: string): ShippingAdapter | undefined {
24
+ return getAdapterRegistry().get(providerKey)
25
+ }
26
+
27
+ export function listShippingAdapters(): ShippingAdapter[] {
28
+ return Array.from(getAdapterRegistry().values())
29
+ }
30
+
31
+ export function clearShippingAdapters(): void {
32
+ getAdapterRegistry().clear()
33
+ }
@@ -0,0 +1,93 @@
1
+ export type UnifiedShipmentStatus =
2
+ | 'label_created'
3
+ | 'picked_up'
4
+ | 'in_transit'
5
+ | 'out_for_delivery'
6
+ | 'delivered'
7
+ | 'failed_delivery'
8
+ | 'returned'
9
+ | 'cancelled'
10
+ | 'unknown'
11
+
12
+ export type Address = {
13
+ countryCode: string
14
+ postalCode: string
15
+ city: string
16
+ line1: string
17
+ line2?: string
18
+ }
19
+
20
+ export type PackageInfo = {
21
+ weightKg: number
22
+ lengthCm: number
23
+ widthCm: number
24
+ heightCm: number
25
+ }
26
+
27
+ export type ShippingRate = {
28
+ serviceCode: string
29
+ serviceName: string
30
+ amount: number
31
+ currencyCode: string
32
+ estimatedDays?: number
33
+ guaranteedDelivery?: boolean
34
+ }
35
+
36
+ export type CreateShipmentInput = {
37
+ orderId: string
38
+ origin: Address
39
+ destination: Address
40
+ packages: PackageInfo[]
41
+ serviceCode: string
42
+ credentials: Record<string, unknown>
43
+ labelFormat?: 'pdf' | 'zpl' | 'png'
44
+ }
45
+
46
+ export type CreateShipmentResult = {
47
+ shipmentId: string
48
+ trackingNumber: string
49
+ labelUrl?: string
50
+ labelData?: string
51
+ estimatedDelivery?: Date
52
+ }
53
+
54
+ export type TrackingResult = {
55
+ trackingNumber: string
56
+ status: UnifiedShipmentStatus
57
+ events: Array<{ status: UnifiedShipmentStatus; occurredAt: string; location?: string }>
58
+ }
59
+
60
+ export type ShippingWebhookEvent = {
61
+ eventType: string
62
+ eventId: string
63
+ idempotencyKey: string
64
+ data: Record<string, unknown>
65
+ timestamp: Date
66
+ }
67
+
68
+ export interface ShippingAdapter {
69
+ readonly providerKey: string
70
+ calculateRates(input: {
71
+ origin: Address
72
+ destination: Address
73
+ packages: PackageInfo[]
74
+ credentials: Record<string, unknown>
75
+ }): Promise<ShippingRate[]>
76
+ createShipment(input: CreateShipmentInput): Promise<CreateShipmentResult>
77
+ getTracking(input: {
78
+ shipmentId?: string
79
+ trackingNumber?: string
80
+ credentials: Record<string, unknown>
81
+ }): Promise<TrackingResult>
82
+ cancelShipment(input: {
83
+ shipmentId: string
84
+ reason?: string
85
+ credentials: Record<string, unknown>
86
+ }): Promise<{ status: UnifiedShipmentStatus }>
87
+ verifyWebhook(input: {
88
+ rawBody: string | Buffer
89
+ headers: Record<string, string | string[] | undefined>
90
+ credentials: Record<string, unknown>
91
+ }): Promise<ShippingWebhookEvent>
92
+ mapStatus(carrierStatus: string): UnifiedShipmentStatus
93
+ }
@@ -0,0 +1,19 @@
1
+ import { createQueue, type Queue } from '@open-mercato/queue'
2
+ import { getRedisUrl } from '@open-mercato/shared/lib/redis/connection'
3
+
4
+ const queues = new Map<string, Queue<Record<string, unknown>>>()
5
+
6
+ export function getShippingCarrierQueue(queueName: string): Queue<Record<string, unknown>> {
7
+ const existing = queues.get(queueName)
8
+ if (existing) return existing
9
+
10
+ const created = process.env.QUEUE_STRATEGY === 'async'
11
+ ? createQueue<Record<string, unknown>>(queueName, 'async', {
12
+ connection: { url: getRedisUrl('QUEUE') },
13
+ concurrency: Math.max(1, Number.parseInt(process.env.SHIPPING_CARRIER_QUEUE_CONCURRENCY ?? '5', 10) || 5),
14
+ })
15
+ : createQueue<Record<string, unknown>>(queueName, 'local')
16
+
17
+ queues.set(queueName, created)
18
+ return created
19
+ }
@@ -0,0 +1,204 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql'
2
+ import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
3
+ import type { CredentialsService } from '../../integrations/lib/credentials-service'
4
+ import { CarrierShipment } from '../data/entities'
5
+ import { emitShippingEvent } from '../events'
6
+ import { getShippingAdapter } from './adapter-registry'
7
+
8
+ export function createShippingCarrierService(deps: {
9
+ em: EntityManager
10
+ integrationCredentialsService: CredentialsService
11
+ }) {
12
+ const { em, integrationCredentialsService } = deps
13
+
14
+ async function findShipmentOrThrow(
15
+ shipmentId: string,
16
+ scope: { organizationId: string; tenantId: string },
17
+ ): Promise<CarrierShipment> {
18
+ const shipment = await findOneWithDecryption(
19
+ em,
20
+ CarrierShipment,
21
+ {
22
+ id: shipmentId,
23
+ organizationId: scope.organizationId,
24
+ tenantId: scope.tenantId,
25
+ deletedAt: null,
26
+ },
27
+ undefined,
28
+ scope,
29
+ )
30
+ if (!shipment) {
31
+ throw new Error('Shipment not found')
32
+ }
33
+ return shipment
34
+ }
35
+
36
+ async function resolveAdapter(providerKey: string, scope: { organizationId: string; tenantId: string }) {
37
+ const adapter = getShippingAdapter(providerKey)
38
+ if (!adapter) throw new Error(`No shipping adapter registered for provider: ${providerKey}`)
39
+ const credentials = await integrationCredentialsService.resolve(`carrier_${providerKey}`, scope) ?? {}
40
+ return { adapter, credentials }
41
+ }
42
+
43
+ return {
44
+ async calculateRates(input: {
45
+ providerKey: string
46
+ origin: { countryCode: string; postalCode: string; city: string; line1: string; line2?: string }
47
+ destination: { countryCode: string; postalCode: string; city: string; line1: string; line2?: string }
48
+ packages: Array<{ weightKg: number; lengthCm: number; widthCm: number; heightCm: number }>
49
+ organizationId: string
50
+ tenantId: string
51
+ }) {
52
+ const { adapter, credentials } = await resolveAdapter(input.providerKey, {
53
+ organizationId: input.organizationId,
54
+ tenantId: input.tenantId,
55
+ })
56
+ return adapter.calculateRates({
57
+ origin: input.origin,
58
+ destination: input.destination,
59
+ packages: input.packages,
60
+ credentials,
61
+ })
62
+ },
63
+
64
+ async createShipment(input: {
65
+ providerKey: string
66
+ orderId: string
67
+ origin: { countryCode: string; postalCode: string; city: string; line1: string; line2?: string }
68
+ destination: { countryCode: string; postalCode: string; city: string; line1: string; line2?: string }
69
+ packages: Array<{ weightKg: number; lengthCm: number; widthCm: number; heightCm: number }>
70
+ serviceCode: string
71
+ labelFormat?: 'pdf' | 'zpl' | 'png'
72
+ organizationId: string
73
+ tenantId: string
74
+ }) {
75
+ const { adapter, credentials } = await resolveAdapter(input.providerKey, {
76
+ organizationId: input.organizationId,
77
+ tenantId: input.tenantId,
78
+ })
79
+ const created = await adapter.createShipment({
80
+ orderId: input.orderId,
81
+ origin: input.origin,
82
+ destination: input.destination,
83
+ packages: input.packages,
84
+ serviceCode: input.serviceCode,
85
+ credentials,
86
+ labelFormat: input.labelFormat,
87
+ })
88
+ const shipment = em.create(CarrierShipment, {
89
+ orderId: input.orderId,
90
+ providerKey: input.providerKey,
91
+ carrierShipmentId: created.shipmentId,
92
+ trackingNumber: created.trackingNumber,
93
+ unifiedStatus: 'label_created',
94
+ labelUrl: created.labelUrl ?? null,
95
+ labelData: created.labelData ?? null,
96
+ organizationId: input.organizationId,
97
+ tenantId: input.tenantId,
98
+ })
99
+ await em.persistAndFlush(shipment)
100
+ await emitShippingEvent('shipping_carriers.shipment.created', {
101
+ shipmentId: shipment.id,
102
+ orderId: input.orderId,
103
+ providerKey: input.providerKey,
104
+ trackingNumber: created.trackingNumber,
105
+ organizationId: input.organizationId,
106
+ tenantId: input.tenantId,
107
+ })
108
+ return shipment
109
+ },
110
+
111
+ async getTracking(input: {
112
+ providerKey: string
113
+ shipmentId?: string
114
+ trackingNumber?: string
115
+ organizationId: string
116
+ tenantId: string
117
+ }) {
118
+ const { adapter, credentials } = await resolveAdapter(input.providerKey, {
119
+ organizationId: input.organizationId,
120
+ tenantId: input.tenantId,
121
+ })
122
+ const shipment = input.shipmentId
123
+ ? await findOneWithDecryption(
124
+ em,
125
+ CarrierShipment,
126
+ {
127
+ id: input.shipmentId,
128
+ organizationId: input.organizationId,
129
+ tenantId: input.tenantId,
130
+ deletedAt: null,
131
+ },
132
+ undefined,
133
+ {
134
+ organizationId: input.organizationId,
135
+ tenantId: input.tenantId,
136
+ },
137
+ )
138
+ : null
139
+ const tracking = await adapter.getTracking({
140
+ shipmentId: shipment?.carrierShipmentId ?? input.shipmentId,
141
+ trackingNumber: input.trackingNumber,
142
+ credentials,
143
+ })
144
+ if (shipment) {
145
+ shipment.unifiedStatus = tracking.status
146
+ shipment.trackingEvents = tracking.events
147
+ shipment.lastPolledAt = new Date()
148
+ await em.flush()
149
+ }
150
+ return tracking
151
+ },
152
+
153
+ async cancelShipment(input: {
154
+ providerKey: string
155
+ shipmentId: string
156
+ reason?: string
157
+ organizationId: string
158
+ tenantId: string
159
+ }) {
160
+ const scope = { organizationId: input.organizationId, tenantId: input.tenantId }
161
+ const shipment = await findShipmentOrThrow(input.shipmentId, scope)
162
+ const { adapter, credentials } = await resolveAdapter(input.providerKey, {
163
+ organizationId: input.organizationId,
164
+ tenantId: input.tenantId,
165
+ })
166
+ const result = await adapter.cancelShipment({
167
+ shipmentId: shipment.carrierShipmentId,
168
+ reason: input.reason,
169
+ credentials,
170
+ })
171
+ shipment.unifiedStatus = result.status
172
+ await em.flush()
173
+ await emitShippingEvent('shipping_carriers.shipment.cancelled', {
174
+ shipmentId: shipment.id,
175
+ providerKey: input.providerKey,
176
+ organizationId: input.organizationId,
177
+ tenantId: input.tenantId,
178
+ })
179
+ return result
180
+ },
181
+
182
+ async findShipmentByCarrierId(
183
+ providerKey: string,
184
+ carrierShipmentId: string,
185
+ scope: { organizationId: string; tenantId: string },
186
+ ) {
187
+ return findOneWithDecryption(
188
+ em,
189
+ CarrierShipment,
190
+ {
191
+ providerKey,
192
+ carrierShipmentId,
193
+ organizationId: scope.organizationId,
194
+ tenantId: scope.tenantId,
195
+ deletedAt: null,
196
+ },
197
+ undefined,
198
+ scope,
199
+ )
200
+ },
201
+ }
202
+ }
203
+
204
+ export type ShippingCarrierService = ReturnType<typeof createShippingCarrierService>
@@ -0,0 +1,38 @@
1
+ import type { UnifiedShipmentStatus } from './adapter'
2
+ import type { CarrierShipment } from '../data/entities'
3
+ import type { ShippingEventId } from '../events'
4
+
5
+ const VALID_SHIPPING_TRANSITIONS: Record<string, UnifiedShipmentStatus[]> = {
6
+ label_created: ['picked_up', 'in_transit', 'cancelled'],
7
+ picked_up: ['in_transit', 'cancelled'],
8
+ in_transit: ['out_for_delivery', 'delivered', 'returned', 'failed_delivery'],
9
+ out_for_delivery: ['delivered', 'returned', 'failed_delivery'],
10
+ failed_delivery: ['in_transit', 'out_for_delivery', 'delivered', 'returned', 'cancelled'],
11
+ }
12
+
13
+ export const TERMINAL_SHIPPING_STATUSES: Set<UnifiedShipmentStatus> = new Set([
14
+ 'delivered',
15
+ 'returned',
16
+ 'cancelled',
17
+ ])
18
+
19
+ export function isValidShippingTransition(from: UnifiedShipmentStatus, to: UnifiedShipmentStatus): boolean {
20
+ if (from === to) return false
21
+ const allowed = VALID_SHIPPING_TRANSITIONS[from]
22
+ if (!allowed) return false
23
+ return allowed.includes(to)
24
+ }
25
+
26
+ export function syncShipmentStatus(shipment: CarrierShipment, newStatus: UnifiedShipmentStatus): boolean {
27
+ const currentStatus = shipment.unifiedStatus as UnifiedShipmentStatus
28
+ if (!isValidShippingTransition(currentStatus, newStatus)) return false
29
+ shipment.unifiedStatus = newStatus
30
+ return true
31
+ }
32
+
33
+ export function getTerminalShippingEvent(status: UnifiedShipmentStatus): ShippingEventId | null {
34
+ if (status === 'delivered') return 'shipping_carriers.shipment.delivered'
35
+ if (status === 'returned') return 'shipping_carriers.shipment.returned'
36
+ if (status === 'cancelled') return 'shipping_carriers.shipment.cancelled'
37
+ return null
38
+ }
@@ -0,0 +1,14 @@
1
+ import { Migration } from '@mikro-orm/migrations'
2
+
3
+ export class Migration20260305170000 extends Migration {
4
+ override async up(): Promise<void> {
5
+ this.addSql(`create table "carrier_shipments" ("id" uuid not null default gen_random_uuid(), "order_id" uuid not null, "provider_key" text not null, "carrier_shipment_id" text not null, "tracking_number" text not null, "unified_status" text not null default 'label_created', "carrier_status" text null, "label_url" text null, "label_data" text null, "tracking_events" jsonb null, "organization_id" uuid not null, "tenant_id" uuid not null, "last_webhook_at" timestamptz null, "last_polled_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, constraint "carrier_shipments_pkey" primary key ("id"));`)
6
+ this.addSql(`create index "carrier_shipments_organization_id_tenant_id_unif_b5ab4_index" on "carrier_shipments" ("organization_id", "tenant_id", "unified_status");`)
7
+ this.addSql(`create index "carrier_shipments_provider_key_carrier_shipment_i_f9f17_index" on "carrier_shipments" ("provider_key", "carrier_shipment_id", "organization_id");`)
8
+ this.addSql(`create index "carrier_shipments_order_id_organization_id_tenant_id_index" on "carrier_shipments" ("order_id", "organization_id", "tenant_id");`)
9
+ }
10
+
11
+ override async down(): Promise<void> {
12
+ this.addSql(`drop table if exists "carrier_shipments";`)
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
2
+
3
+ export const setup: ModuleSetupConfig = {
4
+ defaultRoleFeatures: {
5
+ superadmin: ['shipping_carriers.view', 'shipping_carriers.manage'],
6
+ admin: ['shipping_carriers.view', 'shipping_carriers.manage'],
7
+ employee: ['shipping_carriers.view'],
8
+ },
9
+ }
10
+
11
+ export default setup
@@ -0,0 +1,24 @@
1
+ import type { InjectionRowActionWidget } from '@open-mercato/shared/modules/widgets/injection'
2
+
3
+ const widget: InjectionRowActionWidget = {
4
+ metadata: {
5
+ id: 'shipping_carriers.injection.create-shipment-button',
6
+ priority: 30,
7
+ },
8
+ rowActions: [
9
+ {
10
+ id: 'create_shipment',
11
+ label: 'shipping_carriers.action.createShipment',
12
+ icon: 'Truck',
13
+ onSelect: (row: unknown, context: unknown) => {
14
+ const ctx = context as { navigate?: (path: string) => void }
15
+ const order = row as { id?: string }
16
+ if (ctx.navigate && order.id) {
17
+ ctx.navigate(`/backend/shipping-carriers/create?orderId=${order.id}`)
18
+ }
19
+ },
20
+ },
21
+ ],
22
+ }
23
+
24
+ export default widget
@@ -0,0 +1,22 @@
1
+ import type { InjectionColumnWidget } from '@open-mercato/shared/modules/widgets/injection'
2
+
3
+ const widget: InjectionColumnWidget = {
4
+ metadata: {
5
+ id: 'shipping_carriers.injection.tracking-column',
6
+ priority: 40,
7
+ },
8
+ columns: [
9
+ {
10
+ id: 'carrier_tracking_status',
11
+ header: 'shipping_carriers.column.trackingStatus',
12
+ accessorKey: '_carrier.status',
13
+ sortable: false,
14
+ cell: ({ getValue }) => {
15
+ const value = getValue()
16
+ return typeof value === 'string' && value.length > 0 ? value : 'unknown'
17
+ },
18
+ },
19
+ ],
20
+ }
21
+
22
+ export default widget
@@ -0,0 +1,44 @@
1
+ import type { InjectionColumnWidget } from '@open-mercato/shared/modules/widgets/injection'
2
+
3
+ const SHIPPING_STATUS_COLORS: Record<string, string> = {
4
+ pending: 'bg-gray-100 text-gray-700',
5
+ label_created: 'bg-slate-100 text-slate-700',
6
+ picked_up: 'bg-sky-100 text-sky-700',
7
+ in_transit: 'bg-blue-100 text-blue-700',
8
+ out_for_delivery: 'bg-indigo-100 text-indigo-700',
9
+ delivered: 'bg-green-100 text-green-700',
10
+ returned: 'bg-amber-100 text-amber-700',
11
+ cancelled: 'bg-red-100 text-red-700',
12
+ failed_delivery: 'bg-orange-100 text-orange-700',
13
+ }
14
+
15
+ function formatShippingStatusLabel(value: string): string {
16
+ return value.replace(/_/g, ' ')
17
+ }
18
+
19
+ const widget: InjectionColumnWidget = {
20
+ metadata: {
21
+ id: 'shipping_carriers.injection.tracking-status-badge',
22
+ priority: 45,
23
+ },
24
+ columns: [
25
+ {
26
+ id: 'carrier_status_badge',
27
+ header: 'shipping_carriers.column.shippingStatus',
28
+ accessorKey: '_carrier.status',
29
+ sortable: false,
30
+ cell: ({ getValue }) => {
31
+ const value = getValue()
32
+ if (typeof value !== 'string' || value.length === 0) return null
33
+ const colors = SHIPPING_STATUS_COLORS[value] ?? 'bg-gray-100 text-gray-700'
34
+ return (
35
+ <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${colors}`}>
36
+ {formatShippingStatusLabel(value)}
37
+ </span>
38
+ )
39
+ },
40
+ },
41
+ ],
42
+ }
43
+
44
+ export default widget
@@ -0,0 +1,22 @@
1
+ import type { ModuleInjectionTable } from '@open-mercato/shared/modules/widgets/injection'
2
+
3
+ export const injectionTable: ModuleInjectionTable = {
4
+ 'data-table:sales.shipments:columns': [
5
+ {
6
+ widgetId: 'shipping_carriers.injection.tracking-column',
7
+ priority: 40,
8
+ },
9
+ {
10
+ widgetId: 'shipping_carriers.injection.tracking-status-badge',
11
+ priority: 45,
12
+ },
13
+ ],
14
+ 'data-table:sales.orders:row-actions': [
15
+ {
16
+ widgetId: 'shipping_carriers.injection.create-shipment-button',
17
+ priority: 30,
18
+ },
19
+ ],
20
+ }
21
+
22
+ export default injectionTable
@@ -0,0 +1,33 @@
1
+ import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'
2
+ import type { ShippingCarrierService } from '../lib/shipping-service'
3
+
4
+ type PollerJobPayload = {
5
+ providerKey: string
6
+ shipmentIds: string[]
7
+ scope: {
8
+ organizationId: string
9
+ tenantId: string
10
+ }
11
+ }
12
+
13
+ type HandlerContext = JobContext & {
14
+ resolve: <T = unknown>(name: string) => T
15
+ }
16
+
17
+ export const metadata: WorkerMeta = {
18
+ queue: 'shipping-carriers-status-poller',
19
+ id: 'shipping-carriers:status-poller',
20
+ concurrency: 2,
21
+ }
22
+
23
+ export default async function handle(job: QueuedJob<PollerJobPayload>, ctx: HandlerContext): Promise<void> {
24
+ const service = ctx.resolve<ShippingCarrierService>('shippingCarrierService')
25
+ for (const shipmentId of job.payload.shipmentIds) {
26
+ await service.getTracking({
27
+ providerKey: job.payload.providerKey,
28
+ shipmentId,
29
+ organizationId: job.payload.scope.organizationId,
30
+ tenantId: job.payload.scope.tenantId,
31
+ })
32
+ }
33
+ }