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. NoIncidentEscalatedβ 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:
IncidentCreatedfires on INSERT,IncidentResolvedfires 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_reportsjoin 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).