@freighttech/shipment-tracking 0.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 (456) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +25 -0
  3. package/dist/generated/entities/bic_config/index.js +21 -0
  4. package/dist/generated/entities/bic_config/index.js.map +7 -0
  5. package/dist/generated/entities/carrier_config/index.js +27 -0
  6. package/dist/generated/entities/carrier_config/index.js.map +7 -0
  7. package/dist/generated/entities/location_override/index.js +33 -0
  8. package/dist/generated/entities/location_override/index.js.map +7 -0
  9. package/dist/generated/entities/shipment/index.js +73 -0
  10. package/dist/generated/entities/shipment/index.js.map +7 -0
  11. package/dist/generated/entities/ships_go_config/index.js +31 -0
  12. package/dist/generated/entities/ships_go_config/index.js.map +7 -0
  13. package/dist/generated/entities/tracking_event/index.js +101 -0
  14. package/dist/generated/entities/tracking_event/index.js.map +7 -0
  15. package/dist/generated/entities/tracking_job/index.js +47 -0
  16. package/dist/generated/entities/tracking_job/index.js.map +7 -0
  17. package/dist/generated/entities/webhook/index.js +25 -0
  18. package/dist/generated/entities/webhook/index.js.map +7 -0
  19. package/dist/generated/entities/webhook_delivery/index.js +25 -0
  20. package/dist/generated/entities/webhook_delivery/index.js.map +7 -0
  21. package/dist/generated/entities.ids.generated.js +21 -0
  22. package/dist/generated/entities.ids.generated.js.map +7 -0
  23. package/dist/index.js +41 -0
  24. package/dist/index.js.map +7 -0
  25. package/dist/modules/shipment_tracking/acl.js +22 -0
  26. package/dist/modules/shipment_tracking/acl.js.map +7 -0
  27. package/dist/modules/shipment_tracking/api/bic-configs/route.js +176 -0
  28. package/dist/modules/shipment_tracking/api/bic-configs/route.js.map +7 -0
  29. package/dist/modules/shipment_tracking/api/bic-configs/test/route.js +95 -0
  30. package/dist/modules/shipment_tracking/api/bic-configs/test/route.js.map +7 -0
  31. package/dist/modules/shipment_tracking/api/cargo-events/route.js +93 -0
  32. package/dist/modules/shipment_tracking/api/cargo-events/route.js.map +7 -0
  33. package/dist/modules/shipment_tracking/api/carrier-configs/route.js +139 -0
  34. package/dist/modules/shipment_tracking/api/carrier-configs/route.js.map +7 -0
  35. package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js +177 -0
  36. package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js.map +7 -0
  37. package/dist/modules/shipment_tracking/api/location-overrides/route.js +179 -0
  38. package/dist/modules/shipment_tracking/api/location-overrides/route.js.map +7 -0
  39. package/dist/modules/shipment_tracking/api/openapi.js +27 -0
  40. package/dist/modules/shipment_tracking/api/openapi.js.map +7 -0
  41. package/dist/modules/shipment_tracking/api/shipments/route.js +192 -0
  42. package/dist/modules/shipment_tracking/api/shipments/route.js.map +7 -0
  43. package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js +185 -0
  44. package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js.map +7 -0
  45. package/dist/modules/shipment_tracking/api/tracking-jobs/route.js +144 -0
  46. package/dist/modules/shipment_tracking/api/tracking-jobs/route.js.map +7 -0
  47. package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js +107 -0
  48. package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js.map +7 -0
  49. package/dist/modules/shipment_tracking/api/utils.js +12 -0
  50. package/dist/modules/shipment_tracking/api/utils.js.map +7 -0
  51. package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js +76 -0
  52. package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js.map +7 -0
  53. package/dist/modules/shipment_tracking/api/webhooks/route.js +135 -0
  54. package/dist/modules/shipment_tracking/api/webhooks/route.js.map +7 -0
  55. package/dist/modules/shipment_tracking/api/webhooks/test/route.js +71 -0
  56. package/dist/modules/shipment_tracking/api/webhooks/test/route.js.map +7 -0
  57. package/dist/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
  58. package/dist/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
  59. package/dist/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
  60. package/dist/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
  61. package/dist/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
  62. package/dist/modules/shipment_tracking/assets/carriers/msc.png +0 -0
  63. package/dist/modules/shipment_tracking/assets/carriers/one.png +0 -0
  64. package/dist/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
  65. package/dist/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
  66. package/dist/modules/shipment_tracking/assets/carriers/zim.png +0 -0
  67. package/dist/modules/shipment_tracking/assets/index.js +52 -0
  68. package/dist/modules/shipment_tracking/assets/index.js.map +7 -0
  69. package/dist/modules/shipment_tracking/backend/carrier-configs/page.js +621 -0
  70. package/dist/modules/shipment_tracking/backend/carrier-configs/page.js.map +7 -0
  71. package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js +19 -0
  72. package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js.map +7 -0
  73. package/dist/modules/shipment_tracking/backend/location-overrides/page.js +198 -0
  74. package/dist/modules/shipment_tracking/backend/location-overrides/page.js.map +7 -0
  75. package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js +19 -0
  76. package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js.map +7 -0
  77. package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js +279 -0
  78. package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js.map +7 -0
  79. package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js +19 -0
  80. package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js.map +7 -0
  81. package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js +10 -0
  82. package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js.map +7 -0
  83. package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js +19 -0
  84. package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js.map +7 -0
  85. package/dist/modules/shipment_tracking/backend/webhooks/page.js +198 -0
  86. package/dist/modules/shipment_tracking/backend/webhooks/page.js.map +7 -0
  87. package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js +19 -0
  88. package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js.map +7 -0
  89. package/dist/modules/shipment_tracking/ce.js +52 -0
  90. package/dist/modules/shipment_tracking/ce.js.map +7 -0
  91. package/dist/modules/shipment_tracking/cli.js +229 -0
  92. package/dist/modules/shipment_tracking/cli.js.map +7 -0
  93. package/dist/modules/shipment_tracking/commands/bic-configs.js +66 -0
  94. package/dist/modules/shipment_tracking/commands/bic-configs.js.map +7 -0
  95. package/dist/modules/shipment_tracking/commands/carrier-configs.js +65 -0
  96. package/dist/modules/shipment_tracking/commands/carrier-configs.js.map +7 -0
  97. package/dist/modules/shipment_tracking/commands/index.js +9 -0
  98. package/dist/modules/shipment_tracking/commands/index.js.map +7 -0
  99. package/dist/modules/shipment_tracking/commands/location-overrides.js +93 -0
  100. package/dist/modules/shipment_tracking/commands/location-overrides.js.map +7 -0
  101. package/dist/modules/shipment_tracking/commands/shipments.js +200 -0
  102. package/dist/modules/shipment_tracking/commands/shipments.js.map +7 -0
  103. package/dist/modules/shipment_tracking/commands/shipsgo-configs.js +75 -0
  104. package/dist/modules/shipment_tracking/commands/shipsgo-configs.js.map +7 -0
  105. package/dist/modules/shipment_tracking/commands/tracking-jobs.js +120 -0
  106. package/dist/modules/shipment_tracking/commands/tracking-jobs.js.map +7 -0
  107. package/dist/modules/shipment_tracking/commands/tracking.js +140 -0
  108. package/dist/modules/shipment_tracking/commands/tracking.js.map +7 -0
  109. package/dist/modules/shipment_tracking/commands/webhooks.js +115 -0
  110. package/dist/modules/shipment_tracking/commands/webhooks.js.map +7 -0
  111. package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js +168 -0
  112. package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js.map +7 -0
  113. package/dist/modules/shipment_tracking/components/FacilityLocationInput.js +202 -0
  114. package/dist/modules/shipment_tracking/components/FacilityLocationInput.js.map +7 -0
  115. package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js +501 -0
  116. package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js.map +7 -0
  117. package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js +818 -0
  118. package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js.map +7 -0
  119. package/dist/modules/shipment_tracking/components/ShipmentDrawer.js +404 -0
  120. package/dist/modules/shipment_tracking/components/ShipmentDrawer.js.map +7 -0
  121. package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js +200 -0
  122. package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js.map +7 -0
  123. package/dist/modules/shipment_tracking/components/TimestampCell.js +108 -0
  124. package/dist/modules/shipment_tracking/components/TimestampCell.js.map +7 -0
  125. package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js +343 -0
  126. package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js.map +7 -0
  127. package/dist/modules/shipment_tracking/components/VesselTrackingMap.js +496 -0
  128. package/dist/modules/shipment_tracking/components/VesselTrackingMap.js.map +7 -0
  129. package/dist/modules/shipment_tracking/components/WebhookDrawer.js +332 -0
  130. package/dist/modules/shipment_tracking/components/WebhookDrawer.js.map +7 -0
  131. package/dist/modules/shipment_tracking/data/entities.js +686 -0
  132. package/dist/modules/shipment_tracking/data/entities.js.map +7 -0
  133. package/dist/modules/shipment_tracking/data/validators.js +434 -0
  134. package/dist/modules/shipment_tracking/data/validators.js.map +7 -0
  135. package/dist/modules/shipment_tracking/di.js +60 -0
  136. package/dist/modules/shipment_tracking/di.js.map +7 -0
  137. package/dist/modules/shipment_tracking/encryption.js +12 -0
  138. package/dist/modules/shipment_tracking/encryption.js.map +7 -0
  139. package/dist/modules/shipment_tracking/events.js +87 -0
  140. package/dist/modules/shipment_tracking/events.js.map +7 -0
  141. package/dist/modules/shipment_tracking/hooks/useVesselTracking.js +137 -0
  142. package/dist/modules/shipment_tracking/hooks/useVesselTracking.js.map +7 -0
  143. package/dist/modules/shipment_tracking/i18n/de.json +327 -0
  144. package/dist/modules/shipment_tracking/i18n/en.json +327 -0
  145. package/dist/modules/shipment_tracking/i18n/es.json +327 -0
  146. package/dist/modules/shipment_tracking/i18n/pl.json +327 -0
  147. package/dist/modules/shipment_tracking/index.js +15 -0
  148. package/dist/modules/shipment_tracking/index.js.map +7 -0
  149. package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js +66 -0
  150. package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js.map +7 -0
  151. package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js +1 -0
  152. package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js.map +7 -0
  153. package/dist/modules/shipment_tracking/lib/adapters/cosco.js +236 -0
  154. package/dist/modules/shipment_tracking/lib/adapters/cosco.js.map +7 -0
  155. package/dist/modules/shipment_tracking/lib/adapters/evergreen.js +87 -0
  156. package/dist/modules/shipment_tracking/lib/adapters/evergreen.js.map +7 -0
  157. package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js +68 -0
  158. package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js.map +7 -0
  159. package/dist/modules/shipment_tracking/lib/adapters/index.js +20 -0
  160. package/dist/modules/shipment_tracking/lib/adapters/index.js.map +7 -0
  161. package/dist/modules/shipment_tracking/lib/adapters/maersk.js +84 -0
  162. package/dist/modules/shipment_tracking/lib/adapters/maersk.js.map +7 -0
  163. package/dist/modules/shipment_tracking/lib/adapters/msc.js +170 -0
  164. package/dist/modules/shipment_tracking/lib/adapters/msc.js.map +7 -0
  165. package/dist/modules/shipment_tracking/lib/adapters/zim.js +85 -0
  166. package/dist/modules/shipment_tracking/lib/adapters/zim.js.map +7 -0
  167. package/dist/modules/shipment_tracking/lib/audit-helpers.js +20 -0
  168. package/dist/modules/shipment_tracking/lib/audit-helpers.js.map +7 -0
  169. package/dist/modules/shipment_tracking/lib/auth/base64url.js +8 -0
  170. package/dist/modules/shipment_tracking/lib/auth/base64url.js.map +7 -0
  171. package/dist/modules/shipment_tracking/lib/auth/oauth-client.js +38 -0
  172. package/dist/modules/shipment_tracking/lib/auth/oauth-client.js.map +7 -0
  173. package/dist/modules/shipment_tracking/lib/background.js +15 -0
  174. package/dist/modules/shipment_tracking/lib/background.js.map +7 -0
  175. package/dist/modules/shipment_tracking/lib/bic-api-client.js +106 -0
  176. package/dist/modules/shipment_tracking/lib/bic-api-client.js.map +7 -0
  177. package/dist/modules/shipment_tracking/lib/carrier-adapter.js +17 -0
  178. package/dist/modules/shipment_tracking/lib/carrier-adapter.js.map +7 -0
  179. package/dist/modules/shipment_tracking/lib/current-vessel.js +149 -0
  180. package/dist/modules/shipment_tracking/lib/current-vessel.js.map +7 -0
  181. package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js +124 -0
  182. package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js.map +7 -0
  183. package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js +112 -0
  184. package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js.map +7 -0
  185. package/dist/modules/shipment_tracking/lib/dcsa-params.js +16 -0
  186. package/dist/modules/shipment_tracking/lib/dcsa-params.js.map +7 -0
  187. package/dist/modules/shipment_tracking/lib/empty-return.js +48 -0
  188. package/dist/modules/shipment_tracking/lib/empty-return.js.map +7 -0
  189. package/dist/modules/shipment_tracking/lib/location-overrides.js +85 -0
  190. package/dist/modules/shipment_tracking/lib/location-overrides.js.map +7 -0
  191. package/dist/modules/shipment_tracking/lib/location-types.js +59 -0
  192. package/dist/modules/shipment_tracking/lib/location-types.js.map +7 -0
  193. package/dist/modules/shipment_tracking/lib/logger.js +113 -0
  194. package/dist/modules/shipment_tracking/lib/logger.js.map +7 -0
  195. package/dist/modules/shipment_tracking/lib/poi-event-processor.js +183 -0
  196. package/dist/modules/shipment_tracking/lib/poi-event-processor.js.map +7 -0
  197. package/dist/modules/shipment_tracking/lib/poi-nats-config.js +52 -0
  198. package/dist/modules/shipment_tracking/lib/poi-nats-config.js.map +7 -0
  199. package/dist/modules/shipment_tracking/lib/poi-types.js +43 -0
  200. package/dist/modules/shipment_tracking/lib/poi-types.js.map +7 -0
  201. package/dist/modules/shipment_tracking/lib/rate-limiter.js +31 -0
  202. package/dist/modules/shipment_tracking/lib/rate-limiter.js.map +7 -0
  203. package/dist/modules/shipment_tracking/lib/route-extraction.js +187 -0
  204. package/dist/modules/shipment_tracking/lib/route-extraction.js.map +7 -0
  205. package/dist/modules/shipment_tracking/lib/route-inference.js +106 -0
  206. package/dist/modules/shipment_tracking/lib/route-inference.js.map +7 -0
  207. package/dist/modules/shipment_tracking/lib/schedule-generator.js +63 -0
  208. package/dist/modules/shipment_tracking/lib/schedule-generator.js.map +7 -0
  209. package/dist/modules/shipment_tracking/lib/shipsgo-client.js +143 -0
  210. package/dist/modules/shipment_tracking/lib/shipsgo-client.js.map +7 -0
  211. package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js +204 -0
  212. package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js.map +7 -0
  213. package/dist/modules/shipment_tracking/lib/status-machine.js +131 -0
  214. package/dist/modules/shipment_tracking/lib/status-machine.js.map +7 -0
  215. package/dist/modules/shipment_tracking/lib/time-extraction.js +41 -0
  216. package/dist/modules/shipment_tracking/lib/time-extraction.js.map +7 -0
  217. package/dist/modules/shipment_tracking/lib/timestamp-utils.js +100 -0
  218. package/dist/modules/shipment_tracking/lib/timestamp-utils.js.map +7 -0
  219. package/dist/modules/shipment_tracking/lib/vessel-api.js +111 -0
  220. package/dist/modules/shipment_tracking/lib/vessel-api.js.map +7 -0
  221. package/dist/modules/shipment_tracking/lib/vessel-cache.js +50 -0
  222. package/dist/modules/shipment_tracking/lib/vessel-cache.js.map +7 -0
  223. package/dist/modules/shipment_tracking/lib/vessel-extraction.js +13 -0
  224. package/dist/modules/shipment_tracking/lib/vessel-extraction.js.map +7 -0
  225. package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js +62 -0
  226. package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js.map +7 -0
  227. package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js +48 -0
  228. package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js.map +7 -0
  229. package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js +15 -0
  230. package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js.map +7 -0
  231. package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js +47 -0
  232. package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js.map +7 -0
  233. package/dist/modules/shipment_tracking/notifications.js +145 -0
  234. package/dist/modules/shipment_tracking/notifications.js.map +7 -0
  235. package/dist/modules/shipment_tracking/services/carrierRegistry.js +24 -0
  236. package/dist/modules/shipment_tracking/services/carrierRegistry.js.map +7 -0
  237. package/dist/modules/shipment_tracking/services/poiNatsService.js +397 -0
  238. package/dist/modules/shipment_tracking/services/poiNatsService.js.map +7 -0
  239. package/dist/modules/shipment_tracking/services/shipsGoProvider.js +163 -0
  240. package/dist/modules/shipment_tracking/services/shipsGoProvider.js.map +7 -0
  241. package/dist/modules/shipment_tracking/services/trackingService.js +1283 -0
  242. package/dist/modules/shipment_tracking/services/trackingService.js.map +7 -0
  243. package/dist/modules/shipment_tracking/services/webhookService.js +263 -0
  244. package/dist/modules/shipment_tracking/services/webhookService.js.map +7 -0
  245. package/dist/modules/shipment_tracking/setup.js +72 -0
  246. package/dist/modules/shipment_tracking/setup.js.map +7 -0
  247. package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js +60 -0
  248. package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js.map +7 -0
  249. package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js +58 -0
  250. package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js.map +7 -0
  251. package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js +82 -0
  252. package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js.map +7 -0
  253. package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js +53 -0
  254. package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js.map +7 -0
  255. package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js +28 -0
  256. package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js.map +7 -0
  257. package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js +67 -0
  258. package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js.map +7 -0
  259. package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js +30 -0
  260. package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js.map +7 -0
  261. package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js +19 -0
  262. package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js.map +7 -0
  263. package/dist/modules/shipment_tracking/tables/index.js +6 -0
  264. package/dist/modules/shipment_tracking/tables/index.js.map +7 -0
  265. package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js +284 -0
  266. package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js.map +7 -0
  267. package/dist/modules/shipment_tracking/tables/tracking_job/table.js +36 -0
  268. package/dist/modules/shipment_tracking/tables/tracking_job/table.js.map +7 -0
  269. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js +25 -0
  270. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js.map +7 -0
  271. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js +355 -0
  272. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js.map +7 -0
  273. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js +26 -0
  274. package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js.map +7 -0
  275. package/dist/types/assets.d.js +1 -0
  276. package/dist/types/assets.d.js.map +7 -0
  277. package/generated/entities/bic_config/index.ts +20 -0
  278. package/generated/entities/carrier_config/index.ts +23 -0
  279. package/generated/entities/location_override/index.ts +26 -0
  280. package/generated/entities/shipment/index.ts +46 -0
  281. package/generated/entities/ships_go_config/index.ts +25 -0
  282. package/generated/entities/tracking_event/index.ts +60 -0
  283. package/generated/entities/tracking_job/index.ts +33 -0
  284. package/generated/entities/webhook/index.ts +22 -0
  285. package/generated/entities/webhook_delivery/index.ts +22 -0
  286. package/generated/entities.ids.generated.ts +47 -0
  287. package/package.json +81 -0
  288. package/src/index.ts +39 -0
  289. package/src/modules/shipment_tracking/__integration__/TC-TRACK-410-shipsgo-config-api.spec.ts +133 -0
  290. package/src/modules/shipment_tracking/__integration__/meta.ts +4 -0
  291. package/src/modules/shipment_tracking/__tests__/empty-return-stop.test.ts +231 -0
  292. package/src/modules/shipment_tracking/__tests__/fixtures/hapag-lloyd-transship-container.json +702 -0
  293. package/src/modules/shipment_tracking/__tests__/fixtures/index.ts +434 -0
  294. package/src/modules/shipment_tracking/__tests__/fixtures/maersk-multi-transship-completed.json +1518 -0
  295. package/src/modules/shipment_tracking/__tests__/fixtures/maersk-transship-intransit.json +558 -0
  296. package/src/modules/shipment_tracking/__tests__/fixtures/msc-direct.json +222 -0
  297. package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi-transship-completed.json +974 -0
  298. package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi.json +4846 -0
  299. package/src/modules/shipment_tracking/__tests__/fixtures/msc-transship.json +409 -0
  300. package/src/modules/shipment_tracking/__tests__/fixtures/poi-events.json +240 -0
  301. package/src/modules/shipment_tracking/__tests__/fixtures/synthetic/index.ts +138 -0
  302. package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-eta-updates.json +288 -0
  303. package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-route-inference.json +201 -0
  304. package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-voyage-progression.json +410 -0
  305. package/src/modules/shipment_tracking/__tests__/shipsgo-air-mapper.test.ts +157 -0
  306. package/src/modules/shipment_tracking/__tests__/shipsgo-client.test.ts +155 -0
  307. package/src/modules/shipment_tracking/__tests__/shipsgo-mapper.test.ts +201 -0
  308. package/src/modules/shipment_tracking/__tests__/shipsgo-poll.test.ts +357 -0
  309. package/src/modules/shipment_tracking/__tests__/shipsgo-provider.test.ts +364 -0
  310. package/src/modules/shipment_tracking/__tests__/trackingService.integration.test.ts +2248 -0
  311. package/src/modules/shipment_tracking/__tests__/webhookPayload.test.ts +151 -0
  312. package/src/modules/shipment_tracking/acl.ts +18 -0
  313. package/src/modules/shipment_tracking/api/bic-configs/route.ts +206 -0
  314. package/src/modules/shipment_tracking/api/bic-configs/test/route.ts +108 -0
  315. package/src/modules/shipment_tracking/api/cargo-events/route.ts +101 -0
  316. package/src/modules/shipment_tracking/api/carrier-configs/route.ts +142 -0
  317. package/src/modules/shipment_tracking/api/dashboard/ships-map/route.ts +246 -0
  318. package/src/modules/shipment_tracking/api/location-overrides/route.ts +185 -0
  319. package/src/modules/shipment_tracking/api/openapi.ts +28 -0
  320. package/src/modules/shipment_tracking/api/shipments/route.ts +197 -0
  321. package/src/modules/shipment_tracking/api/shipsgo-configs/route.ts +215 -0
  322. package/src/modules/shipment_tracking/api/tracking-jobs/route.ts +149 -0
  323. package/src/modules/shipment_tracking/api/tracking-jobs/sync/route.ts +116 -0
  324. package/src/modules/shipment_tracking/api/utils.ts +10 -0
  325. package/src/modules/shipment_tracking/api/webhooks/deliveries/route.ts +82 -0
  326. package/src/modules/shipment_tracking/api/webhooks/route.ts +138 -0
  327. package/src/modules/shipment_tracking/api/webhooks/test/route.ts +84 -0
  328. package/src/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
  329. package/src/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
  330. package/src/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
  331. package/src/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
  332. package/src/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
  333. package/src/modules/shipment_tracking/assets/carriers/msc.png +0 -0
  334. package/src/modules/shipment_tracking/assets/carriers/one.png +0 -0
  335. package/src/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
  336. package/src/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
  337. package/src/modules/shipment_tracking/assets/carriers/zim.png +0 -0
  338. package/src/modules/shipment_tracking/assets/index.ts +66 -0
  339. package/src/modules/shipment_tracking/backend/carrier-configs/page.meta.ts +16 -0
  340. package/src/modules/shipment_tracking/backend/carrier-configs/page.tsx +782 -0
  341. package/src/modules/shipment_tracking/backend/location-overrides/page.meta.ts +16 -0
  342. package/src/modules/shipment_tracking/backend/location-overrides/page.tsx +241 -0
  343. package/src/modules/shipment_tracking/backend/shipment-tracking/page.meta.ts +16 -0
  344. package/src/modules/shipment_tracking/backend/shipment-tracking/page.tsx +340 -0
  345. package/src/modules/shipment_tracking/backend/tracking-jobs/page.meta.ts +16 -0
  346. package/src/modules/shipment_tracking/backend/tracking-jobs/page.tsx +16 -0
  347. package/src/modules/shipment_tracking/backend/webhooks/page.meta.ts +16 -0
  348. package/src/modules/shipment_tracking/backend/webhooks/page.tsx +228 -0
  349. package/src/modules/shipment_tracking/ce.ts +48 -0
  350. package/src/modules/shipment_tracking/cli.ts +321 -0
  351. package/src/modules/shipment_tracking/commands/bic-configs.ts +94 -0
  352. package/src/modules/shipment_tracking/commands/carrier-configs.ts +89 -0
  353. package/src/modules/shipment_tracking/commands/index.ts +8 -0
  354. package/src/modules/shipment_tracking/commands/location-overrides.ts +119 -0
  355. package/src/modules/shipment_tracking/commands/shipments.ts +247 -0
  356. package/src/modules/shipment_tracking/commands/shipsgo-configs.ts +101 -0
  357. package/src/modules/shipment_tracking/commands/tracking-jobs.ts +158 -0
  358. package/src/modules/shipment_tracking/commands/tracking.ts +230 -0
  359. package/src/modules/shipment_tracking/commands/webhooks.ts +159 -0
  360. package/src/modules/shipment_tracking/components/CombinedTimestampCell.tsx +236 -0
  361. package/src/modules/shipment_tracking/components/FacilityLocationInput.tsx +235 -0
  362. package/src/modules/shipment_tracking/components/LocationOverrideDrawer.tsx +586 -0
  363. package/src/modules/shipment_tracking/components/ShipmentDetailsDrawer.tsx +1364 -0
  364. package/src/modules/shipment_tracking/components/ShipmentDrawer.tsx +498 -0
  365. package/src/modules/shipment_tracking/components/ShipsGoConfigSection.tsx +266 -0
  366. package/src/modules/shipment_tracking/components/TimestampCell.tsx +146 -0
  367. package/src/modules/shipment_tracking/components/TrackingJobDrawer.tsx +467 -0
  368. package/src/modules/shipment_tracking/components/VesselTrackingMap.tsx +761 -0
  369. package/src/modules/shipment_tracking/components/WebhookDrawer.tsx +434 -0
  370. package/src/modules/shipment_tracking/data/entities.ts +748 -0
  371. package/src/modules/shipment_tracking/data/validators.ts +523 -0
  372. package/src/modules/shipment_tracking/di.ts +73 -0
  373. package/src/modules/shipment_tracking/encryption.ts +17 -0
  374. package/src/modules/shipment_tracking/events.ts +122 -0
  375. package/src/modules/shipment_tracking/hooks/useVesselTracking.ts +297 -0
  376. package/src/modules/shipment_tracking/i18n/de.json +327 -0
  377. package/src/modules/shipment_tracking/i18n/en.json +327 -0
  378. package/src/modules/shipment_tracking/i18n/es.json +327 -0
  379. package/src/modules/shipment_tracking/i18n/pl.json +327 -0
  380. package/src/modules/shipment_tracking/index.ts +13 -0
  381. package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-mapping.test.ts +385 -0
  382. package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-parser.test.ts +398 -0
  383. package/src/modules/shipment_tracking/lib/__tests__/empty-return.test.ts +174 -0
  384. package/src/modules/shipment_tracking/lib/__tests__/poi-event-processor.test.ts +699 -0
  385. package/src/modules/shipment_tracking/lib/__tests__/route-inference.test.ts +402 -0
  386. package/src/modules/shipment_tracking/lib/__tests__/status-machine.test.ts +447 -0
  387. package/src/modules/shipment_tracking/lib/__tests__/time-extraction.test.ts +331 -0
  388. package/src/modules/shipment_tracking/lib/__tests__/timestamp-utils.test.ts +260 -0
  389. package/src/modules/shipment_tracking/lib/__tests__/vessel-api.test.ts +125 -0
  390. package/src/modules/shipment_tracking/lib/__tests__/vessel-extraction.test.ts +108 -0
  391. package/src/modules/shipment_tracking/lib/adapters/cma-cgm.ts +84 -0
  392. package/src/modules/shipment_tracking/lib/adapters/cosco-types.ts +145 -0
  393. package/src/modules/shipment_tracking/lib/adapters/cosco.ts +314 -0
  394. package/src/modules/shipment_tracking/lib/adapters/evergreen.ts +107 -0
  395. package/src/modules/shipment_tracking/lib/adapters/hapag-lloyd.ts +88 -0
  396. package/src/modules/shipment_tracking/lib/adapters/index.ts +18 -0
  397. package/src/modules/shipment_tracking/lib/adapters/maersk.ts +104 -0
  398. package/src/modules/shipment_tracking/lib/adapters/msc.ts +223 -0
  399. package/src/modules/shipment_tracking/lib/adapters/zim.ts +106 -0
  400. package/src/modules/shipment_tracking/lib/audit-helpers.ts +29 -0
  401. package/src/modules/shipment_tracking/lib/auth/base64url.ts +4 -0
  402. package/src/modules/shipment_tracking/lib/auth/oauth-client.ts +53 -0
  403. package/src/modules/shipment_tracking/lib/background.ts +24 -0
  404. package/src/modules/shipment_tracking/lib/bic-api-client.ts +199 -0
  405. package/src/modules/shipment_tracking/lib/carrier-adapter.ts +136 -0
  406. package/src/modules/shipment_tracking/lib/current-vessel.ts +274 -0
  407. package/src/modules/shipment_tracking/lib/dcsa-event-mapping.ts +202 -0
  408. package/src/modules/shipment_tracking/lib/dcsa-event-parser.ts +163 -0
  409. package/src/modules/shipment_tracking/lib/dcsa-params.ts +14 -0
  410. package/src/modules/shipment_tracking/lib/empty-return.ts +122 -0
  411. package/src/modules/shipment_tracking/lib/location-overrides.ts +150 -0
  412. package/src/modules/shipment_tracking/lib/location-types.ts +154 -0
  413. package/src/modules/shipment_tracking/lib/logger.ts +195 -0
  414. package/src/modules/shipment_tracking/lib/poi-event-processor.ts +302 -0
  415. package/src/modules/shipment_tracking/lib/poi-nats-config.ts +134 -0
  416. package/src/modules/shipment_tracking/lib/poi-types.ts +198 -0
  417. package/src/modules/shipment_tracking/lib/rate-limiter.ts +58 -0
  418. package/src/modules/shipment_tracking/lib/route-extraction.ts +439 -0
  419. package/src/modules/shipment_tracking/lib/route-inference.ts +238 -0
  420. package/src/modules/shipment_tracking/lib/schedule-generator.ts +92 -0
  421. package/src/modules/shipment_tracking/lib/shipsgo-client.ts +350 -0
  422. package/src/modules/shipment_tracking/lib/shipsgo-mapper.ts +296 -0
  423. package/src/modules/shipment_tracking/lib/status-machine.ts +230 -0
  424. package/src/modules/shipment_tracking/lib/time-extraction.ts +85 -0
  425. package/src/modules/shipment_tracking/lib/timestamp-utils.ts +244 -0
  426. package/src/modules/shipment_tracking/lib/vessel-api.ts +299 -0
  427. package/src/modules/shipment_tracking/lib/vessel-cache.ts +102 -0
  428. package/src/modules/shipment_tracking/lib/vessel-extraction.ts +39 -0
  429. package/src/modules/shipment_tracking/lib/webhook-dispatcher.ts +93 -0
  430. package/src/modules/shipment_tracking/migrations/.snapshot-open-mercato.json +2914 -0
  431. package/src/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.ts +60 -0
  432. package/src/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.ts +22 -0
  433. package/src/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.ts +65 -0
  434. package/src/modules/shipment_tracking/notifications.ts +151 -0
  435. package/src/modules/shipment_tracking/services/carrierRegistry.ts +29 -0
  436. package/src/modules/shipment_tracking/services/poiNatsService.ts +526 -0
  437. package/src/modules/shipment_tracking/services/shipsGoProvider.ts +231 -0
  438. package/src/modules/shipment_tracking/services/trackingService.ts +1777 -0
  439. package/src/modules/shipment_tracking/services/webhookService.ts +347 -0
  440. package/src/modules/shipment_tracking/setup.ts +99 -0
  441. package/src/modules/shipment_tracking/subscribers/__tests__/terminal-event-ingest.test.ts +141 -0
  442. package/src/modules/shipment_tracking/subscribers/cargo-event-created.ts +115 -0
  443. package/src/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.ts +115 -0
  444. package/src/modules/shipment_tracking/subscribers/poi-event-notification.ts +144 -0
  445. package/src/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.ts +94 -0
  446. package/src/modules/shipment_tracking/subscribers/shipment-status-changed.ts +41 -0
  447. package/src/modules/shipment_tracking/subscribers/terminal-event-ingest.ts +109 -0
  448. package/src/modules/shipment_tracking/subscribers/tracking-job-initial-poll.ts +53 -0
  449. package/src/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.ts +50 -0
  450. package/src/modules/shipment_tracking/tables/index.ts +4 -0
  451. package/src/modules/shipment_tracking/tables/tracking_job/table.client.tsx +337 -0
  452. package/src/modules/shipment_tracking/tables/tracking_job/table.ts +34 -0
  453. package/src/modules/shipment_tracking/widgets/dashboard/ships-map/config.ts +32 -0
  454. package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.tsx +448 -0
  455. package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.ts +25 -0
  456. package/src/types/assets.d.ts +5 -0
@@ -0,0 +1,163 @@
1
+ import crypto from 'node:crypto'
2
+ import type { CarrierFetchedEvent, DocumentReference, SealInfo } from './carrier-adapter'
3
+ import type { TrackingEventType, TrackingEventClassifierCode } from '../data/entities'
4
+
5
+ type RawDcsaEvent = Record<string, unknown>
6
+
7
+ /**
8
+ * Parse coordinate value - handles both number and string formats from DCSA APIs.
9
+ * Some carriers return coordinates as strings (e.g., "54.381628"), others as numbers.
10
+ */
11
+ function parseCoordinate(value: unknown): number | null {
12
+ if (value == null) return null
13
+ if (typeof value === 'number') return Number.isNaN(value) ? null : value
14
+ if (typeof value === 'string') {
15
+ const trimmed = value.trim()
16
+ if (trimmed === '') return null
17
+ const parsed = parseFloat(trimmed)
18
+ return Number.isNaN(parsed) ? null : parsed
19
+ }
20
+ return null
21
+ }
22
+
23
+ type DcsaResponseShape =
24
+ | { events: RawDcsaEvent[] }
25
+ | RawDcsaEvent[]
26
+
27
+ export function extractDcsaEventArray(data: unknown): RawDcsaEvent[] {
28
+ if (Array.isArray(data)) return data
29
+ if (data && typeof data === 'object' && 'events' in data && Array.isArray((data as Record<string, unknown>).events)) {
30
+ return (data as { events: RawDcsaEvent[] }).events
31
+ }
32
+ return []
33
+ }
34
+
35
+ /**
36
+ * Parses DCSA T&T v3.0 events into normalized CarrierFetchedEvent objects.
37
+ * Handles both flat event structure and nested metadata/payload structure.
38
+ */
39
+ export function parseDcsaEvents(data: DcsaResponseShape, _carrierName: string): CarrierFetchedEvent[] {
40
+ const events = extractDcsaEventArray(data)
41
+
42
+ return events.map((event) => {
43
+ // DCSA v3.0 can have nested metadata/payload or flat structure
44
+ const metadata = event.metadata as Record<string, unknown> | undefined
45
+ const payload = event.payload as Record<string, unknown> | undefined
46
+ const effectiveEvent = payload ?? event // Use payload if present, otherwise use flat event
47
+
48
+ // Extract nested objects
49
+ const transportCall = effectiveEvent.transportCall as Record<string, unknown> | undefined
50
+ const vessel = transportCall?.vessel as Record<string, unknown> | undefined
51
+ const location = (effectiveEvent.eventLocation ??
52
+ transportCall?.location) as Record<string, unknown> | undefined
53
+ const geoLocation = location?.geoLocation as Record<string, unknown> | undefined
54
+ const address = location?.address as Record<string, unknown> | undefined
55
+ const publisher = (metadata?.publisher ?? event.publisher) as Record<string, unknown> | undefined
56
+
57
+ // ─── Event Source ──────────────────────────────────────────────
58
+ const sourceEventId = (metadata?.eventID ?? event.eventID ?? event.eventId ?? crypto.randomUUID()) as string
59
+
60
+ // ─── Core Event Fields ─────────────────────────────────────────
61
+ const eventType = (metadata?.eventType ?? event.eventType) as TrackingEventType
62
+ const eventCode = (effectiveEvent.equipmentEventTypeCode ??
63
+ effectiveEvent.transportEventTypeCode ??
64
+ effectiveEvent.shipmentEventTypeCode) as string
65
+ const eventClassifierCode = (effectiveEvent.eventClassifierCode ?? null) as TrackingEventClassifierCode | null
66
+ const eventDateTime = new Date((effectiveEvent.eventDateTime ?? event.eventDateTime) as string)
67
+
68
+ // ─── Document References ───────────────────────────────────────
69
+ const rawDocRefs = (effectiveEvent.relatedDocumentReferences ?? effectiveEvent.documentReferences) as Array<Record<string, unknown>> | undefined
70
+ const relatedDocumentReferences: DocumentReference[] | null = rawDocRefs?.map((ref) => ({
71
+ type: (ref.type ?? ref.documentReferenceType) as string,
72
+ value: (ref.value ?? ref.documentReferenceValue) as string,
73
+ })) ?? null
74
+
75
+ // ─── Seals ─────────────────────────────────────────────────────
76
+ const rawSeals = effectiveEvent.seals as Array<Record<string, unknown>> | undefined
77
+ const seals: SealInfo[] | null = rawSeals?.map((seal) => ({
78
+ number: (seal.sealNumber ?? seal.number) as string,
79
+ source: (seal.sealSource ?? seal.source) as string | null ?? null,
80
+ type: (seal.sealType ?? seal.type) as string | null ?? null,
81
+ })) ?? null
82
+
83
+ // ─── Event Created DateTime ────────────────────────────────────
84
+ const eventCreatedDateTimeRaw = metadata?.eventCreatedDateTime ?? event.eventCreatedDateTime
85
+ const eventCreatedDateTime = eventCreatedDateTimeRaw
86
+ ? new Date(eventCreatedDateTimeRaw as string)
87
+ : null
88
+
89
+ return {
90
+ // ─── Event Source ──────────────────────────────────────────────
91
+ source: 'dcsa' as const,
92
+ sourceEventId,
93
+
94
+ // ─── Core Event Fields ─────────────────────────────────────────
95
+ eventType,
96
+ eventCode,
97
+ eventClassifierCode,
98
+ eventDateTime,
99
+ eventDateTimeOffset: null, // Not typically in DCSA response, derived from datetime
100
+ description: (effectiveEvent.description as string) ?? null,
101
+ rawData: event,
102
+
103
+ // ─── Equipment Fields ──────────────────────────────────────────
104
+ equipmentReference: (effectiveEvent.equipmentReference as string) ?? null,
105
+ isoEquipmentCode: (effectiveEvent.ISOEquipmentCode as string) ?? null,
106
+ emptyIndicatorCode: (effectiveEvent.emptyIndicatorCode as 'EMPTY' | 'LADEN') ?? null,
107
+ isTransshipmentMove: (effectiveEvent.isTransshipmentMove as boolean) ?? null,
108
+
109
+ // ─── Location Fields ───────────────────────────────────────────
110
+ locationName: (location?.locationName as string) ?? null,
111
+ locationUnlocode: ((location?.UNLocationCode ?? location?.unLocationCode ??
112
+ transportCall?.UNLocationCode ?? transportCall?.unLocationCode) as string) ?? null,
113
+ locationCountry: (address?.country as string) ?? null,
114
+
115
+ // Facility code - transportCall has priority (where most carriers put it), then location
116
+ facilityCode: ((transportCall?.facilityCode ?? location?.facilityCode) as string) ?? null,
117
+ facilityCodeListProvider: ((transportCall?.facilityCodeListProvider ??
118
+ location?.facilityCodeListProvider) as 'SMDG' | 'BIC') ?? null,
119
+ facilityTypeCode: ((transportCall?.facilityTypeCode ?? effectiveEvent.facilityTypeCode ??
120
+ location?.facilityTypeCode) as string) ?? null,
121
+
122
+ // Address from otherFacility (full address string from DCSA)
123
+ facilityAddress: (transportCall?.otherFacility as string) ?? null,
124
+
125
+ // Coordinates - check location directly (as strings), then geoLocation nested
126
+ latitude: parseCoordinate(location?.latitude) ?? parseCoordinate(geoLocation?.latitude),
127
+ longitude: parseCoordinate(location?.longitude) ?? parseCoordinate(geoLocation?.longitude),
128
+
129
+ // ─── Transport Call Fields ─────────────────────────────────────
130
+ transportCallReference: (transportCall?.transportCallReference as string) ?? null,
131
+ modeOfTransport: (transportCall?.modeOfTransport as 'VESSEL' | 'RAIL' | 'TRUCK' | 'BARGE') ?? null,
132
+ vesselName: ((vessel?.vesselName ?? vessel?.name) as string) ?? null,
133
+ vesselImo: (vessel?.vesselIMONumber as string) ?? null,
134
+ voyageNumber: (transportCall?.carrierExportVoyageNumber as string) ??
135
+ (transportCall?.exportVoyageNumber as string) ??
136
+ (transportCall?.importVoyageNumber as string) ??
137
+ (transportCall?.voyageNumber as string) ??
138
+ (vessel?.voyage as string) ?? null,
139
+ carrierServiceCode: (transportCall?.carrierServiceCode as string) ?? null,
140
+ carrierExportVoyageNumber: ((transportCall?.carrierExportVoyageNumber ?? transportCall?.exportVoyageNumber) as string) ?? null,
141
+ carrierImportVoyageNumber: ((transportCall?.carrierImportVoyageNumber ?? transportCall?.importVoyageNumber) as string) ?? null,
142
+ universalServiceReference: (transportCall?.universalServiceReference as string) ?? null,
143
+ universalExportVoyageReference: (transportCall?.universalExportVoyageReference as string) ?? null,
144
+ universalImportVoyageReference: (transportCall?.universalImportVoyageReference as string) ?? null,
145
+ portVisitReference: (transportCall?.portVisitReference as string) ?? null,
146
+
147
+ // ─── Document References ───────────────────────────────────────
148
+ relatedDocumentReferences,
149
+
150
+ // ─── Metadata Fields ───────────────────────────────────────────
151
+ eventCreatedDateTime,
152
+ retractedEventId: (metadata?.retractedEventID as string) ?? null,
153
+ publisherName: (publisher?.partyName as string) ?? _carrierName,
154
+ publisherRole: (metadata?.publisherRole as string) ??
155
+ (event.publisherRole as string) ?? null,
156
+
157
+ // ─── Additional Event Fields ───────────────────────────────────
158
+ delayReasonCode: (effectiveEvent.delayReasonCode as string) ?? null,
159
+ changeRemark: (effectiveEvent.changeRemark as string) ?? null,
160
+ seals,
161
+ }
162
+ })
163
+ }
@@ -0,0 +1,14 @@
1
+ import type { TrackingReferenceType } from '../data/entities'
2
+
3
+ export function buildDcsaQueryParams(referenceValue: string, referenceType: TrackingReferenceType): string {
4
+ switch (referenceType) {
5
+ case 'container':
6
+ return `equipmentReference=${encodeURIComponent(referenceValue)}`
7
+ case 'booking':
8
+ return `carrierBookingReference=${encodeURIComponent(referenceValue)}`
9
+ case 'bol':
10
+ return `transportDocumentReference=${encodeURIComponent(referenceValue)}`
11
+ default:
12
+ return `transportDocumentReference=${encodeURIComponent(referenceValue)}`
13
+ }
14
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Container-journey completion detection (to stop polling a finished job).
3
+ *
4
+ * A container is done when the carrier reports either:
5
+ *
6
+ * - **Empty return** (DCSA carriers) — an actual (`ACT`) empty gate-in
7
+ * (`GTIN` + `emptyIndicatorCode === 'EMPTY'`). Keying on the empty flag is
8
+ * unambiguous: a *laden* `GTIN` is the export-origin gate-in (see
9
+ * `route-inference.ts`), so this can never fire at origin.
10
+ * - **Delivered to consignee** (COSCO) — an actual `DLVR` event. COSCO never
11
+ * emits `GTIN`/`emptyIndicatorCode`, so it needs its own terminal signal.
12
+ * `DLVR` is COSCO-exclusive (no other adapter or fixture emits it), so this
13
+ * branch cannot prematurely stop a DCSA carrier. Note: we deliberately key on
14
+ * the `DLVR` *event code*, not the `DELIVERED` *status* — DCSA carriers reach
15
+ * `DELIVERED` via `GTOT`-at-destination (laden pickup) *before* the empty is
16
+ * returned, so a status-based stop would defeat the empty-return intent.
17
+ *
18
+ * A `TrackingJob` may cover many containers (Bill of Lading / Booking Number),
19
+ * so a job is only complete when **every** discovered container is complete —
20
+ * never on the first. Pure helpers: no DI, no persistence.
21
+ *
22
+ * Backup for missing events: empty gate-in (and COSCO `DLVR`) are sometimes
23
+ * absent from carrier feeds, so `destinationArrivedBefore` stops a job once it
24
+ * has arrived at its destination port and `STALE_AFTER_ARRIVAL_DAYS` have passed.
25
+ */
26
+
27
+ /** Minimal event shape both a fetched and a persisted `TrackingEvent` satisfy. */
28
+ export type EmptyReturnEvent = {
29
+ eventType: string
30
+ eventCode: string
31
+ eventClassifierCode?: string | null
32
+ emptyIndicatorCode?: string | null
33
+ equipmentReference?: string | null
34
+ locationUnlocode?: string | null
35
+ eventDateTime?: Date | string | null
36
+ }
37
+
38
+ /** Buffer after destination arrival before we stop a job whose empty-return event never arrived. */
39
+ export const STALE_AFTER_ARRIVAL_DAYS = 30
40
+ const DAY_MS = 24 * 60 * 60 * 1000
41
+
42
+ /** The `cutoff` for `destinationArrivedBefore`: arrivals at/before this are stale. */
43
+ export function staleArrivalCutoff(now: Date = new Date()): Date {
44
+ return new Date(now.getTime() - STALE_AFTER_ARRIVAL_DAYS * DAY_MS)
45
+ }
46
+
47
+ /** An actual empty gate-in — the empty container returned to a depot (DCSA). */
48
+ export function isEmptyGateIn(e: EmptyReturnEvent): boolean {
49
+ return (
50
+ e.eventType === 'EQUIPMENT' &&
51
+ e.eventCode === 'GTIN' &&
52
+ e.emptyIndicatorCode === 'EMPTY' &&
53
+ e.eventClassifierCode === 'ACT'
54
+ )
55
+ }
56
+
57
+ /** An actual delivery to consignee — COSCO's terminal signal (CS210 → DLVR). */
58
+ export function isFinalDelivery(e: EmptyReturnEvent): boolean {
59
+ return e.eventType === 'EQUIPMENT' && e.eventCode === 'DLVR' && e.eventClassifierCode === 'ACT'
60
+ }
61
+
62
+ /** A container is done when it is returned empty (DCSA) or delivered (COSCO). */
63
+ export function isContainerComplete(e: EmptyReturnEvent): boolean {
64
+ return isEmptyGateIn(e) || isFinalDelivery(e)
65
+ }
66
+
67
+ /**
68
+ * True when the job has ≥1 discovered container and every one has completed its
69
+ * journey (empty return or delivery), i.e. polling can stop.
70
+ */
71
+ export function allContainersComplete(
72
+ events: readonly EmptyReturnEvent[],
73
+ containerNumbers: ReadonlySet<string>,
74
+ ): boolean {
75
+ if (containerNumbers.size === 0) return false
76
+ const complete = new Set<string>()
77
+ for (const e of events) {
78
+ if (e.equipmentReference && isContainerComplete(e)) complete.add(e.equipmentReference)
79
+ }
80
+ for (const c of containerNumbers) {
81
+ if (!complete.has(c)) return false
82
+ }
83
+ return true
84
+ }
85
+
86
+ /**
87
+ * An actual arrival at the job's destination port — `ARRI` (transport) or `DISC`
88
+ * (equipment), `ACT`, at the destination UNLOCODE. Destination-scoped by
89
+ * construction: a null/unknown destination matches nothing, so the backup can
90
+ * never fire for an in-transit shipment. Transshipment arrivals (different
91
+ * UNLOCODE) are excluded.
92
+ */
93
+ export function isDestinationArrival(
94
+ e: EmptyReturnEvent,
95
+ destinationUnlocode: string | null | undefined,
96
+ ): boolean {
97
+ if (!destinationUnlocode) return false
98
+ return (
99
+ (e.eventCode === 'ARRI' || e.eventCode === 'DISC') &&
100
+ e.eventClassifierCode === 'ACT' &&
101
+ !!e.locationUnlocode &&
102
+ e.locationUnlocode.toUpperCase() === destinationUnlocode.toUpperCase()
103
+ )
104
+ }
105
+
106
+ /**
107
+ * Time-based backup: true when the shipment arrived at its destination port
108
+ * at/before `cutoff` (i.e. long enough ago to stop even though the empty-return
109
+ * event never arrived). Job-level — `ARRI` carries no container reference.
110
+ */
111
+ export function destinationArrivedBefore(
112
+ events: readonly EmptyReturnEvent[],
113
+ destinationUnlocode: string | null | undefined,
114
+ cutoff: Date,
115
+ ): boolean {
116
+ for (const e of events) {
117
+ if (!isDestinationArrival(e, destinationUnlocode)) continue
118
+ const t = e.eventDateTime ? new Date(e.eventDateTime).getTime() : NaN
119
+ if (!Number.isNaN(t) && t <= cutoff.getTime()) return true
120
+ }
121
+ return false
122
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Location Override Helpers
3
+ *
4
+ * Provides lookup and application of location overrides for BIC/SMDG facility data.
5
+ * Overrides allow correcting incorrect terminal/facility information from BIC API.
6
+ */
7
+
8
+ import type { EntityManager } from '@mikro-orm/postgresql'
9
+ import { LocationOverride, type FacilityLocation, type FacilityCodeListProvider } from '../data/entities'
10
+
11
+ export interface LocationOverrideMatch {
12
+ unlocode: string
13
+ facilityCode: string
14
+ facilityCodeListProvider: FacilityCodeListProvider
15
+ carrierCode?: string | null
16
+ }
17
+
18
+ export interface LocationOverrideScope {
19
+ organizationId: string
20
+ tenantId: string
21
+ }
22
+
23
+ /**
24
+ * Finds the most specific location override for a given facility.
25
+ *
26
+ * Priority order:
27
+ * 1. Carrier-specific override (carrierCode matches)
28
+ * 2. Global override (carrierCode is null)
29
+ *
30
+ * @returns The override to apply, or null if no override exists
31
+ */
32
+ export async function findLocationOverride(
33
+ em: EntityManager,
34
+ match: LocationOverrideMatch,
35
+ scope: LocationOverrideScope
36
+ ): Promise<LocationOverride | null> {
37
+ if (!match.unlocode || !match.facilityCode || !match.facilityCodeListProvider) {
38
+ return null
39
+ }
40
+
41
+ // Build query conditions - carrier-specific first, then global
42
+ const conditions: Record<string, unknown> = {
43
+ organizationId: scope.organizationId,
44
+ tenantId: scope.tenantId,
45
+ unlocode: match.unlocode.toUpperCase(),
46
+ facilityCode: match.facilityCode,
47
+ facilityCodeListProvider: match.facilityCodeListProvider,
48
+ isActive: true,
49
+ deletedAt: null,
50
+ }
51
+
52
+ // First try carrier-specific override (normalize to uppercase)
53
+ if (match.carrierCode) {
54
+ const carrierSpecific = await em.findOne(LocationOverride, {
55
+ ...conditions,
56
+ carrierCode: match.carrierCode.toUpperCase(),
57
+ })
58
+ if (carrierSpecific) {
59
+ return carrierSpecific
60
+ }
61
+ }
62
+
63
+ // Fall back to global override (carrierCode is null)
64
+ const globalOverride = await em.findOne(LocationOverride, {
65
+ ...conditions,
66
+ carrierCode: null,
67
+ })
68
+
69
+ return globalOverride
70
+ }
71
+
72
+ /**
73
+ * Applies override data to a FacilityLocation.
74
+ * Only non-null fields from the override are applied.
75
+ * Sets source to 'manual' to indicate the data was manually overridden.
76
+ */
77
+ export function applyLocationOverride(
78
+ location: FacilityLocation,
79
+ overrideData: Partial<FacilityLocation>
80
+ ): FacilityLocation {
81
+ const result: FacilityLocation = { ...location }
82
+
83
+ // Apply each override field if it's defined and not null
84
+ if (overrideData.name != null) {
85
+ result.name = overrideData.name
86
+ }
87
+ if (overrideData.address !== undefined) {
88
+ result.address = overrideData.address
89
+ }
90
+ if (overrideData.operatorName !== undefined) {
91
+ result.operatorName = overrideData.operatorName
92
+ }
93
+ if (overrideData.countryCode !== undefined) {
94
+ result.countryCode = overrideData.countryCode
95
+ }
96
+ if (overrideData.facilityTypeCode !== undefined) {
97
+ result.facilityTypeCode = overrideData.facilityTypeCode
98
+ }
99
+ if (overrideData.coords !== undefined) {
100
+ result.coords = overrideData.coords
101
+ }
102
+ // Can also override unlocode/facilityCode if needed (rare)
103
+ if (overrideData.unlocode !== undefined) {
104
+ result.unlocode = overrideData.unlocode
105
+ }
106
+ if (overrideData.facilityCode !== undefined) {
107
+ result.facilityCode = overrideData.facilityCode
108
+ }
109
+ if (overrideData.facilityCodeListProvider !== undefined) {
110
+ result.facilityCodeListProvider = overrideData.facilityCodeListProvider
111
+ }
112
+
113
+ // Mark as manually overridden
114
+ result.source = 'manual'
115
+
116
+ return result
117
+ }
118
+
119
+ /**
120
+ * Finds and applies location override to a FacilityLocation in one step.
121
+ * Returns the original location if no override exists.
122
+ */
123
+ export async function applyLocationOverrideIfExists(
124
+ em: EntityManager,
125
+ location: FacilityLocation | null | undefined,
126
+ carrierCode: string | null | undefined,
127
+ scope: LocationOverrideScope
128
+ ): Promise<FacilityLocation | null> {
129
+ if (!location) {
130
+ return null
131
+ }
132
+
133
+ // Skip if location doesn't have required match fields
134
+ if (!location.unlocode || !location.facilityCode || !location.facilityCodeListProvider) {
135
+ return location
136
+ }
137
+
138
+ const override = await findLocationOverride(em, {
139
+ unlocode: location.unlocode,
140
+ facilityCode: location.facilityCode,
141
+ facilityCodeListProvider: location.facilityCodeListProvider,
142
+ carrierCode,
143
+ }, scope)
144
+
145
+ if (override) {
146
+ return applyLocationOverride(location, override.overrideData)
147
+ }
148
+
149
+ return location
150
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Location Types for Shipment Tracking
3
+ *
4
+ * Rich location data combining port (UN/LOCODE) and facility/terminal details.
5
+ * Used for Shipment origin/destination and RouteStopEntry.
6
+ */
7
+
8
+ // ─── Types ───────────────────────────────────────────────────
9
+
10
+ /**
11
+ * Rich location data for origin, destination, or transshipment points.
12
+ * Combines port-level (UN/LOCODE) with facility-level (terminal) details.
13
+ */
14
+ export interface FacilityLocation {
15
+ // Display name (terminal or port name)
16
+ name: string
17
+
18
+ // Port-level identifiers
19
+ unlocode: string | null // UN/LOCODE (e.g., "PLGDN")
20
+ countryCode: string | null // ISO 3166-1 alpha-2 (e.g., "PL")
21
+
22
+ // Facility/terminal identifiers (separate fields)
23
+ facilityCode: string | null // SMDG/BIC code (e.g., "DCT")
24
+ facilityCodeListProvider: 'BIC' | 'SMDG' | null
25
+ facilityTypeCode: string | null // POTE (port terminal), DEPO (depot), etc.
26
+
27
+ // Address (from DCSA otherFacility or BIC API)
28
+ address: string | null // Full address string
29
+
30
+ // Coordinates
31
+ coords: {
32
+ latitude: number
33
+ longitude: number
34
+ } | null
35
+
36
+ // Operator (from BIC API enrichment only)
37
+ operatorName: string | null
38
+
39
+ // Source of the data
40
+ source: 'dcsa' | 'bic' | 'manual'
41
+ }
42
+
43
+ /**
44
+ * Input type for building FacilityLocation from TrackingEvent data.
45
+ */
46
+ export interface LocationEventInput {
47
+ locationName?: string | null
48
+ locationUnlocode?: string | null
49
+ locationCountry?: string | null
50
+ facilityCode?: string | null
51
+ facilityCodeListProvider?: 'BIC' | 'SMDG' | null
52
+ facilityTypeCode?: string | null
53
+ facilityAddress?: string | null
54
+ latitude?: number | null
55
+ longitude?: number | null
56
+ }
57
+
58
+ // ─── Helpers ─────────────────────────────────────────────────
59
+
60
+ /**
61
+ * Determines if location data is "complete enough" to skip BIC enrichment.
62
+ * Complete = has name AND (coords OR address)
63
+ */
64
+ export function isLocationComplete(loc: Partial<FacilityLocation> | null | undefined): boolean {
65
+ if (!loc) return false
66
+ const hasName = !!loc.name && loc.name !== 'Unknown'
67
+ const hasCoords = loc.coords?.latitude != null && loc.coords?.longitude != null
68
+ const hasAddress = !!loc.address
69
+
70
+ // Complete if we have name AND (coords OR address)
71
+ return hasName && (hasCoords || hasAddress)
72
+ }
73
+
74
+ /**
75
+ * Builds a FacilityLocation from TrackingEvent data.
76
+ * Extracts country code from UN/LOCODE if not provided.
77
+ */
78
+ export function buildLocationFromEvent(event: LocationEventInput): FacilityLocation {
79
+ // Extract country code from UN/LOCODE (first 2 chars) if not provided
80
+ const countryCode = event.locationCountry ||
81
+ (event.locationUnlocode?.length === 5 ? event.locationUnlocode.slice(0, 2) : null)
82
+
83
+ return {
84
+ name: event.locationName || event.locationUnlocode || 'Unknown',
85
+ unlocode: event.locationUnlocode || null,
86
+ countryCode,
87
+ facilityCode: event.facilityCode || null,
88
+ facilityCodeListProvider: event.facilityCodeListProvider || null,
89
+ facilityTypeCode: event.facilityTypeCode || null,
90
+ address: event.facilityAddress || null,
91
+ coords: (event.latitude != null && event.longitude != null)
92
+ ? { latitude: event.latitude, longitude: event.longitude }
93
+ : null,
94
+ operatorName: null, // Only populated by BIC enrichment
95
+ source: 'dcsa',
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Merges BIC enrichment data into an existing FacilityLocation.
101
+ * BIC provides more detailed facility names (e.g., "GDYNIA CONTAINER TERMINAL S.A.")
102
+ * so we prefer BIC name over generic port names from DCSA.
103
+ */
104
+ export function mergeLocationWithBicData(
105
+ location: FacilityLocation,
106
+ bicData: {
107
+ name?: string
108
+ address?: string
109
+ coords?: { latitude: number; longitude: number }
110
+ operatorName?: string
111
+ facilityCode?: string
112
+ facilityCodeListProvider?: 'BIC' | 'SMDG'
113
+ }
114
+ ): FacilityLocation {
115
+ // BIC provides more descriptive terminal names, so prefer BIC name when available
116
+ // Only keep DCSA name if BIC doesn't provide one
117
+ const enrichedName = bicData.name || location.name
118
+
119
+ return {
120
+ ...location,
121
+ name: enrichedName,
122
+ address: location.address || bicData.address || null,
123
+ coords: location.coords || bicData.coords || null,
124
+ operatorName: location.operatorName || bicData.operatorName || null,
125
+ facilityCode: location.facilityCode || bicData.facilityCode || null,
126
+ facilityCodeListProvider: location.facilityCodeListProvider || bicData.facilityCodeListProvider || null,
127
+ source: bicData.name || bicData.address || bicData.coords ? 'bic' : location.source,
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Creates an empty/unknown FacilityLocation with just a name/unlocode.
133
+ * Used when no event data is available but we need a location object.
134
+ */
135
+ export function createBasicLocation(
136
+ nameOrUnlocode: string,
137
+ unlocode?: string | null
138
+ ): FacilityLocation {
139
+ const actualUnlocode = unlocode || (nameOrUnlocode.length === 5 ? nameOrUnlocode : null)
140
+ const countryCode = actualUnlocode?.slice(0, 2) || null
141
+
142
+ return {
143
+ name: nameOrUnlocode,
144
+ unlocode: actualUnlocode,
145
+ countryCode,
146
+ facilityCode: null,
147
+ facilityCodeListProvider: null,
148
+ facilityTypeCode: null,
149
+ address: null,
150
+ coords: null,
151
+ operatorName: null,
152
+ source: 'manual',
153
+ }
154
+ }