Route Updates

SALLY continuously monitors active routes and updates them when conditions change. This page explains the trigger system, the re-plan vs ETA-update decision, and how route versioning works.


Endpoint

POST /api/v1/routes/update

Authentication: Bearer token required. Roles: DISPATCHER, ADMIN, OWNER.


Request

{
  "plan_id": "RPL-2026021101",
  "trigger": {
    "type": "dock_time_changed",
    "details": {
      "stop_id": "LOC-001",
      "original_dock_hours": 2.0,
      "actual_dock_hours": 4.5,
      "reason": "Loading delays due to staffing shortage"
    }
  },
  "driver_current_state": {
    "latitude": 34.0522,
    "longitude": -118.2437,
    "hours_driven": 3.5,
    "on_duty_hours": 6.0
  }
}

Response

{
  "plan_id": "RPL-2026021101",
  "version": 2,
  "previous_version": 1,
  "update_type": "re_plan",
  "trigger_summary": "Dock time at ABC Distribution Center changed from 2.0h to 4.5h (+2.5h)",
  "impact": {
    "eta_change_hours": 2.5,
    "hos_impact": "Duty window reduced by 2.5h. Rest stop moved earlier.",
    "stops_affected": ["LOC-002"],
    "re_plan_required": true,
    "reason": "HOS impact exceeds threshold. Remaining route requires re-planning."
  },
  "segments": [
    {
      "sequence": 1,
      "type": "drive",
      "from": "Current Location",
      "to": "Truck Stop - I-5 Exit 200",
      "distance_miles": 30,
      "duration_hours": 0.5
    },
    {
      "sequence": 2,
      "type": "rest",
      "location": "Truck Stop - I-5 Exit 200",
      "rest_type": "full_rest",
      "duration_hours": 10.0,
      "reason": "Extended dock time consumed duty window. Full rest required before continuing."
    },
    {
      "sequence": 3,
      "type": "drive",
      "from": "Truck Stop - I-5 Exit 200",
      "to": "XYZ Warehouse",
      "distance_miles": 200,
      "duration_hours": 3.5
    }
  ],
  "compliance": {
    "hos_violations": 0,
    "missed_appointments": 0,
    "overall_status": "COMPLIANT"
  },
  "updated_at": "2026-02-11T14:30:00Z"
}

Trigger Types

SALLY monitors 20 alert types across 6 categories. Each trigger is evaluated to determine whether a re-plan or ETA update is needed.

HOS Triggers

TriggerDescriptionTypical Response
hos_approaching_limitDriver within 1h of drive/duty limitMonitor; ensure rest stop upcoming
hos_violationActive HOS violation detectedMandatory rest, re-plan route
break_required8h since last breakInsert 30-min break
cycle_limit_approachingWithin 5h of 70h cycle limitPlan extended rest or 34h restart

Route Progress Triggers

TriggerDescriptionTypical Response
dock_time_changedActual dock time differs from estimateRe-plan if impact exceeds 30 min
missed_appointmentDriver missed time windowContact customer, re-plan
route_delayETA delay exceeds 30 minutesUpdate ETAs, notify customer
driver_not_movingNo movement for 2+ hours during drive segmentAlert dispatcher

Load Triggers

TriggerDescriptionTypical Response
load_addedNew stop added mid-routeRe-sequence remaining stops
load_cancelledStop removed from routeRe-plan with remaining stops

Driver Triggers

TriggerDescriptionTypical Response
driver_rest_requestDriver wants to rest at current locationUpdate HOS, re-plan remaining route
driver_status_changeDriver changed duty statusUpdate HOS tracking

External Triggers

TriggerDescriptionTypical Response
traffic_delayReal-time traffic alert on routeRe-plan if delay exceeds 30 min
weather_alertSevere weather on routeAdjust speed estimates, re-plan if needed

Re-Plan vs ETA Update

When a trigger is detected, the update handler decides what to do:

Trigger Detected

Calculate Impact:
  - HOS hours consumed/changed
  - Time added/removed
  - Stops affected

Impact > Threshold?
  ├── YES → Full Re-Plan (invoke Route Planning Engine)
  └── NO  → ETA Update Only (adjust timing, no route changes)

Decision Thresholds

ConditionDecision
ETA change under 30 minutesETA update only
ETA change 30+ minutesRe-plan
HOS violation imminentRe-plan (always)
Stop added or cancelledRe-plan (always)
Driver rest requestRe-plan (always)
Traffic delay under 30 minETA update only
Traffic delay 30+ minRe-plan

Update Types

TypeDescription
re_planFull route re-planning. Generates new segment sequence from current location. May re-order stops, insert/remove rest stops.
eta_updateTiming adjustment only. Same segments, updated arrival/departure times.
notify_onlyInformational trigger. No route or timing changes (e.g., route completed).

Route Versioning

Every update creates a new version of the route plan. This provides a complete audit trail.

FieldDescription
versionCurrent plan version (increments with each update)
previous_versionVersion before this update
trigger_summaryHuman-readable description of what changed
impactAnalysis of the trigger’s effect on the route

Example version history:

VersionTriggerUpdate TypeKey Change
v1Initial planOriginal route with 8 segments
v2Dock time extended (+2.5h)Re-planRest stop moved earlier, 1 segment added
v3Traffic delay (45 min)Re-planAlternative route segment, ETA +30 min
v4Driver rest requestRe-planRest inserted at current location

Monitoring Loop

The Continuous Monitoring Service runs in the background, checking every active route every 60 seconds:

For each active route:
  1. Check HOS state (approaching limits?)
  2. Check route progress (on track? delays?)
  3. Check external conditions (traffic? weather?)
  4. Check driver status (moving? resting?)

  If trigger detected:
    → Evaluate severity
    → Generate alert (for dispatcher)
    → Determine update type (re-plan / ETA / notify)
    → Execute update
    → Notify driver of changes

Driver Notifications

When a route is updated, the driver receives a notification:

  • Re-plan: “Route updated. Review changes.” with a diff of what changed
  • ETA update: “ETA updated. New arrival at Stop B: 3:45 PM (was 3:15 PM)”
  • Mandatory rest: “Rest required. Navigate to [location] for 10h rest.”

The driver can:

  • Accept the new route (becomes active)
  • View changes (see before/after comparison)
  • Request modification (dispatcher notified)

Error Handling

404 — Plan Not Found

{
  "statusCode": 404,
  "message": "Route plan RPL-INVALID not found",
  "error": "Not Found"
}

409 — Plan Not Active

{
  "statusCode": 409,
  "message": "Route plan RPL-2026021101 is not active (status: completed). Only active plans can be updated.",
  "error": "Conflict"
}

422 — Route Infeasible After Update

{
  "statusCode": 422,
  "message": "Route is not feasible after update: all remaining appointments are past their latest time window.",
  "error": "Unprocessable Entity"
}