grm-shared-library 1.1.187 → 1.1.189

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 (116) hide show
  1. package/dist/cjs/index.js +1 -0
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/kafka/topics.js +6 -0
  4. package/dist/cjs/kafka/topics.js.map +1 -1
  5. package/dist/cjs/modules/common/constants/service.const.js +1 -0
  6. package/dist/cjs/modules/common/constants/service.const.js.map +1 -1
  7. package/dist/cjs/modules/socket/enums/redis-channel-name.enum.js +1 -0
  8. package/dist/cjs/modules/socket/enums/redis-channel-name.enum.js.map +1 -1
  9. package/dist/cjs/modules/socket/enums/socket-event-name.enum.js +5 -0
  10. package/dist/cjs/modules/socket/enums/socket-event-name.enum.js.map +1 -1
  11. package/dist/cjs/modules/tracking/constants/tracking-kafka.const.js +37 -0
  12. package/dist/cjs/modules/tracking/constants/tracking-kafka.const.js.map +1 -0
  13. package/dist/cjs/modules/tracking/enums/tracking-connection-status.enum.js +27 -0
  14. package/dist/cjs/modules/tracking/enums/tracking-connection-status.enum.js.map +1 -0
  15. package/dist/cjs/modules/tracking/enums/tracking-event-quality.enum.js +22 -0
  16. package/dist/cjs/modules/tracking/enums/tracking-event-quality.enum.js.map +1 -0
  17. package/dist/cjs/modules/tracking/enums/tracking-provider-code.enum.js +28 -0
  18. package/dist/cjs/modules/tracking/enums/tracking-provider-code.enum.js.map +1 -0
  19. package/dist/cjs/modules/tracking/enums/tracking-transport-type.enum.js +22 -0
  20. package/dist/cjs/modules/tracking/enums/tracking-transport-type.enum.js.map +1 -0
  21. package/dist/cjs/modules/tracking/enums/tracking-unit-online-status.enum.js +18 -0
  22. package/dist/cjs/modules/tracking/enums/tracking-unit-online-status.enum.js.map +1 -0
  23. package/dist/cjs/modules/tracking/index.js +39 -0
  24. package/dist/cjs/modules/tracking/index.js.map +1 -0
  25. package/dist/cjs/modules/tracking/interfaces/response-unit-position-event-v1.js +3 -0
  26. package/dist/cjs/modules/tracking/interfaces/response-unit-position-event-v1.js.map +1 -0
  27. package/dist/cjs/modules/tracking/interfaces/response-unit-status-event-v1.js +3 -0
  28. package/dist/cjs/modules/tracking/interfaces/response-unit-status-event-v1.js.map +1 -0
  29. package/dist/cjs/modules/tracking/interfaces/tracking-device-unmapped-event-v1.js +3 -0
  30. package/dist/cjs/modules/tracking/interfaces/tracking-device-unmapped-event-v1.js.map +1 -0
  31. package/dist/cjs/modules/tracking/interfaces/tracking-ingestion-error-event-v1.js +3 -0
  32. package/dist/cjs/modules/tracking/interfaces/tracking-ingestion-error-event-v1.js.map +1 -0
  33. package/dist/cjs/modules/tracking/interfaces/tracking-position-quality-flags.js +3 -0
  34. package/dist/cjs/modules/tracking/interfaces/tracking-position-quality-flags.js.map +1 -0
  35. package/dist/cjs/modules/tracking/interfaces/tracking-provider-health-event-v1.js +3 -0
  36. package/dist/cjs/modules/tracking/interfaces/tracking-provider-health-event-v1.js.map +1 -0
  37. package/dist/cjs/modules/tracking/interfaces/tracking-realtime-envelope.js +3 -0
  38. package/dist/cjs/modules/tracking/interfaces/tracking-realtime-envelope.js.map +1 -0
  39. package/dist/cjs/modules/tracking/interfaces/tracking-socket-payloads.js +3 -0
  40. package/dist/cjs/modules/tracking/interfaces/tracking-socket-payloads.js.map +1 -0
  41. package/dist/cjs/modules/tracking/interfaces/tracking-unit-current-state.js +3 -0
  42. package/dist/cjs/modules/tracking/interfaces/tracking-unit-current-state.js.map +1 -0
  43. package/dist/cjs/modules/tracking/utils/tracking-event-id.util.js +31 -0
  44. package/dist/cjs/modules/tracking/utils/tracking-event-id.util.js.map +1 -0
  45. package/dist/cjs/modules/tracking/utils/tracking-validation.util.js +101 -0
  46. package/dist/cjs/modules/tracking/utils/tracking-validation.util.js.map +1 -0
  47. package/dist/esm/index.js +1 -0
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/kafka/topics.js +6 -0
  50. package/dist/esm/kafka/topics.js.map +1 -1
  51. package/dist/esm/modules/common/constants/service.const.js +1 -0
  52. package/dist/esm/modules/common/constants/service.const.js.map +1 -1
  53. package/dist/esm/modules/socket/enums/redis-channel-name.enum.js +1 -0
  54. package/dist/esm/modules/socket/enums/redis-channel-name.enum.js.map +1 -1
  55. package/dist/esm/modules/socket/enums/socket-event-name.enum.js +5 -0
  56. package/dist/esm/modules/socket/enums/socket-event-name.enum.js.map +1 -1
  57. package/dist/esm/modules/tracking/constants/tracking-kafka.const.js +34 -0
  58. package/dist/esm/modules/tracking/constants/tracking-kafka.const.js.map +1 -0
  59. package/dist/esm/modules/tracking/enums/tracking-connection-status.enum.js +24 -0
  60. package/dist/esm/modules/tracking/enums/tracking-connection-status.enum.js.map +1 -0
  61. package/dist/esm/modules/tracking/enums/tracking-event-quality.enum.js +19 -0
  62. package/dist/esm/modules/tracking/enums/tracking-event-quality.enum.js.map +1 -0
  63. package/dist/esm/modules/tracking/enums/tracking-provider-code.enum.js +25 -0
  64. package/dist/esm/modules/tracking/enums/tracking-provider-code.enum.js.map +1 -0
  65. package/dist/esm/modules/tracking/enums/tracking-transport-type.enum.js +19 -0
  66. package/dist/esm/modules/tracking/enums/tracking-transport-type.enum.js.map +1 -0
  67. package/dist/esm/modules/tracking/enums/tracking-unit-online-status.enum.js +15 -0
  68. package/dist/esm/modules/tracking/enums/tracking-unit-online-status.enum.js.map +1 -0
  69. package/dist/esm/modules/tracking/index.js +23 -0
  70. package/dist/esm/modules/tracking/index.js.map +1 -0
  71. package/dist/esm/modules/tracking/interfaces/response-unit-position-event-v1.js +2 -0
  72. package/dist/esm/modules/tracking/interfaces/response-unit-position-event-v1.js.map +1 -0
  73. package/dist/esm/modules/tracking/interfaces/response-unit-status-event-v1.js +2 -0
  74. package/dist/esm/modules/tracking/interfaces/response-unit-status-event-v1.js.map +1 -0
  75. package/dist/esm/modules/tracking/interfaces/tracking-device-unmapped-event-v1.js +2 -0
  76. package/dist/esm/modules/tracking/interfaces/tracking-device-unmapped-event-v1.js.map +1 -0
  77. package/dist/esm/modules/tracking/interfaces/tracking-ingestion-error-event-v1.js +2 -0
  78. package/dist/esm/modules/tracking/interfaces/tracking-ingestion-error-event-v1.js.map +1 -0
  79. package/dist/esm/modules/tracking/interfaces/tracking-position-quality-flags.js +2 -0
  80. package/dist/esm/modules/tracking/interfaces/tracking-position-quality-flags.js.map +1 -0
  81. package/dist/esm/modules/tracking/interfaces/tracking-provider-health-event-v1.js +2 -0
  82. package/dist/esm/modules/tracking/interfaces/tracking-provider-health-event-v1.js.map +1 -0
  83. package/dist/esm/modules/tracking/interfaces/tracking-realtime-envelope.js +2 -0
  84. package/dist/esm/modules/tracking/interfaces/tracking-realtime-envelope.js.map +1 -0
  85. package/dist/esm/modules/tracking/interfaces/tracking-socket-payloads.js +2 -0
  86. package/dist/esm/modules/tracking/interfaces/tracking-socket-payloads.js.map +1 -0
  87. package/dist/esm/modules/tracking/interfaces/tracking-unit-current-state.js +2 -0
  88. package/dist/esm/modules/tracking/interfaces/tracking-unit-current-state.js.map +1 -0
  89. package/dist/esm/modules/tracking/utils/tracking-event-id.util.js +27 -0
  90. package/dist/esm/modules/tracking/utils/tracking-event-id.util.js.map +1 -0
  91. package/dist/esm/modules/tracking/utils/tracking-validation.util.js +93 -0
  92. package/dist/esm/modules/tracking/utils/tracking-validation.util.js.map +1 -0
  93. package/dist/types/index.d.ts +1 -0
  94. package/dist/types/kafka/topics.d.ts +5 -0
  95. package/dist/types/modules/common/constants/service.const.d.ts +4 -0
  96. package/dist/types/modules/socket/enums/redis-channel-name.enum.d.ts +2 -1
  97. package/dist/types/modules/socket/enums/socket-event-name.enum.d.ts +5 -1
  98. package/dist/types/modules/tracking/constants/tracking-kafka.const.d.ts +32 -0
  99. package/dist/types/modules/tracking/enums/tracking-connection-status.enum.d.ts +22 -0
  100. package/dist/types/modules/tracking/enums/tracking-event-quality.enum.d.ts +17 -0
  101. package/dist/types/modules/tracking/enums/tracking-provider-code.enum.d.ts +23 -0
  102. package/dist/types/modules/tracking/enums/tracking-transport-type.enum.d.ts +17 -0
  103. package/dist/types/modules/tracking/enums/tracking-unit-online-status.enum.d.ts +13 -0
  104. package/dist/types/modules/tracking/index.d.ts +17 -0
  105. package/dist/types/modules/tracking/interfaces/response-unit-position-event-v1.d.ts +62 -0
  106. package/dist/types/modules/tracking/interfaces/response-unit-status-event-v1.d.ts +23 -0
  107. package/dist/types/modules/tracking/interfaces/tracking-device-unmapped-event-v1.d.ts +25 -0
  108. package/dist/types/modules/tracking/interfaces/tracking-ingestion-error-event-v1.d.ts +27 -0
  109. package/dist/types/modules/tracking/interfaces/tracking-position-quality-flags.d.ts +22 -0
  110. package/dist/types/modules/tracking/interfaces/tracking-provider-health-event-v1.d.ts +27 -0
  111. package/dist/types/modules/tracking/interfaces/tracking-realtime-envelope.d.ts +32 -0
  112. package/dist/types/modules/tracking/interfaces/tracking-socket-payloads.d.ts +53 -0
  113. package/dist/types/modules/tracking/interfaces/tracking-unit-current-state.d.ts +27 -0
  114. package/dist/types/modules/tracking/utils/tracking-event-id.util.d.ts +27 -0
  115. package/dist/types/modules/tracking/utils/tracking-validation.util.d.ts +40 -0
  116. package/package.json +1 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Freshness of a response unit's last known position, derived by the projector's
3
+ * scheduled status evaluator from the gap between "now" and the last event time,
4
+ * using per-connection stale/offline thresholds.
5
+ */
6
+ export declare enum TrackingUnitOnlineStatus {
7
+ /** Reporting within the configured stale threshold. */
8
+ ONLINE = "ONLINE",
9
+ /** No update within the stale threshold but within the offline threshold. */
10
+ STALE = "STALE",
11
+ /** No update within the offline threshold. */
12
+ OFFLINE = "OFFLINE"
13
+ }
@@ -0,0 +1,17 @@
1
+ export * from './enums/tracking-provider-code.enum';
2
+ export * from './enums/tracking-transport-type.enum';
3
+ export * from './enums/tracking-connection-status.enum';
4
+ export * from './enums/tracking-unit-online-status.enum';
5
+ export * from './enums/tracking-event-quality.enum';
6
+ export * from './interfaces/tracking-position-quality-flags';
7
+ export * from './interfaces/response-unit-position-event-v1';
8
+ export * from './interfaces/response-unit-status-event-v1';
9
+ export * from './interfaces/tracking-provider-health-event-v1';
10
+ export * from './interfaces/tracking-device-unmapped-event-v1';
11
+ export * from './interfaces/tracking-ingestion-error-event-v1';
12
+ export * from './interfaces/tracking-unit-current-state';
13
+ export * from './interfaces/tracking-socket-payloads';
14
+ export * from './interfaces/tracking-realtime-envelope';
15
+ export * from './constants/tracking-kafka.const';
16
+ export * from './utils/tracking-event-id.util';
17
+ export * from './utils/tracking-validation.util';
@@ -0,0 +1,62 @@
1
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
2
+ /**
3
+ * Canonical, provider-neutral position event (schema v1).
4
+ *
5
+ * Produced by clarion-response-tracking after a raw provider location has been
6
+ * parsed, validated, normalized and bound to a Clarion response unit. Published
7
+ * on the `tracking.response-unit.position.v1` Kafka topic and consumed by the
8
+ * projector (history + current state) and any future tracking consumers.
9
+ *
10
+ * SECURITY: this contract is deliberately free of provider credentials, secret
11
+ * references, raw provider payloads and internal Kafka metadata. `organizationId`
12
+ * and `controlCentreId` are always sourced from trusted Clarion data (the device
13
+ * binding + response-unit projection), never from provider-supplied fields.
14
+ */
15
+ export interface ResponseUnitPositionEventV1 {
16
+ schemaVersion: 1;
17
+ /** Deterministic id (see buildTrackingEventId) — same fix ⇒ same id. */
18
+ eventId: string;
19
+ providerCode: TrackingProviderCode;
20
+ providerConnectionId: string;
21
+ organizationId: number;
22
+ controlCentreId: number;
23
+ responseUnitId: number;
24
+ externalUnitId: string;
25
+ externalDeviceId?: string;
26
+ imei?: string;
27
+ /** When the provider recorded the fix (ISO 8601, UTC). */
28
+ eventTime: string;
29
+ /** When Clarion received the message (ISO 8601, UTC). */
30
+ receivedAt: string;
31
+ position: {
32
+ latitude: number;
33
+ longitude: number;
34
+ altitudeMetres?: number;
35
+ accuracyMetres?: number;
36
+ };
37
+ motion: {
38
+ /** Normalized to kilometres per hour. */
39
+ speedKph?: number;
40
+ /** Degrees clockwise from true north, [0, 360). Omitted when unknown. */
41
+ courseDegrees?: number;
42
+ moving?: boolean;
43
+ ignitionOn?: boolean;
44
+ };
45
+ telemetry?: {
46
+ satellites?: number;
47
+ odometerKm?: number;
48
+ batteryPercentage?: number;
49
+ externalPowerVoltage?: number;
50
+ gsmSignalPercentage?: number;
51
+ };
52
+ providerStatus?: string;
53
+ quality: {
54
+ duplicate: boolean;
55
+ outOfOrder: boolean;
56
+ coordinatesValid: boolean;
57
+ };
58
+ /** Safe, non-sensitive raw values preserved for future re-normalization. */
59
+ providerMetadata?: Record<string, unknown>;
60
+ /** Correlation id for tracing across services. */
61
+ correlationId?: string;
62
+ }
@@ -0,0 +1,23 @@
1
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
2
+ import { TrackingUnitOnlineStatus } from '../enums/tracking-unit-online-status.enum';
3
+ /**
4
+ * Canonical online-status change event (schema v1). Emitted by the projector's
5
+ * status evaluator only when a unit's ONLINE/STALE/OFFLINE status actually
6
+ * changes, on `tracking.response-unit.status.v1`.
7
+ */
8
+ export interface ResponseUnitStatusEventV1 {
9
+ schemaVersion: 1;
10
+ eventId: string;
11
+ organizationId: number;
12
+ controlCentreId: number;
13
+ responseUnitId: number;
14
+ providerCode: TrackingProviderCode;
15
+ providerConnectionId: string;
16
+ previousStatus?: TrackingUnitOnlineStatus;
17
+ status: TrackingUnitOnlineStatus;
18
+ /** ISO 8601, UTC — the eventTime of the last position seen for this unit. */
19
+ lastEventTime?: string;
20
+ /** ISO 8601, UTC — when the evaluator computed this status. */
21
+ evaluatedAt: string;
22
+ correlationId?: string;
23
+ }
@@ -0,0 +1,25 @@
1
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
2
+ /**
3
+ * Emitted on `tracking.device.unmapped.v1` when telemetry arrives for an external
4
+ * unit that has no active device binding. Drives the administrative unmapped-unit
5
+ * projection. Never broadcast to ordinary tracking rooms.
6
+ *
7
+ * SECURITY: `payloadSummary` carries only safe, non-sensitive fields (e.g.
8
+ * coordinates, timestamp, nickname) — never credentials or the raw provider frame.
9
+ */
10
+ export interface TrackingDeviceUnmappedEventV1 {
11
+ schemaVersion: 1;
12
+ eventId: string;
13
+ providerCode: TrackingProviderCode;
14
+ providerConnectionId: string;
15
+ organizationId: number;
16
+ controlCentreId?: number;
17
+ externalUnitId: string;
18
+ externalNickname?: string;
19
+ firstSeenAt: string;
20
+ lastSeenAt: string;
21
+ occurrenceCount: number;
22
+ payloadSummary?: Record<string, unknown>;
23
+ evaluatedAt: string;
24
+ correlationId?: string;
25
+ }
@@ -0,0 +1,27 @@
1
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
2
+ /**
3
+ * Stage at which ingestion of a provider message/location failed.
4
+ */
5
+ export type TrackingIngestionStage = 'parse' | 'validate' | 'normalize' | 'resolve-binding' | 'persist-history' | 'update-current-state' | 'publish';
6
+ /**
7
+ * Emitted on `tracking.ingestion.error.v1` for observability when a message or
8
+ * a single location fails to ingest. One bad location must never terminate the
9
+ * connection nor block the other locations in the same frame.
10
+ *
11
+ * SECURITY: errorMessage must be sanitized before emission — no credentials,
12
+ * no raw provider frame, no tokens.
13
+ */
14
+ export interface TrackingIngestionErrorEventV1 {
15
+ schemaVersion: 1;
16
+ eventId: string;
17
+ providerCode: TrackingProviderCode;
18
+ providerConnectionId: string;
19
+ organizationId?: number;
20
+ controlCentreId?: number;
21
+ externalUnitId?: string;
22
+ stage: TrackingIngestionStage;
23
+ errorCode: string;
24
+ errorMessage: string;
25
+ occurredAt: string;
26
+ correlationId?: string;
27
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Fine-grained quality booleans attached to an ingested position. Kept
3
+ * provider-neutral; producers set what they can determine and leave the rest
4
+ * undefined. `duplicate`, `outOfOrder` and `coordinatesValid` are always set
5
+ * because the ingestion pipeline always evaluates them.
6
+ */
7
+ export interface TrackingPositionQualityFlags {
8
+ /** The same deterministic eventId was already ingested. */
9
+ duplicate: boolean;
10
+ /** eventTime is older than the current-state eventTime for this unit. */
11
+ outOfOrder: boolean;
12
+ /** Latitude/longitude are within valid WGS84 ranges. */
13
+ coordinatesValid: boolean;
14
+ /** eventTime parsed and fell within the accepted tolerance window. */
15
+ timestampValid?: boolean;
16
+ /** courseDegrees was present and within [0, 360). */
17
+ courseValid?: boolean;
18
+ /** speed parsed to a finite, non-negative value. */
19
+ speedValid?: boolean;
20
+ /** Distance/time since the previous fix implies an implausible jump. */
21
+ positionJumpSuspected?: boolean;
22
+ }
@@ -0,0 +1,27 @@
1
+ import { TrackingConnectionStatus } from '../enums/tracking-connection-status.enum';
2
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
3
+ /**
4
+ * Provider-connection health event (schema v1), emitted on
5
+ * `tracking.provider.health.v1` when a connection's status meaningfully changes
6
+ * (never on every heartbeat). Delivered to administrators only — never broadcast
7
+ * to ordinary tracking rooms.
8
+ *
9
+ * SECURITY: errorMessage is sanitized upstream; it must never contain the
10
+ * password, the full authentication request, secret references or tokens.
11
+ */
12
+ export interface TrackingProviderHealthEventV1 {
13
+ schemaVersion: 1;
14
+ eventId: string;
15
+ providerConnectionId: string;
16
+ providerCode: TrackingProviderCode;
17
+ organizationId: number;
18
+ controlCentreId?: number;
19
+ connectionStatus: TrackingConnectionStatus;
20
+ connectedAt?: string;
21
+ disconnectedAt?: string;
22
+ lastEventAt?: string;
23
+ errorCode?: string;
24
+ errorMessage?: string;
25
+ evaluatedAt: string;
26
+ correlationId?: string;
27
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The message clarion-response-tracking publishes to the Redis `realtime:tracking`
3
+ * channel for clarion-socket to fan out. Mirrors the flat newsfeed realtime
4
+ * envelope convention (deliberately simpler than the incident EventEnvelope).
5
+ *
6
+ * clarion-socket dedups on `eventId`, derives authorized rooms from
7
+ * `organizationId`/`controlCentreId`, and emits `payload` under the matching
8
+ * `SocketEventName` (position/status/removed/provider-health).
9
+ *
10
+ * SECURITY: `payload` is always one of the frontend-safe Tracking*SocketPayloadV1
11
+ * shapes — never a raw provider frame or anything carrying credentials.
12
+ */
13
+ export type TrackingRealtimeEventType = 'position' | 'status' | 'removed' | 'provider-health';
14
+ export interface TrackingRealtimeEnvelope<TPayload = unknown> {
15
+ /** Deterministic where possible; used by clarion-socket for dedup. */
16
+ eventId: string;
17
+ eventType: TrackingRealtimeEventType;
18
+ organizationId: number;
19
+ /** Absent for org-wide-only events; present to also target a CC room. */
20
+ controlCentreId?: number;
21
+ responseUnitId?: number;
22
+ /** ISO 8601, UTC. */
23
+ occurredAt: string;
24
+ /**
25
+ * True for provider-health events, which must only reach administrators —
26
+ * clarion-socket routes these to admin/role rooms, not org/cc tracking rooms.
27
+ */
28
+ adminOnly?: boolean;
29
+ payload: TPayload;
30
+ correlationId?: string;
31
+ sourceService: string;
32
+ }
@@ -0,0 +1,53 @@
1
+ import { TrackingConnectionStatus } from '../enums/tracking-connection-status.enum';
2
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
3
+ import { TrackingUnitOnlineStatus } from '../enums/tracking-unit-online-status.enum';
4
+ /**
5
+ * Frontend-safe payloads emitted to Socket.IO clients by clarion-socket.
6
+ *
7
+ * These are intentionally a minimal projection — no secretReference, no
8
+ * credentials, no raw provider frame, no internal Kafka metadata. clarion-socket
9
+ * emits exactly these shapes; the frontend mirror lives in clarion-shared-types.
10
+ */
11
+ export interface TrackingPositionSocketPayloadV1 {
12
+ responseUnitId: number;
13
+ organizationId: number;
14
+ controlCentreId: number;
15
+ eventTime: string;
16
+ receivedAt: string;
17
+ latitude: number;
18
+ longitude: number;
19
+ accuracyMetres?: number;
20
+ speedKph?: number;
21
+ /** Degrees clockwise from true north, [0, 360). Omitted when unknown. */
22
+ courseDegrees?: number;
23
+ moving?: boolean;
24
+ ignitionOn?: boolean;
25
+ status: TrackingUnitOnlineStatus;
26
+ }
27
+ export interface TrackingStatusSocketPayloadV1 {
28
+ responseUnitId: number;
29
+ organizationId: number;
30
+ controlCentreId: number;
31
+ status: TrackingUnitOnlineStatus;
32
+ previousStatus?: TrackingUnitOnlineStatus;
33
+ lastEventTime?: string;
34
+ evaluatedAt: string;
35
+ }
36
+ export interface TrackingRemovedSocketPayloadV1 {
37
+ responseUnitId: number;
38
+ organizationId: number;
39
+ controlCentreId: number;
40
+ /** Why the unit was removed (binding disabled/deleted, unit deleted, …). */
41
+ reason?: string;
42
+ evaluatedAt: string;
43
+ }
44
+ export interface TrackingProviderHealthSocketPayloadV1 {
45
+ providerConnectionId: string;
46
+ providerCode: TrackingProviderCode;
47
+ organizationId: number;
48
+ controlCentreId?: number;
49
+ connectionStatus: TrackingConnectionStatus;
50
+ lastEventAt?: string;
51
+ errorCode?: string;
52
+ evaluatedAt: string;
53
+ }
@@ -0,0 +1,27 @@
1
+ import { TrackingProviderCode } from '../enums/tracking-provider-code.enum';
2
+ import { TrackingUnitOnlineStatus } from '../enums/tracking-unit-online-status.enum';
3
+ /**
4
+ * Shape of the current-position projection held in Redis
5
+ * (`tracking:unit-state:{responseUnitId}`) and returned by the current-position
6
+ * REST endpoints. Frontend-safe: no credentials, no provider raw frame.
7
+ */
8
+ export interface TrackingUnitCurrentState {
9
+ organizationId: number;
10
+ controlCentreId: number;
11
+ responseUnitId: number;
12
+ providerCode: TrackingProviderCode;
13
+ providerConnectionId: string;
14
+ externalUnitId: string;
15
+ latitude: number;
16
+ longitude: number;
17
+ accuracyMetres?: number | null;
18
+ speedKph?: number | null;
19
+ courseDegrees?: number | null;
20
+ altitudeMetres?: number | null;
21
+ moving?: boolean | null;
22
+ ignitionOn?: boolean | null;
23
+ eventTime: string;
24
+ receivedAt: string;
25
+ lastPresenceAt?: string | null;
26
+ status: TrackingUnitOnlineStatus;
27
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Stable inputs from which a tracking event's id is derived. Chosen so that the
3
+ * SAME provider fix always yields the SAME id (idempotent history + dedup),
4
+ * while distinct fixes for the same unit yield distinct ids.
5
+ */
6
+ export interface TrackingEventIdParts {
7
+ providerConnectionId: string;
8
+ externalUnitId: string;
9
+ /** Provider event time as Unix epoch SECONDS. */
10
+ eventEpochSeconds: number;
11
+ latitude: number;
12
+ longitude: number;
13
+ }
14
+ /**
15
+ * Build a deterministic tracking event id (sha256 hex) from stable fix inputs.
16
+ *
17
+ * Coordinates are quantized to 6 decimal places (~0.11 m) so floating-point
18
+ * representation differences across services never split one physical fix into
19
+ * two ids. Epoch seconds are truncated to whole seconds.
20
+ */
21
+ export declare function buildTrackingEventId(parts: TrackingEventIdParts): string;
22
+ /**
23
+ * Kafka partition key for position/status events. Keying by
24
+ * `{organizationId}:{controlCentreId}:{responseUnitId}` guarantees per-unit
25
+ * ordering within a partition. Never use a random key for these events.
26
+ */
27
+ export declare function buildTrackingPartitionKey(organizationId: number, controlCentreId: number, responseUnitId: number): string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Provider-neutral validation/normalization helpers shared by the ingestion
3
+ * pipeline (and reusable by tests). No provider-specific field names appear here.
4
+ */
5
+ /** WGS84 latitude range check. */
6
+ export declare function isValidLatitude(value: unknown): value is number;
7
+ /** WGS84 longitude range check. */
8
+ export declare function isValidLongitude(value: unknown): value is number;
9
+ /** A valid course is a finite number in [0, 360). */
10
+ export declare function isValidCourseDegrees(value: unknown): value is number;
11
+ /**
12
+ * Normalize a raw course/bearing value into degrees in [0, 360), or null when it
13
+ * cannot be trusted for rotation.
14
+ *
15
+ * - A raw value of exactly `unknownSentinel` (default -1) is treated as unknown.
16
+ * - When `divisor` > 1 the raw value is divided (e.g. 27306 / 100 = 273.06).
17
+ * - The result is wrapped into [0, 360); a non-finite result yields null.
18
+ *
19
+ * The divisor is NOT hardcoded to a provider's scale — callers pass the value
20
+ * they have configured/confirmed for that connection.
21
+ */
22
+ export declare function normalizeCourseDegrees(raw: number | null | undefined, divisor?: number, unknownSentinel?: number | null): number | null;
23
+ /** Supported provider speed units for normalization into km/h. */
24
+ export type TrackingSpeedUnit = 'KPH' | 'MPS' | 'MPH' | 'RAW';
25
+ /**
26
+ * Convert a raw speed into kilometres per hour given the source unit and an
27
+ * optional multiplier applied to the raw value first. Returns null for
28
+ * non-finite or negative inputs. `RAW` means "already km/h after the multiplier".
29
+ */
30
+ export declare function normalizeSpeedToKph(raw: number | null | undefined, unit?: TrackingSpeedUnit, multiplier?: number): number | null;
31
+ /**
32
+ * Validate a provider epoch-seconds timestamp against a tolerance window and
33
+ * convert to an ISO 8601 UTC string. Returns null when out of range/unparseable.
34
+ *
35
+ * @param epochSeconds provider timestamp in seconds
36
+ * @param nowMs current time in ms (injectable for deterministic tests)
37
+ * @param futureToleranceSeconds max seconds a fix may be ahead of now
38
+ * @param maxAgeSeconds max seconds a fix may be behind now (0/undefined = no limit)
39
+ */
40
+ export declare function epochSecondsToIsoUtc(epochSeconds: number | null | undefined, nowMs: number, futureToleranceSeconds?: number, maxAgeSeconds?: number): string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grm-shared-library",
3
- "version": "1.1.187",
3
+ "version": "1.1.189",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",