@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,699 @@
1
+ /**
2
+ * POI Event Processor Tests
3
+ *
4
+ * Tests for processing AIS POI proximity events using real messages
5
+ * captured from the NATS stream.
6
+ */
7
+
8
+ import {
9
+ generateSourceEventId,
10
+ extractEventDateTime,
11
+ getPoiCode,
12
+ mapToOpenMercatoEventId,
13
+ createTrackingEventFromPoi,
14
+ resolvePoiLocationName,
15
+ } from '../poi-event-processor'
16
+ import {
17
+ PROXIMITY_EVENT_CODES,
18
+ PROXIMITY_EVENT_CATEGORY,
19
+ type PoiProximityEvent,
20
+ type ProximityEventType,
21
+ type ProcessedPoiEvent,
22
+ } from '../poi-types'
23
+ import { poiFixtures, createTestScope } from '../../__tests__/fixtures'
24
+ import { TrackingJob } from '../../data/entities'
25
+
26
+ describe('poi-event-processor', () => {
27
+ // ─── Event Code Mapping ────────────────────────────────────────────────────
28
+
29
+ describe('PROXIMITY_EVENT_CODES', () => {
30
+ it('should map all 7 event types to correct codes', () => {
31
+ expect(PROXIMITY_EVENT_CODES.PORT_ARRIVAL).toBe('PARR')
32
+ expect(PROXIMITY_EVENT_CODES.PORT_PROXIMITY_ARRIVAL).toBe('PPRA')
33
+ expect(PROXIMITY_EVENT_CODES.PORT_PROXIMITY_DEPARTURE).toBe('PPRD')
34
+ expect(PROXIMITY_EVENT_CODES.TERMINAL_ARRIVAL).toBe('TARR')
35
+ expect(PROXIMITY_EVENT_CODES.TERMINAL_PROXIMITY_ARRIVAL).toBe('TPRA')
36
+ expect(PROXIMITY_EVENT_CODES.TERMINAL_PROXIMITY_DEPARTURE).toBe('TPRD')
37
+ expect(PROXIMITY_EVENT_CODES.WAYPOINT_REACHED).toBe('WAYR')
38
+ })
39
+
40
+ it('should have unique codes for each event type', () => {
41
+ const codes = Object.values(PROXIMITY_EVENT_CODES)
42
+ const uniqueCodes = new Set(codes)
43
+ expect(uniqueCodes.size).toBe(codes.length)
44
+ })
45
+ })
46
+
47
+ describe('PROXIMITY_EVENT_CATEGORY', () => {
48
+ it('should categorize arrival events correctly', () => {
49
+ expect(PROXIMITY_EVENT_CATEGORY.PORT_ARRIVAL).toBe('arrival')
50
+ expect(PROXIMITY_EVENT_CATEGORY.TERMINAL_ARRIVAL).toBe('arrival')
51
+ })
52
+
53
+ it('should categorize proximity arrivals correctly', () => {
54
+ expect(PROXIMITY_EVENT_CATEGORY.PORT_PROXIMITY_ARRIVAL).toBe('proximity')
55
+ expect(PROXIMITY_EVENT_CATEGORY.TERMINAL_PROXIMITY_ARRIVAL).toBe('proximity')
56
+ })
57
+
58
+ it('should categorize departure events correctly', () => {
59
+ expect(PROXIMITY_EVENT_CATEGORY.PORT_PROXIMITY_DEPARTURE).toBe('departure')
60
+ expect(PROXIMITY_EVENT_CATEGORY.TERMINAL_PROXIMITY_DEPARTURE).toBe('departure')
61
+ })
62
+
63
+ it('should categorize waypoint events correctly', () => {
64
+ expect(PROXIMITY_EVENT_CATEGORY.WAYPOINT_REACHED).toBe('waypoint')
65
+ })
66
+ })
67
+
68
+ // ─── Source Event ID Generation ────────────────────────────────────────────
69
+
70
+ describe('generateSourceEventId', () => {
71
+ it('should generate unique IDs for different events', () => {
72
+ const event1 = poiFixtures.waypointReached[0]
73
+ const event2 = poiFixtures.waypointReached[1]
74
+
75
+ const id1 = generateSourceEventId(event1)
76
+ const id2 = generateSourceEventId(event2)
77
+
78
+ expect(id1).not.toBe(id2)
79
+ })
80
+
81
+ it('should include mmsi in the ID', () => {
82
+ const event = poiFixtures.waypointReached[0]
83
+ const id = generateSourceEventId(event)
84
+
85
+ expect(id).toContain(String(event.mmsi))
86
+ })
87
+
88
+ it('should include event type in the ID', () => {
89
+ const event = poiFixtures.portArrival[0]
90
+ const id = generateSourceEventId(event)
91
+
92
+ expect(id).toContain('PORT_ARRIVAL')
93
+ })
94
+
95
+ it('should include timestamp in the ID', () => {
96
+ const event = poiFixtures.terminalArrival[0]
97
+ const id = generateSourceEventId(event)
98
+
99
+ expect(id).toContain(event.ata!)
100
+ })
101
+
102
+ it('should use atd for departure events', () => {
103
+ const event = poiFixtures.terminalProximityDeparture[0]
104
+ const id = generateSourceEventId(event)
105
+
106
+ expect(id).toContain(event.atd!)
107
+ })
108
+
109
+ it('should be deterministic for the same event', () => {
110
+ const event = poiFixtures.portArrival[0]
111
+ const id1 = generateSourceEventId(event)
112
+ const id2 = generateSourceEventId(event)
113
+
114
+ expect(id1).toBe(id2)
115
+ })
116
+
117
+ it('should be deterministic for timeless events (no ata/atd)', () => {
118
+ // WAYPOINT/proximity events can arrive without ata/atd. The id must still be
119
+ // stable across redeliveries — anchored on the POI code, never the wall clock.
120
+ const event = { ...poiFixtures.waypointReached[0], ata: undefined, atd: undefined }
121
+
122
+ const id1 = generateSourceEventId(event)
123
+ const id2 = generateSourceEventId(event)
124
+
125
+ expect(id1).toBe(id2)
126
+ expect(id1).toContain(getPoiCode(event)!)
127
+ // No embedded ISO timestamp (would indicate a wall-clock fallback)
128
+ expect(id1).not.toMatch(/T\d{2}:\d{2}/)
129
+ })
130
+
131
+ it('should anchor on "unknown" when no ata/atd and no POI code', () => {
132
+ const event = {
133
+ ...poiFixtures.waypointReached[0],
134
+ ata: undefined,
135
+ atd: undefined,
136
+ arrivedPoiCode: undefined,
137
+ departedPoiCode: undefined,
138
+ }
139
+
140
+ const id = generateSourceEventId(event)
141
+
142
+ expect(id).toContain('unknown')
143
+ expect(generateSourceEventId(event)).toBe(id)
144
+ })
145
+ })
146
+
147
+ // ─── DateTime Extraction ───────────────────────────────────────────────────
148
+
149
+ describe('extractEventDateTime', () => {
150
+ it('should extract ata for arrival events', () => {
151
+ const event = poiFixtures.portArrival[0]
152
+ const dateTime = extractEventDateTime(event)
153
+
154
+ expect(dateTime.toISOString()).toBe(event.ata)
155
+ })
156
+
157
+ it('should extract atd for departure events', () => {
158
+ const event = poiFixtures.terminalProximityDeparture[0]
159
+ const dateTime = extractEventDateTime(event)
160
+
161
+ expect(dateTime.toISOString()).toBe(event.atd)
162
+ })
163
+
164
+ it('should extract ata for waypoint events', () => {
165
+ const event = poiFixtures.waypointReached[0]
166
+ const dateTime = extractEventDateTime(event)
167
+
168
+ expect(dateTime.toISOString()).toBe(event.ata)
169
+ })
170
+
171
+ it('should fallback to current time if no ata/atd', () => {
172
+ const event = { ...poiFixtures.waypointReached[0], ata: undefined, atd: undefined }
173
+ const before = new Date()
174
+ const dateTime = extractEventDateTime(event)
175
+ const after = new Date()
176
+
177
+ expect(dateTime.getTime()).toBeGreaterThanOrEqual(before.getTime())
178
+ expect(dateTime.getTime()).toBeLessThanOrEqual(after.getTime())
179
+ })
180
+ })
181
+
182
+ // ─── POI Code Extraction ───────────────────────────────────────────────────
183
+
184
+ describe('getPoiCode', () => {
185
+ it('should return arrivedPoiCode for arrival events', () => {
186
+ const event = poiFixtures.portArrival[0]
187
+ const code = getPoiCode(event)
188
+
189
+ expect(code).toBe(event.arrivedPoiCode)
190
+ })
191
+
192
+ it('should return departedPoiCode for departure events', () => {
193
+ const event = poiFixtures.terminalProximityDeparture[0]
194
+ const code = getPoiCode(event)
195
+
196
+ expect(code).toBe(event.departedPoiCode)
197
+ })
198
+
199
+ it('should return arrivedPoiCode for waypoint events', () => {
200
+ const event = poiFixtures.waypointReached[0]
201
+ const code = getPoiCode(event)
202
+
203
+ expect(code).toBe(event.arrivedPoiCode)
204
+ })
205
+
206
+ it('should return null if no POI code present', () => {
207
+ const event = { ...poiFixtures.waypointReached[0], arrivedPoiCode: undefined, departedPoiCode: undefined }
208
+ const code = getPoiCode(event)
209
+
210
+ expect(code).toBeNull()
211
+ })
212
+ })
213
+
214
+ // ─── Open Mercato Event ID Mapping ─────────────────────────────────────────
215
+
216
+ describe('mapToOpenMercatoEventId', () => {
217
+ it('should map all event types to shipment_tracking.poi.* namespace', () => {
218
+ const eventTypes: ProximityEventType[] = [
219
+ 'PORT_ARRIVAL',
220
+ 'PORT_PROXIMITY_ARRIVAL',
221
+ 'PORT_PROXIMITY_DEPARTURE',
222
+ 'TERMINAL_ARRIVAL',
223
+ 'TERMINAL_PROXIMITY_ARRIVAL',
224
+ 'TERMINAL_PROXIMITY_DEPARTURE',
225
+ 'WAYPOINT_REACHED',
226
+ ]
227
+
228
+ for (const type of eventTypes) {
229
+ const eventId = mapToOpenMercatoEventId(type)
230
+ expect(eventId).toMatch(/^shipment_tracking\.poi\./)
231
+ }
232
+ })
233
+
234
+ it('should map PORT_ARRIVAL correctly', () => {
235
+ expect(mapToOpenMercatoEventId('PORT_ARRIVAL')).toBe('shipment_tracking.poi.port_arrival')
236
+ })
237
+
238
+ it('should map TERMINAL_ARRIVAL correctly', () => {
239
+ expect(mapToOpenMercatoEventId('TERMINAL_ARRIVAL')).toBe('shipment_tracking.poi.terminal_arrival')
240
+ })
241
+
242
+ it('should map WAYPOINT_REACHED correctly', () => {
243
+ expect(mapToOpenMercatoEventId('WAYPOINT_REACHED')).toBe('shipment_tracking.poi.waypoint_reached')
244
+ })
245
+
246
+ it('should map proximity arrival events correctly', () => {
247
+ expect(mapToOpenMercatoEventId('PORT_PROXIMITY_ARRIVAL')).toBe('shipment_tracking.poi.port_proximity_arrival')
248
+ expect(mapToOpenMercatoEventId('TERMINAL_PROXIMITY_ARRIVAL')).toBe('shipment_tracking.poi.terminal_proximity_arrival')
249
+ })
250
+
251
+ it('should map departure events correctly', () => {
252
+ expect(mapToOpenMercatoEventId('PORT_PROXIMITY_DEPARTURE')).toBe('shipment_tracking.poi.port_departure')
253
+ expect(mapToOpenMercatoEventId('TERMINAL_PROXIMITY_DEPARTURE')).toBe('shipment_tracking.poi.terminal_departure')
254
+ })
255
+ })
256
+
257
+ // ─── TrackingEvent Creation ────────────────────────────────────────────────
258
+
259
+ describe('createTrackingEventFromPoi', () => {
260
+ const scope = createTestScope()
261
+
262
+ function createMockTrackingJob(): TrackingJob {
263
+ const job = new TrackingJob()
264
+ job.id = '00000000-0000-0000-0000-000000000003'
265
+ job.organizationId = scope.organizationId
266
+ job.tenantId = scope.tenantId
267
+ return job
268
+ }
269
+
270
+ function createProcessedEvent(poiEvent: PoiProximityEvent): ProcessedPoiEvent {
271
+ return {
272
+ poiEvent,
273
+ vesselImo: String(poiEvent.shipId),
274
+ shipmentIds: ['shipment-1'],
275
+ eventDateTime: extractEventDateTime(poiEvent),
276
+ poiCode: getPoiCode(poiEvent),
277
+ eventCode: PROXIMITY_EVENT_CODES[poiEvent.type],
278
+ sourceEventId: generateSourceEventId(poiEvent),
279
+ }
280
+ }
281
+
282
+ it('should create TrackingEvent with correct source', () => {
283
+ const poiEvent = poiFixtures.portArrival[0]
284
+ const processed = createProcessedEvent(poiEvent)
285
+ const trackingJob = createMockTrackingJob()
286
+
287
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
288
+
289
+ expect(trackingEvent.source).toBe('ais')
290
+ })
291
+
292
+ it('should set eventType to TRANSPORT', () => {
293
+ const poiEvent = poiFixtures.terminalArrival[0]
294
+ const processed = createProcessedEvent(poiEvent)
295
+ const trackingJob = createMockTrackingJob()
296
+
297
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
298
+
299
+ expect(trackingEvent.eventType).toBe('TRANSPORT')
300
+ })
301
+
302
+ it('should set eventClassifierCode to ACT (actual)', () => {
303
+ const poiEvent = poiFixtures.waypointReached[0]
304
+ const processed = createProcessedEvent(poiEvent)
305
+ const trackingJob = createMockTrackingJob()
306
+
307
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
308
+
309
+ expect(trackingEvent.eventClassifierCode).toBe('ACT')
310
+ })
311
+
312
+ it('should set correct event code', () => {
313
+ const poiEvent = poiFixtures.portArrival[0]
314
+ const processed = createProcessedEvent(poiEvent)
315
+ const trackingJob = createMockTrackingJob()
316
+
317
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
318
+
319
+ expect(trackingEvent.eventCode).toBe('PARR')
320
+ })
321
+
322
+ it('should set coordinates from POI event', () => {
323
+ const poiEvent = poiFixtures.terminalProximityArrival[0]
324
+ const processed = createProcessedEvent(poiEvent)
325
+ const trackingJob = createMockTrackingJob()
326
+
327
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
328
+
329
+ expect(trackingEvent.latitude).toBe(poiEvent.lat)
330
+ expect(trackingEvent.longitude).toBe(poiEvent.lng)
331
+ })
332
+
333
+ it('should set vessel name from POI event', () => {
334
+ const poiEvent = poiFixtures.waypointReached[0]
335
+ const processed = createProcessedEvent(poiEvent)
336
+ const trackingJob = createMockTrackingJob()
337
+
338
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
339
+
340
+ expect(trackingEvent.vesselName).toBe('EXAMPLE VESSEL 14')
341
+ })
342
+
343
+ it('should set locationUnlocode to POI code', () => {
344
+ const poiEvent = poiFixtures.portArrival[1]
345
+ const processed = createProcessedEvent(poiEvent)
346
+ const trackingJob = createMockTrackingJob()
347
+
348
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
349
+
350
+ expect(trackingEvent.locationUnlocode).toBe('N044E008-03880')
351
+ })
352
+
353
+ it('should store raw data for debugging', () => {
354
+ const poiEvent = poiFixtures.terminalProximityDeparture[0]
355
+ const processed = createProcessedEvent(poiEvent)
356
+ const trackingJob = createMockTrackingJob()
357
+
358
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
359
+
360
+ expect(trackingEvent.rawData).toBeDefined()
361
+ expect(trackingEvent.rawData?.poiEventType).toBe('TERMINAL_PROXIMITY_DEPARTURE')
362
+ expect(trackingEvent.rawData?.mmsi).toBe(poiEvent.mmsi)
363
+ expect(trackingEvent.rawData?.distanceToPoiMeters).toBe(poiEvent.distanceToPoiMeters)
364
+ })
365
+
366
+ it('should inherit organization and tenant from tracking job', () => {
367
+ const poiEvent = poiFixtures.portArrival[0]
368
+ const processed = createProcessedEvent(poiEvent)
369
+ const trackingJob = createMockTrackingJob()
370
+
371
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
372
+
373
+ expect(trackingEvent.organizationId).toBe(scope.organizationId)
374
+ expect(trackingEvent.tenantId).toBe(scope.tenantId)
375
+ })
376
+
377
+ it('should set sourceEventId for deduplication', () => {
378
+ const poiEvent = poiFixtures.waypointReached[1]
379
+ const processed = createProcessedEvent(poiEvent)
380
+ const trackingJob = createMockTrackingJob()
381
+
382
+ const trackingEvent = createTrackingEventFromPoi(processed, trackingJob)
383
+
384
+ expect(trackingEvent.sourceEventId).toBe(processed.sourceEventId)
385
+ expect(trackingEvent.sourceEventId).toContain('poi-')
386
+ })
387
+
388
+ it('should resolve locationName from POI identity for port/terminal events', () => {
389
+ const base = poiFixtures.terminalArrival[0]
390
+ const poiEvent: PoiProximityEvent = {
391
+ ...base,
392
+ type: 'TERMINAL_ARRIVAL',
393
+ terminalName: 'Qingdao New Qianwan Container Terminal (QQCTN)',
394
+ portName: 'Port of Qingdao',
395
+ city: 'Qingdao',
396
+ }
397
+ const trackingEvent = createTrackingEventFromPoi(createProcessedEvent(poiEvent), createMockTrackingJob())
398
+ expect(trackingEvent.locationName).toBe('Qingdao New Qianwan Container Terminal (QQCTN)')
399
+ })
400
+
401
+ it('should leave locationName null for waypoints (region name used instead)', () => {
402
+ const poiEvent: PoiProximityEvent = {
403
+ ...poiFixtures.waypointReached[0],
404
+ regionNamePl: 'Morze Północne',
405
+ regionNameEn: 'North Sea',
406
+ }
407
+ const trackingEvent = createTrackingEventFromPoi(createProcessedEvent(poiEvent), createMockTrackingJob())
408
+ expect(trackingEvent.locationName).toBeNull()
409
+ expect(trackingEvent.regionNamePl).toBe('Morze Północne')
410
+ expect(trackingEvent.regionNameEn).toBe('North Sea')
411
+ })
412
+ })
413
+
414
+ describe('resolvePoiLocationName', () => {
415
+ const base = poiFixtures.portArrival[0]
416
+
417
+ it('terminal: prefers terminalName, then portName, then city', () => {
418
+ expect(resolvePoiLocationName({ ...base, type: 'TERMINAL_ARRIVAL', terminalName: 'T', portName: 'P', city: 'C' })).toBe('T')
419
+ expect(resolvePoiLocationName({ ...base, type: 'TERMINAL_ARRIVAL', terminalName: null, portName: 'P', city: 'C' })).toBe('P')
420
+ expect(resolvePoiLocationName({ ...base, type: 'TERMINAL_PROXIMITY_ARRIVAL', terminalName: null, portName: null, city: 'C' })).toBe('C')
421
+ })
422
+
423
+ it('port: prefers city, then portName', () => {
424
+ expect(resolvePoiLocationName({ ...base, type: 'PORT_ARRIVAL', city: 'Gdańsk', portName: 'Port of Gdańsk' })).toBe('Gdańsk')
425
+ expect(resolvePoiLocationName({ ...base, type: 'PORT_PROXIMITY_ARRIVAL', city: null, portName: 'Port of Gdańsk' })).toBe('Port of Gdańsk')
426
+ })
427
+
428
+ it('returns null for waypoints and when no identity is present', () => {
429
+ expect(resolvePoiLocationName({ ...base, type: 'WAYPOINT_REACHED' })).toBeNull()
430
+ expect(resolvePoiLocationName({ ...base, type: 'PORT_ARRIVAL', city: null, portName: null })).toBeNull()
431
+ })
432
+ })
433
+
434
+ // ─── Real NATS Message Tests ───────────────────────────────────────────────
435
+
436
+ describe('with real NATS messages', () => {
437
+ describe('WAYPOINT_REACHED events', () => {
438
+ it('should parse EXAMPLE VESSEL 14 waypoint event', () => {
439
+ const event = poiFixtures.waypointReached[0]
440
+
441
+ expect(event.type).toBe('WAYPOINT_REACHED')
442
+ expect(event.mmsi).toBe(111000001)
443
+ expect(event.shipId).toBe(8100001)
444
+ expect(event.shipName).toBe('EXAMPLE VESSEL 14')
445
+ expect(event.arrivedPoiCode).toBe('N051E002-00772')
446
+ expect(event.distanceToPoiMeters).toBeCloseTo(4926.73, 0)
447
+ expect(event.lat).toBeCloseTo(51.346, 2)
448
+ expect(event.lng).toBeCloseTo(2.118, 2)
449
+ })
450
+
451
+ it('should parse EXAMPLE VESSEL 15 waypoint event', () => {
452
+ const event = poiFixtures.waypointReached[1]
453
+
454
+ expect(event.type).toBe('WAYPOINT_REACHED')
455
+ expect(event.mmsi).toBe(111000002)
456
+ expect(event.shipName).toBe('EXAMPLE VESSEL 15')
457
+ expect(event.arrivedPoiCode).toBe('N001E103-00217')
458
+ })
459
+
460
+ it('should have valid timestamps for all waypoint events', () => {
461
+ for (const event of poiFixtures.waypointReached) {
462
+ expect(event.ata).toBeDefined()
463
+ const date = new Date(event.ata!)
464
+ expect(date.getTime()).not.toBeNaN()
465
+ }
466
+ })
467
+ })
468
+
469
+ describe('PORT_ARRIVAL events', () => {
470
+ it('should parse EXAMPLE VESSEL 17 port arrival', () => {
471
+ const event = poiFixtures.portArrival[0]
472
+
473
+ expect(event.type).toBe('PORT_ARRIVAL')
474
+ expect(event.mmsi).toBe(111000004)
475
+ expect(event.shipName).toBe('EXAMPLE VESSEL 17')
476
+ expect(event.arrivedPoiCode).toBe('N035E139-03434')
477
+ expect(event.sequenceOrder).toBe(2)
478
+ })
479
+
480
+ it('should parse EXAMPLE VESSEL 18 port arrival with very close distance', () => {
481
+ const event = poiFixtures.portArrival[1]
482
+
483
+ expect(event.type).toBe('PORT_ARRIVAL')
484
+ expect(event.mmsi).toBe(111000005)
485
+ expect(event.shipName).toBe('EXAMPLE VESSEL 18')
486
+ expect(event.distanceToPoiMeters).toBeCloseTo(27.25, 1) // Very close - actual arrival
487
+ expect(event.arrivedPoiCode).toBe('N044E008-03880')
488
+ })
489
+ })
490
+
491
+ describe('TERMINAL_ARRIVAL events', () => {
492
+ it('should parse EXAMPLE VESSEL 17 terminal arrival (same vessel as port arrival)', () => {
493
+ const event = poiFixtures.terminalArrival[0]
494
+
495
+ expect(event.type).toBe('TERMINAL_ARRIVAL')
496
+ expect(event.mmsi).toBe(111000004)
497
+ expect(event.shipName).toBe('EXAMPLE VESSEL 17')
498
+ expect(event.sequenceOrder).toBe(3) // Comes after PORT_ARRIVAL
499
+ })
500
+
501
+ it('should parse EXAMPLE VESSEL 19 terminal arrival in Sydney', () => {
502
+ const event = poiFixtures.terminalArrival[2]
503
+
504
+ expect(event.type).toBe('TERMINAL_ARRIVAL')
505
+ expect(event.shipName).toBe('EXAMPLE VESSEL 19')
506
+ expect(event.lat).toBeLessThan(0) // Southern hemisphere
507
+ expect(event.arrivedPoiCode).toBe('S034E151-00941')
508
+ })
509
+ })
510
+
511
+ describe('proximity arrival events', () => {
512
+ it('should parse EXAMPLE VESSEL 20 port proximity arrival', () => {
513
+ const event = poiFixtures.portProximityArrival[0]
514
+
515
+ expect(event.type).toBe('PORT_PROXIMITY_ARRIVAL')
516
+ expect(event.mmsi).toBe(111000007)
517
+ expect(event.shipName).toBe('EXAMPLE VESSEL 20')
518
+ expect(event.distanceToPoiMeters).toBeCloseTo(136.13, 1)
519
+ })
520
+
521
+ it('should parse EXAMPLE VESSEL 21 terminal proximity arrival', () => {
522
+ const event = poiFixtures.terminalProximityArrival[0]
523
+
524
+ expect(event.type).toBe('TERMINAL_PROXIMITY_ARRIVAL')
525
+ expect(event.mmsi).toBe(111000008)
526
+ expect(event.shipName).toBe('EXAMPLE VESSEL 21')
527
+ expect(event.distanceToPoiMeters).toBeCloseTo(964.82, 1)
528
+ })
529
+
530
+ it('should have ata (arrival time) for all proximity arrivals', () => {
531
+ const allProximityArrivals = [
532
+ ...poiFixtures.portProximityArrival,
533
+ ...poiFixtures.terminalProximityArrival,
534
+ ]
535
+
536
+ for (const event of allProximityArrivals) {
537
+ expect(event.ata).toBeDefined()
538
+ expect(event.atd).toBeUndefined()
539
+ }
540
+ })
541
+ })
542
+
543
+ describe('proximity departure events', () => {
544
+ it('should parse EXAMPLE VESSEL 23 port proximity departure', () => {
545
+ const event = poiFixtures.portProximityDeparture[0]
546
+
547
+ expect(event.type).toBe('PORT_PROXIMITY_DEPARTURE')
548
+ expect(event.mmsi).toBe(111000010)
549
+ expect(event.shipName).toBe('EXAMPLE VESSEL 23')
550
+ expect(event.departedPoiCode).toBe('N037W001-03965')
551
+ })
552
+
553
+ it('should parse EXAMPLE VESSEL 24 terminal proximity departure', () => {
554
+ const event = poiFixtures.terminalProximityDeparture[2]
555
+
556
+ expect(event.type).toBe('TERMINAL_PROXIMITY_DEPARTURE')
557
+ expect(event.shipName).toBe('EXAMPLE VESSEL 24')
558
+ expect(event.departedPoiCode).toBe('N051W009-03379')
559
+ })
560
+
561
+ it('should have atd (departure time) for all departures', () => {
562
+ const allDepartures = [
563
+ ...poiFixtures.portProximityDeparture,
564
+ ...poiFixtures.terminalProximityDeparture,
565
+ ]
566
+
567
+ for (const event of allDepartures) {
568
+ expect(event.atd).toBeDefined()
569
+ expect(event.ata).toBeUndefined()
570
+ }
571
+ })
572
+ })
573
+
574
+ describe('all valid events', () => {
575
+ it('should have all required fields', () => {
576
+ for (const event of poiFixtures.allValidEvents) {
577
+ expect(event.type).toBeDefined()
578
+ expect(event.mmsi).toBeDefined()
579
+ expect(typeof event.mmsi).toBe('number')
580
+ expect(event.shipId).toBeDefined()
581
+ expect(event.shipName).toBeDefined()
582
+ expect(event.lat).toBeDefined()
583
+ expect(event.lng).toBeDefined()
584
+ expect(event.sequenceOrder).toBeDefined()
585
+ }
586
+ })
587
+
588
+ it('should have valid coordinates', () => {
589
+ for (const event of poiFixtures.allValidEvents) {
590
+ expect(event.lat).toBeGreaterThanOrEqual(-90)
591
+ expect(event.lat).toBeLessThanOrEqual(90)
592
+ expect(event.lng).toBeGreaterThanOrEqual(-180)
593
+ expect(event.lng).toBeLessThanOrEqual(180)
594
+ }
595
+ })
596
+
597
+ it('should have valid MMSI (9 digits)', () => {
598
+ for (const event of poiFixtures.allValidEvents) {
599
+ const mmsiStr = String(event.mmsi)
600
+ expect(mmsiStr.length).toBe(9)
601
+ }
602
+ })
603
+
604
+ it('should map all events to valid event codes', () => {
605
+ for (const event of poiFixtures.allValidEvents) {
606
+ const code = PROXIMITY_EVENT_CODES[event.type]
607
+ expect(code).toBeDefined()
608
+ expect(code.length).toBe(4) // All codes are 4 characters
609
+ }
610
+ })
611
+ })
612
+ })
613
+
614
+ // ─── Invalid Message Handling ──────────────────────────────────────────────
615
+
616
+ describe('invalid message handling', () => {
617
+ it('should identify messages without type', () => {
618
+ for (const msg of poiFixtures.invalidMessages) {
619
+ const typedMsg = msg as Partial<PoiProximityEvent>
620
+ // Most invalid messages don't have type
621
+ if (!typedMsg.type) {
622
+ expect(typedMsg.type).toBeUndefined()
623
+ }
624
+ }
625
+ })
626
+
627
+ it('should identify messages without mmsi', () => {
628
+ const msgsWithoutMmsi = poiFixtures.invalidMessages.filter(
629
+ (msg) => !(msg as Partial<PoiProximityEvent>).mmsi
630
+ )
631
+ expect(msgsWithoutMmsi.length).toBeGreaterThan(0)
632
+ })
633
+
634
+ it('should identify empty test messages', () => {
635
+ const emptyMsg = poiFixtures.invalidMessages.find(
636
+ (msg) => Object.keys(msg as object).length === 0
637
+ )
638
+ expect(emptyMsg).toBeDefined()
639
+ })
640
+
641
+ it('should identify messages with test payload', () => {
642
+ const testMsgs = poiFixtures.invalidMessages.filter(
643
+ (msg) => (msg as { test?: string }).test
644
+ )
645
+ expect(testMsgs.length).toBeGreaterThan(0)
646
+ })
647
+
648
+ it('should validate that invalid messages are missing required fields', () => {
649
+ for (const msg of poiFixtures.invalidMessages) {
650
+ const typedMsg = msg as Partial<PoiProximityEvent>
651
+ const hasRequiredFields = typedMsg.type && typedMsg.mmsi && typedMsg.shipName
652
+ expect(hasRequiredFields).toBeFalsy()
653
+ }
654
+ })
655
+ })
656
+
657
+ // ─── POI Code Format Tests ─────────────────────────────────────────────────
658
+
659
+ describe('POI code format', () => {
660
+ it('should follow grid-based format (e.g., N051E002-00772)', () => {
661
+ const poiCodePattern = /^[NS]\d{3}[EW]\d{3}-\d{5}$/
662
+
663
+ for (const event of poiFixtures.allValidEvents) {
664
+ const code = getPoiCode(event)
665
+ if (code) {
666
+ expect(code).toMatch(poiCodePattern)
667
+ }
668
+ }
669
+ })
670
+
671
+ it('should encode latitude in the code', () => {
672
+ const event = poiFixtures.waypointReached[0] // lat: 51.346...
673
+ const code = getPoiCode(event)
674
+
675
+ expect(code?.startsWith('N051')).toBe(true) // North 51 degrees
676
+ })
677
+
678
+ it('should encode longitude in the code', () => {
679
+ const event = poiFixtures.waypointReached[0] // lng: 2.117...
680
+ const code = getPoiCode(event)
681
+
682
+ expect(code).toContain('E002') // East 2 degrees
683
+ })
684
+
685
+ it('should use S for southern latitudes', () => {
686
+ const event = poiFixtures.terminalArrival[2] // EXAMPLE VESSEL 19 in Sydney
687
+ const code = getPoiCode(event)
688
+
689
+ expect(code?.startsWith('S034')).toBe(true)
690
+ })
691
+
692
+ it('should use W for western longitudes', () => {
693
+ const event = poiFixtures.terminalProximityArrival[0] // EXAMPLE VESSEL 21 at -118...
694
+ const code = getPoiCode(event)
695
+
696
+ expect(code).toContain('W119')
697
+ })
698
+ })
699
+ })