Busflow Docs

Internal documentation portal

Skip to content

ADR-016: Incident Lifecycle State Machine ​

Status: βœ… Accepted Triggered by: Level 2 Audit β€” Incident & IssueReport Workflow (Findings I-1, I-2, I-3, I-4, I-10)

Context ​

The L1 audit flagged the Incident entity as having an insufficient lifecycle (OPEN β†’ RESOLVED). Journey 2 ("Alpine Stau") demonstrates a multi-step workflow: driver reports β†’ dispatcher acknowledges β†’ dispatcher broadcasts β†’ incident resolved. The current schema cannot represent these intermediate states, track the responsible dispatcher, or emit events for downstream systems (Communications, Backoffice). The L2 drill-down confirms that three additional fields (assigned_to, reporter_crew_id, resolved_at) and two intermediate states (ACKNOWLEDGED, IN_PROGRESS) are required.

Decision ​

Expand the Incident status enum to OPEN β†’ ACKNOWLEDGED β†’ IN_PROGRESS β†’ RESOLVED and add the missing fields. Register two domain events: IncidentCreated and IncidentResolved. No separate IncidentEscalated event β€” the Communications consumer routes based on severity in the IncidentCreated payload (CRITICAL β†’ WhatsApp broadcast, LOW/MEDIUM β†’ dispatch board only), consistent with the existing event catalog pattern. The dispatcher is the primary actor for ACKNOWLEDGED and IN_PROGRESS transitions. Phase 1 UI: "Take Over" button atomically transitions OPEN β†’ ACKNOWLEDGED β†’ IN_PROGRESS and sets assigned_to in a single action.

Consequences ​

  • Schema: 6 new columns on incidents: reporter_crew_id, assigned_to, description, geo_coordinates, resolved_at. Status enum expanded from 2 to 4 states. See schema-operations.md Β§incidents.
  • Event catalog: 2 new events: IncidentCreated, IncidentResolved. No IncidentEscalated β€” severity-based routing in consumer. See event-catalog.md.
  • XState: Incident lifecycle machine replaces the bare enum, per workflow-orchestration.md patterns.
  • Hasura Event Triggers: IncidentCreated fires on INSERT, IncidentResolved fires on UPDATE to RESOLVED.
  • Driver Hub (offline): The driver creates an Incident with status = OPEN. Subsequent transitions require server connectivity (dispatcher-driven). No offline state advancement beyond OPEN. Dedup key: (service_leg_id, type, occurred_at Β± 5min) prevents duplicate incidents on sync.
  • BREAKDOWN incidents do NOT emit VehicleMaintenanceRequired β€” the driver files a separate IssueReport for vehicle maintenance (see ADR-008).
  • IssueReport ↔ Incident linkage: New incident_issue_reports join table bridges the many-to-many relationship. The dispatcher manually links IssueReports to Incidents β€” no automatic promotion.
  • IssueReport feedback loop: Two new Backoffice β†’ Operations events (VehicleInspectionScheduled, VehicleInspectionCompleted) drive IssueReport status transitions (OPEN β†’ IN_PROGRESS β†’ RESOLVED).

Internal documentation β€” Busflow