@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.
- package/LICENSE +21 -0
- package/NOTICE +25 -0
- package/dist/generated/entities/bic_config/index.js +21 -0
- package/dist/generated/entities/bic_config/index.js.map +7 -0
- package/dist/generated/entities/carrier_config/index.js +27 -0
- package/dist/generated/entities/carrier_config/index.js.map +7 -0
- package/dist/generated/entities/location_override/index.js +33 -0
- package/dist/generated/entities/location_override/index.js.map +7 -0
- package/dist/generated/entities/shipment/index.js +73 -0
- package/dist/generated/entities/shipment/index.js.map +7 -0
- package/dist/generated/entities/ships_go_config/index.js +31 -0
- package/dist/generated/entities/ships_go_config/index.js.map +7 -0
- package/dist/generated/entities/tracking_event/index.js +101 -0
- package/dist/generated/entities/tracking_event/index.js.map +7 -0
- package/dist/generated/entities/tracking_job/index.js +47 -0
- package/dist/generated/entities/tracking_job/index.js.map +7 -0
- package/dist/generated/entities/webhook/index.js +25 -0
- package/dist/generated/entities/webhook/index.js.map +7 -0
- package/dist/generated/entities/webhook_delivery/index.js +25 -0
- package/dist/generated/entities/webhook_delivery/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +21 -0
- package/dist/generated/entities.ids.generated.js.map +7 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +7 -0
- package/dist/modules/shipment_tracking/acl.js +22 -0
- package/dist/modules/shipment_tracking/acl.js.map +7 -0
- package/dist/modules/shipment_tracking/api/bic-configs/route.js +176 -0
- package/dist/modules/shipment_tracking/api/bic-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/bic-configs/test/route.js +95 -0
- package/dist/modules/shipment_tracking/api/bic-configs/test/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/cargo-events/route.js +93 -0
- package/dist/modules/shipment_tracking/api/cargo-events/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/carrier-configs/route.js +139 -0
- package/dist/modules/shipment_tracking/api/carrier-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js +177 -0
- package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/location-overrides/route.js +179 -0
- package/dist/modules/shipment_tracking/api/location-overrides/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/openapi.js +27 -0
- package/dist/modules/shipment_tracking/api/openapi.js.map +7 -0
- package/dist/modules/shipment_tracking/api/shipments/route.js +192 -0
- package/dist/modules/shipment_tracking/api/shipments/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js +185 -0
- package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/route.js +144 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js +107 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/utils.js +12 -0
- package/dist/modules/shipment_tracking/api/utils.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js +76 -0
- package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/route.js +135 -0
- package/dist/modules/shipment_tracking/api/webhooks/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/test/route.js +71 -0
- package/dist/modules/shipment_tracking/api/webhooks/test/route.js.map +7 -0
- package/dist/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/msc.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/one.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/zim.png +0 -0
- package/dist/modules/shipment_tracking/assets/index.js +52 -0
- package/dist/modules/shipment_tracking/assets/index.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.js +621 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.js +198 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js +279 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js +10 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.js +198 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/ce.js +52 -0
- package/dist/modules/shipment_tracking/ce.js.map +7 -0
- package/dist/modules/shipment_tracking/cli.js +229 -0
- package/dist/modules/shipment_tracking/cli.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/bic-configs.js +66 -0
- package/dist/modules/shipment_tracking/commands/bic-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/carrier-configs.js +65 -0
- package/dist/modules/shipment_tracking/commands/carrier-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/index.js +9 -0
- package/dist/modules/shipment_tracking/commands/index.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/location-overrides.js +93 -0
- package/dist/modules/shipment_tracking/commands/location-overrides.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/shipments.js +200 -0
- package/dist/modules/shipment_tracking/commands/shipments.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/shipsgo-configs.js +75 -0
- package/dist/modules/shipment_tracking/commands/shipsgo-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/tracking-jobs.js +120 -0
- package/dist/modules/shipment_tracking/commands/tracking-jobs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/tracking.js +140 -0
- package/dist/modules/shipment_tracking/commands/tracking.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/webhooks.js +115 -0
- package/dist/modules/shipment_tracking/commands/webhooks.js.map +7 -0
- package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js +168 -0
- package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js.map +7 -0
- package/dist/modules/shipment_tracking/components/FacilityLocationInput.js +202 -0
- package/dist/modules/shipment_tracking/components/FacilityLocationInput.js.map +7 -0
- package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js +501 -0
- package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js +818 -0
- package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipmentDrawer.js +404 -0
- package/dist/modules/shipment_tracking/components/ShipmentDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js +200 -0
- package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js.map +7 -0
- package/dist/modules/shipment_tracking/components/TimestampCell.js +108 -0
- package/dist/modules/shipment_tracking/components/TimestampCell.js.map +7 -0
- package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js +343 -0
- package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/VesselTrackingMap.js +496 -0
- package/dist/modules/shipment_tracking/components/VesselTrackingMap.js.map +7 -0
- package/dist/modules/shipment_tracking/components/WebhookDrawer.js +332 -0
- package/dist/modules/shipment_tracking/components/WebhookDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/data/entities.js +686 -0
- package/dist/modules/shipment_tracking/data/entities.js.map +7 -0
- package/dist/modules/shipment_tracking/data/validators.js +434 -0
- package/dist/modules/shipment_tracking/data/validators.js.map +7 -0
- package/dist/modules/shipment_tracking/di.js +60 -0
- package/dist/modules/shipment_tracking/di.js.map +7 -0
- package/dist/modules/shipment_tracking/encryption.js +12 -0
- package/dist/modules/shipment_tracking/encryption.js.map +7 -0
- package/dist/modules/shipment_tracking/events.js +87 -0
- package/dist/modules/shipment_tracking/events.js.map +7 -0
- package/dist/modules/shipment_tracking/hooks/useVesselTracking.js +137 -0
- package/dist/modules/shipment_tracking/hooks/useVesselTracking.js.map +7 -0
- package/dist/modules/shipment_tracking/i18n/de.json +327 -0
- package/dist/modules/shipment_tracking/i18n/en.json +327 -0
- package/dist/modules/shipment_tracking/i18n/es.json +327 -0
- package/dist/modules/shipment_tracking/i18n/pl.json +327 -0
- package/dist/modules/shipment_tracking/index.js +15 -0
- package/dist/modules/shipment_tracking/index.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js +66 -0
- package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js +1 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco.js +236 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/evergreen.js +87 -0
- package/dist/modules/shipment_tracking/lib/adapters/evergreen.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js +68 -0
- package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/index.js +20 -0
- package/dist/modules/shipment_tracking/lib/adapters/index.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/maersk.js +84 -0
- package/dist/modules/shipment_tracking/lib/adapters/maersk.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/msc.js +170 -0
- package/dist/modules/shipment_tracking/lib/adapters/msc.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/zim.js +85 -0
- package/dist/modules/shipment_tracking/lib/adapters/zim.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/audit-helpers.js +20 -0
- package/dist/modules/shipment_tracking/lib/audit-helpers.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/auth/base64url.js +8 -0
- package/dist/modules/shipment_tracking/lib/auth/base64url.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/auth/oauth-client.js +38 -0
- package/dist/modules/shipment_tracking/lib/auth/oauth-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/background.js +15 -0
- package/dist/modules/shipment_tracking/lib/background.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/bic-api-client.js +106 -0
- package/dist/modules/shipment_tracking/lib/bic-api-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/carrier-adapter.js +17 -0
- package/dist/modules/shipment_tracking/lib/carrier-adapter.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/current-vessel.js +149 -0
- package/dist/modules/shipment_tracking/lib/current-vessel.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js +124 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js +112 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-params.js +16 -0
- package/dist/modules/shipment_tracking/lib/dcsa-params.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/empty-return.js +48 -0
- package/dist/modules/shipment_tracking/lib/empty-return.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/location-overrides.js +85 -0
- package/dist/modules/shipment_tracking/lib/location-overrides.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/location-types.js +59 -0
- package/dist/modules/shipment_tracking/lib/location-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/logger.js +113 -0
- package/dist/modules/shipment_tracking/lib/logger.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-event-processor.js +183 -0
- package/dist/modules/shipment_tracking/lib/poi-event-processor.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-nats-config.js +52 -0
- package/dist/modules/shipment_tracking/lib/poi-nats-config.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-types.js +43 -0
- package/dist/modules/shipment_tracking/lib/poi-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/rate-limiter.js +31 -0
- package/dist/modules/shipment_tracking/lib/rate-limiter.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/route-extraction.js +187 -0
- package/dist/modules/shipment_tracking/lib/route-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/route-inference.js +106 -0
- package/dist/modules/shipment_tracking/lib/route-inference.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/schedule-generator.js +63 -0
- package/dist/modules/shipment_tracking/lib/schedule-generator.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-client.js +143 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js +204 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/status-machine.js +131 -0
- package/dist/modules/shipment_tracking/lib/status-machine.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/time-extraction.js +41 -0
- package/dist/modules/shipment_tracking/lib/time-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/timestamp-utils.js +100 -0
- package/dist/modules/shipment_tracking/lib/timestamp-utils.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-api.js +111 -0
- package/dist/modules/shipment_tracking/lib/vessel-api.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-cache.js +50 -0
- package/dist/modules/shipment_tracking/lib/vessel-cache.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-extraction.js +13 -0
- package/dist/modules/shipment_tracking/lib/vessel-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js +62 -0
- package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js +48 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js +15 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js +47 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js.map +7 -0
- package/dist/modules/shipment_tracking/notifications.js +145 -0
- package/dist/modules/shipment_tracking/notifications.js.map +7 -0
- package/dist/modules/shipment_tracking/services/carrierRegistry.js +24 -0
- package/dist/modules/shipment_tracking/services/carrierRegistry.js.map +7 -0
- package/dist/modules/shipment_tracking/services/poiNatsService.js +397 -0
- package/dist/modules/shipment_tracking/services/poiNatsService.js.map +7 -0
- package/dist/modules/shipment_tracking/services/shipsGoProvider.js +163 -0
- package/dist/modules/shipment_tracking/services/shipsGoProvider.js.map +7 -0
- package/dist/modules/shipment_tracking/services/trackingService.js +1283 -0
- package/dist/modules/shipment_tracking/services/trackingService.js.map +7 -0
- package/dist/modules/shipment_tracking/services/webhookService.js +263 -0
- package/dist/modules/shipment_tracking/services/webhookService.js.map +7 -0
- package/dist/modules/shipment_tracking/setup.js +72 -0
- package/dist/modules/shipment_tracking/setup.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js +60 -0
- package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js +58 -0
- package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js +82 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js +53 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js +28 -0
- package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js +67 -0
- package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js +30 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js +19 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/index.js +6 -0
- package/dist/modules/shipment_tracking/tables/index.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js +284 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.js +36 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js +25 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js +355 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js +26 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js.map +7 -0
- package/dist/types/assets.d.js +1 -0
- package/dist/types/assets.d.js.map +7 -0
- package/generated/entities/bic_config/index.ts +20 -0
- package/generated/entities/carrier_config/index.ts +23 -0
- package/generated/entities/location_override/index.ts +26 -0
- package/generated/entities/shipment/index.ts +46 -0
- package/generated/entities/ships_go_config/index.ts +25 -0
- package/generated/entities/tracking_event/index.ts +60 -0
- package/generated/entities/tracking_job/index.ts +33 -0
- package/generated/entities/webhook/index.ts +22 -0
- package/generated/entities/webhook_delivery/index.ts +22 -0
- package/generated/entities.ids.generated.ts +47 -0
- package/package.json +81 -0
- package/src/index.ts +39 -0
- package/src/modules/shipment_tracking/__integration__/TC-TRACK-410-shipsgo-config-api.spec.ts +133 -0
- package/src/modules/shipment_tracking/__integration__/meta.ts +4 -0
- package/src/modules/shipment_tracking/__tests__/empty-return-stop.test.ts +231 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/hapag-lloyd-transship-container.json +702 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/index.ts +434 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/maersk-multi-transship-completed.json +1518 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/maersk-transship-intransit.json +558 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-direct.json +222 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi-transship-completed.json +974 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi.json +4846 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-transship.json +409 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/poi-events.json +240 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic/index.ts +138 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-eta-updates.json +288 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-route-inference.json +201 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-voyage-progression.json +410 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-air-mapper.test.ts +157 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-client.test.ts +155 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-mapper.test.ts +201 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-poll.test.ts +357 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-provider.test.ts +364 -0
- package/src/modules/shipment_tracking/__tests__/trackingService.integration.test.ts +2248 -0
- package/src/modules/shipment_tracking/__tests__/webhookPayload.test.ts +151 -0
- package/src/modules/shipment_tracking/acl.ts +18 -0
- package/src/modules/shipment_tracking/api/bic-configs/route.ts +206 -0
- package/src/modules/shipment_tracking/api/bic-configs/test/route.ts +108 -0
- package/src/modules/shipment_tracking/api/cargo-events/route.ts +101 -0
- package/src/modules/shipment_tracking/api/carrier-configs/route.ts +142 -0
- package/src/modules/shipment_tracking/api/dashboard/ships-map/route.ts +246 -0
- package/src/modules/shipment_tracking/api/location-overrides/route.ts +185 -0
- package/src/modules/shipment_tracking/api/openapi.ts +28 -0
- package/src/modules/shipment_tracking/api/shipments/route.ts +197 -0
- package/src/modules/shipment_tracking/api/shipsgo-configs/route.ts +215 -0
- package/src/modules/shipment_tracking/api/tracking-jobs/route.ts +149 -0
- package/src/modules/shipment_tracking/api/tracking-jobs/sync/route.ts +116 -0
- package/src/modules/shipment_tracking/api/utils.ts +10 -0
- package/src/modules/shipment_tracking/api/webhooks/deliveries/route.ts +82 -0
- package/src/modules/shipment_tracking/api/webhooks/route.ts +138 -0
- package/src/modules/shipment_tracking/api/webhooks/test/route.ts +84 -0
- package/src/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/msc.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/one.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/zim.png +0 -0
- package/src/modules/shipment_tracking/assets/index.ts +66 -0
- package/src/modules/shipment_tracking/backend/carrier-configs/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/carrier-configs/page.tsx +782 -0
- package/src/modules/shipment_tracking/backend/location-overrides/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/location-overrides/page.tsx +241 -0
- package/src/modules/shipment_tracking/backend/shipment-tracking/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/shipment-tracking/page.tsx +340 -0
- package/src/modules/shipment_tracking/backend/tracking-jobs/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/tracking-jobs/page.tsx +16 -0
- package/src/modules/shipment_tracking/backend/webhooks/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/webhooks/page.tsx +228 -0
- package/src/modules/shipment_tracking/ce.ts +48 -0
- package/src/modules/shipment_tracking/cli.ts +321 -0
- package/src/modules/shipment_tracking/commands/bic-configs.ts +94 -0
- package/src/modules/shipment_tracking/commands/carrier-configs.ts +89 -0
- package/src/modules/shipment_tracking/commands/index.ts +8 -0
- package/src/modules/shipment_tracking/commands/location-overrides.ts +119 -0
- package/src/modules/shipment_tracking/commands/shipments.ts +247 -0
- package/src/modules/shipment_tracking/commands/shipsgo-configs.ts +101 -0
- package/src/modules/shipment_tracking/commands/tracking-jobs.ts +158 -0
- package/src/modules/shipment_tracking/commands/tracking.ts +230 -0
- package/src/modules/shipment_tracking/commands/webhooks.ts +159 -0
- package/src/modules/shipment_tracking/components/CombinedTimestampCell.tsx +236 -0
- package/src/modules/shipment_tracking/components/FacilityLocationInput.tsx +235 -0
- package/src/modules/shipment_tracking/components/LocationOverrideDrawer.tsx +586 -0
- package/src/modules/shipment_tracking/components/ShipmentDetailsDrawer.tsx +1364 -0
- package/src/modules/shipment_tracking/components/ShipmentDrawer.tsx +498 -0
- package/src/modules/shipment_tracking/components/ShipsGoConfigSection.tsx +266 -0
- package/src/modules/shipment_tracking/components/TimestampCell.tsx +146 -0
- package/src/modules/shipment_tracking/components/TrackingJobDrawer.tsx +467 -0
- package/src/modules/shipment_tracking/components/VesselTrackingMap.tsx +761 -0
- package/src/modules/shipment_tracking/components/WebhookDrawer.tsx +434 -0
- package/src/modules/shipment_tracking/data/entities.ts +748 -0
- package/src/modules/shipment_tracking/data/validators.ts +523 -0
- package/src/modules/shipment_tracking/di.ts +73 -0
- package/src/modules/shipment_tracking/encryption.ts +17 -0
- package/src/modules/shipment_tracking/events.ts +122 -0
- package/src/modules/shipment_tracking/hooks/useVesselTracking.ts +297 -0
- package/src/modules/shipment_tracking/i18n/de.json +327 -0
- package/src/modules/shipment_tracking/i18n/en.json +327 -0
- package/src/modules/shipment_tracking/i18n/es.json +327 -0
- package/src/modules/shipment_tracking/i18n/pl.json +327 -0
- package/src/modules/shipment_tracking/index.ts +13 -0
- package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-mapping.test.ts +385 -0
- package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-parser.test.ts +398 -0
- package/src/modules/shipment_tracking/lib/__tests__/empty-return.test.ts +174 -0
- package/src/modules/shipment_tracking/lib/__tests__/poi-event-processor.test.ts +699 -0
- package/src/modules/shipment_tracking/lib/__tests__/route-inference.test.ts +402 -0
- package/src/modules/shipment_tracking/lib/__tests__/status-machine.test.ts +447 -0
- package/src/modules/shipment_tracking/lib/__tests__/time-extraction.test.ts +331 -0
- package/src/modules/shipment_tracking/lib/__tests__/timestamp-utils.test.ts +260 -0
- package/src/modules/shipment_tracking/lib/__tests__/vessel-api.test.ts +125 -0
- package/src/modules/shipment_tracking/lib/__tests__/vessel-extraction.test.ts +108 -0
- package/src/modules/shipment_tracking/lib/adapters/cma-cgm.ts +84 -0
- package/src/modules/shipment_tracking/lib/adapters/cosco-types.ts +145 -0
- package/src/modules/shipment_tracking/lib/adapters/cosco.ts +314 -0
- package/src/modules/shipment_tracking/lib/adapters/evergreen.ts +107 -0
- package/src/modules/shipment_tracking/lib/adapters/hapag-lloyd.ts +88 -0
- package/src/modules/shipment_tracking/lib/adapters/index.ts +18 -0
- package/src/modules/shipment_tracking/lib/adapters/maersk.ts +104 -0
- package/src/modules/shipment_tracking/lib/adapters/msc.ts +223 -0
- package/src/modules/shipment_tracking/lib/adapters/zim.ts +106 -0
- package/src/modules/shipment_tracking/lib/audit-helpers.ts +29 -0
- package/src/modules/shipment_tracking/lib/auth/base64url.ts +4 -0
- package/src/modules/shipment_tracking/lib/auth/oauth-client.ts +53 -0
- package/src/modules/shipment_tracking/lib/background.ts +24 -0
- package/src/modules/shipment_tracking/lib/bic-api-client.ts +199 -0
- package/src/modules/shipment_tracking/lib/carrier-adapter.ts +136 -0
- package/src/modules/shipment_tracking/lib/current-vessel.ts +274 -0
- package/src/modules/shipment_tracking/lib/dcsa-event-mapping.ts +202 -0
- package/src/modules/shipment_tracking/lib/dcsa-event-parser.ts +163 -0
- package/src/modules/shipment_tracking/lib/dcsa-params.ts +14 -0
- package/src/modules/shipment_tracking/lib/empty-return.ts +122 -0
- package/src/modules/shipment_tracking/lib/location-overrides.ts +150 -0
- package/src/modules/shipment_tracking/lib/location-types.ts +154 -0
- package/src/modules/shipment_tracking/lib/logger.ts +195 -0
- package/src/modules/shipment_tracking/lib/poi-event-processor.ts +302 -0
- package/src/modules/shipment_tracking/lib/poi-nats-config.ts +134 -0
- package/src/modules/shipment_tracking/lib/poi-types.ts +198 -0
- package/src/modules/shipment_tracking/lib/rate-limiter.ts +58 -0
- package/src/modules/shipment_tracking/lib/route-extraction.ts +439 -0
- package/src/modules/shipment_tracking/lib/route-inference.ts +238 -0
- package/src/modules/shipment_tracking/lib/schedule-generator.ts +92 -0
- package/src/modules/shipment_tracking/lib/shipsgo-client.ts +350 -0
- package/src/modules/shipment_tracking/lib/shipsgo-mapper.ts +296 -0
- package/src/modules/shipment_tracking/lib/status-machine.ts +230 -0
- package/src/modules/shipment_tracking/lib/time-extraction.ts +85 -0
- package/src/modules/shipment_tracking/lib/timestamp-utils.ts +244 -0
- package/src/modules/shipment_tracking/lib/vessel-api.ts +299 -0
- package/src/modules/shipment_tracking/lib/vessel-cache.ts +102 -0
- package/src/modules/shipment_tracking/lib/vessel-extraction.ts +39 -0
- package/src/modules/shipment_tracking/lib/webhook-dispatcher.ts +93 -0
- package/src/modules/shipment_tracking/migrations/.snapshot-open-mercato.json +2914 -0
- package/src/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.ts +60 -0
- package/src/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.ts +22 -0
- package/src/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.ts +65 -0
- package/src/modules/shipment_tracking/notifications.ts +151 -0
- package/src/modules/shipment_tracking/services/carrierRegistry.ts +29 -0
- package/src/modules/shipment_tracking/services/poiNatsService.ts +526 -0
- package/src/modules/shipment_tracking/services/shipsGoProvider.ts +231 -0
- package/src/modules/shipment_tracking/services/trackingService.ts +1777 -0
- package/src/modules/shipment_tracking/services/webhookService.ts +347 -0
- package/src/modules/shipment_tracking/setup.ts +99 -0
- package/src/modules/shipment_tracking/subscribers/__tests__/terminal-event-ingest.test.ts +141 -0
- package/src/modules/shipment_tracking/subscribers/cargo-event-created.ts +115 -0
- package/src/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.ts +115 -0
- package/src/modules/shipment_tracking/subscribers/poi-event-notification.ts +144 -0
- package/src/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.ts +94 -0
- package/src/modules/shipment_tracking/subscribers/shipment-status-changed.ts +41 -0
- package/src/modules/shipment_tracking/subscribers/terminal-event-ingest.ts +109 -0
- package/src/modules/shipment_tracking/subscribers/tracking-job-initial-poll.ts +53 -0
- package/src/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.ts +50 -0
- package/src/modules/shipment_tracking/tables/index.ts +4 -0
- package/src/modules/shipment_tracking/tables/tracking_job/table.client.tsx +337 -0
- package/src/modules/shipment_tracking/tables/tracking_job/table.ts +34 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/config.ts +32 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.tsx +448 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.ts +25 -0
- 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
|
+
}
|