Event Model for ETA & Exceptions
This document details the JSON structure for prediction.eta_update and exception.occurrence events.
These events drive the “Control Tower” dashboards and automated customer notifications.
The model favors high-cardinality metadata (explicit IDs) over pre-computed text strings to allow for internationalization (i18n) downstream.
ETA Update Structure
The eta_update event is generated whenever the prediction engine recalculates a route. This can be triggered by a GPS ping, a change in traffic conditions, or a manual update from a dispatcher. Note that we separate the calculated_at timestamp (when the ML model ran) from the event_timestamp (when the data point was valid).
{
"event_id": "evt_8839201-ax-99",
"event_type": "prediction.eta_update",
"shipment_id": "shp_5500221",
"carrier_id": "carr_992",
"payload": {
"stop_sequence": 2,
"facility_id": "fac_atl_004",
"original_appointment": "2023-10-27T14:00:00Z",
"previous_eta": "2023-10-27T14:30:00Z",
"current_eta": "2023-10-27T16:15:00Z",
"confidence_score": 0.89,
"drift_minutes": 105,
"reason_code": "TRAFFIC_CONGESTION"
},
"meta": {
"source_system": "ML_PREDICTOR_V2",
"calculated_at": "2023-10-27T10:05:22Z"
}
}
Internal Lab Notes: Handling Drift
The “Yo-Yo” Effect: We observed cases where ETA predictions oscillate wildly (e.g., +2 hours, then -1 hour, then +2 hours) when a truck is idling near a highway exit.
Mitigation: Do not trigger customer notifications solely on drift_minutes. Implement a hysteresis loop in the notification service. Only alert if the drift persists for > 2 consecutive pings or exceeds a “Hard Threshold” (e.g., > 4 hours).
Anti-Pattern: Never overwrite the original_appointment field in the database with the current_eta. You destroy your ability to calculate On-Time-In-Full (OTIF) metrics if you lose the baseline.
Exception Occurrence Structure
Exceptions cover non-temporal issues: damaged cargo, refused delivery, or missing paperwork. Unlike ETAs which are continuous, Exceptions are discrete. They often require a “Resolution” workflow (e.g., a user manually clearing the exception).
| Field | Type | Description |
|---|---|---|
| severity_level | enum | Values: INFO, WARN, CRITICAL. |
| resolution_required | boolean | If true, the shipment enters a “Blocked” state in the TMS until an operator acknowledges. |
| location_context | object | Lat/Long and reverse-geocoded address where exception occurred. |
{
"event_type": "exception.occurrence",
"code": "EX_TEMP_OUT_OF_RANGE",
"description": "Reefer temperature exceeded -10C threshold.",
"sensor_readings": [
{ "metric": "temp_c", "value": -8.5 },
{ "metric": "battery_v", "value": 12.1 }
]
}
Internal Lab Notes: Assumption vs Reality
We often assume GPS coordinates in an exception event match the truck’s location. However, for “Manual” exceptions (e.g., driver calls in a breakdown), the dispatcher might enter the event hours later from a central office.
Always rely on the linked asset_id to fetch the true telemetry position at event_timestamp rather than trusting the user_location metadata for geospatial analysis.
Document generated for BigData-ETL Platform Engineering. Last validated against Schema Registry v2.4.1.