CMMS Work Order Synchronization
A classified defect is not closed until a mechanic has repaired it and someone has certified that repair — and that certification is a federal obligation, not a workflow nicety. Under 49 CFR § 396.11©(2), a motor carrier must certify that every defect noted on a driver vehicle inspection report which would affect safe operation has been repaired before the vehicle is dispatched again, and under § 396.3 it must keep systematic maintenance records proving it. When your maintenance shop lives in a computerized maintenance management system (CMMS) such as Fleetio, Maintenance Connection, or eMaint, the repair-complete signal is created there — and if that signal never flows back to the compliance system, the loop stays open and the vehicle is dispatched on an uncertified repair. This guide specifies the bidirectional synchronization that turns a classified defect into a CMMS work order and drives the completion back to the certification gate that clears the vehicle.
This section sits inside the Telematics, ELD & Maintenance Platform Integration section, which defines the canonical outbound DvirComplianceEvent that every downstream platform consumes. Severity scoring is produced upstream by the Severity Scoring Algorithms for DVIR Defects engine and the routing decision by Critical vs Non-Critical Routing Logic; this layer takes the resulting event, opens the corresponding work order, and reconciles its status. The field-level translation from a defect to a single work-order line item is covered in depth in Mapping DVIR Defects to CMMS Work Orders; this page defines the schema, the sync algorithm, and the compliance gate those mappings feed.
Prerequisites and Environment Setup
Anchor link to "Prerequisites and Environment Setup"Work-order synchronization is a long-running service, not a batch job: it consumes compliance events, holds open work orders, and reacts to inbound completion webhooks at arbitrary times. Target Python 3.10+ (the code uses X | Y unions, match/case, and list[...] generics) with:
- Pydantic 2.x — model the
WorkOrdercontract and validate every inbound CMMS payload before it touches your state. - httpx — async HTTP client for the outbound CMMS REST calls, with per-vendor timeouts and retry budgets.
- A CMMS account with API + webhook access — Fleetio, Maintenance Connection, and eMaint each expose a work-order create/update API and outbound webhooks; the vendor-neutral adapter layer pattern applies here too when you support more than one.
- A durable store keyed on
(dvir_id, defect_id)— Postgres with a unique constraint on that pair is the enforcement point for idempotent upsert; do not rely on application-side deduplication alone. - The canonical event contract — the inbound
DvirComplianceEventis defined by the Telematics, ELD & Maintenance Platform Integration section and must already validate against the Standardized DVIR JSON Schema Design contract before it reaches this service.
Never open a work order directly from a raw inspection payload. The event this service consumes has already been scored, routed, and hashed; opening work from unvalidated input lets an OCR artifact or a duplicate submission create phantom repair work that a mechanic will waste a bay on.
Data Schema and Normalization
Anchor link to "Data Schema and Normalization"Two records govern this loop. The inbound DvirComplianceEvent is the canonical outbound event — reuse it verbatim rather than inventing a local shape. The outbound WorkOrder is the CMMS-facing record this service owns. Keeping the field names identical to the scoring and routing pages lets a single defect be reconstructed end to end during an audit.
| Field | Type | Enumeration / range | Compliance tag |
|---|---|---|---|
work_order_id |
str |
CMMS-assigned or client UUID | Cross-system correlation key |
dvir_id |
str |
matches the source DVIR | FMCSA_396.11 |
defect_id |
str |
one per classified defect | Idempotency key component |
vmrs_code |
str |
VMRS system-assembly-component | Maintenance record taxonomy |
priority |
str (enum) |
oos, urgent, scheduled |
Derived from severity band |
status |
str (enum) |
open, in_progress, completed, verified |
Certification lifecycle |
opened_at |
datetime (tz-aware) |
ISO-8601 | § 396.3 record anchor |
closed_at |
datetime | None |
ISO-8601 or null until verified | Repair completion timestamp |
The status enum is the spine of the certification loop. open and in_progress are shop-side states; completed means the mechanic marked the repair done in the CMMS; verified means your system has reconciled that completion and recorded the carrier certification. Only verified clears the certification gate — a completed work order that has not been verified is not yet a certified repair under § 396.11©(2). Enforce the contract in Pydantic so a malformed CMMS webhook is rejected, not coerced:
from datetime import datetime
from enum import Enum
from pydantic import BaseModel, Field
class WorkOrderStatus(str, Enum):
OPEN = "open"
IN_PROGRESS = "in_progress"
COMPLETED = "completed" # mechanic marked done in the CMMS
VERIFIED = "verified" # carrier certification recorded — clears § 396.11(c)(2)
class WorkOrder(BaseModel):
model_config = {"use_enum_values": True}
work_order_id: str
dvir_id: str
defect_id: str
vmrs_code: str
priority: str = Field(pattern=r"^(oos|urgent|scheduled)$")
status: WorkOrderStatus = WorkOrderStatus.OPEN
opened_at: datetime
closed_at: datetime | None = None
class DvirComplianceEvent(BaseModel):
"""Canonical outbound event defined by the section. Reused, never redefined."""
event_id: str
dvir_id: str
vehicle_vin: str
driver_id: str
severity_score: int = Field(ge=0, le=100)
compliance_action: str = Field(pattern=r"^(OOS_HOLD|REPAIR_QUEUE|SCHEDULED_PM)$")
audit_hash: str # SHA-256 over canonical JSON
version: int
emitted_at: datetime
Core Algorithm or Workflow
Anchor link to "Core Algorithm or Workflow"Synchronization runs as two directional flows sharing one durable state table. The outbound flow creates work; the inbound flow closes it. Both must be idempotent because both are driven by at-least-once delivery — a webhook or event will be redelivered, and a naive handler creates duplicate work orders or double-certifies a repair.
- Consume the compliance event. Read the
DvirComplianceEvent, verify itsaudit_hashagainst the canonical JSON, and reject any event whose hash does not match — a mismatched hash means the payload was altered in flight and must not open work. - Map defect to work order. For each classified defect on the DVIR, translate
defect_categoryto avmrs_codeand derivepriorityfrom the severity band. The full field-level mapping is specified in Mapping DVIR Defects to CMMS Work Orders. - Upsert idempotently. Insert the work order keyed on
(dvir_id, defect_id). If a row already exists for that pair, update it in place rather than creating a second one. This is what makes a redelivered event a no-op instead of a duplicate repair. - Push to the CMMS. Call the vendor create/update API. Store the CMMS-assigned
work_order_idback on the row so later completion webhooks can be correlated. - Reconcile inbound completion. When the CMMS emits a completion webhook, look up the work order by its CMMS id, advance
open/in_progress→completed, and stampclosed_at. - Verify and certify. Record the carrier certification, advance
completed→verified, and re-evaluate the certification gate for the parent DVIR. Only when every affecting defect isverifiedmay the vehicle be cleared for dispatch.
The upsert is the load-bearing step. Push the uniqueness invariant into the database and let the conflict clause absorb retries:
from datetime import datetime, timezone
import httpx
from sqlalchemy import text
from sqlalchemy.engine import Connection
SEVERITY_TO_PRIORITY = {"critical": "oos", "major": "urgent", "minor": "scheduled"}
def band(score: int) -> str:
# 0-34 minor / 35-69 major / 70-100 critical — identical to the scoring engine.
return "critical" if score >= 70 else "major" if score >= 35 else "minor"
def upsert_work_order(conn: Connection, wo: WorkOrder) -> str:
"""Insert or update keyed on (dvir_id, defect_id). A redelivered event
is a no-op, so a webhook retry never opens a duplicate repair order."""
row = conn.execute(
text("""
INSERT INTO work_orders
(work_order_id, dvir_id, defect_id, vmrs_code, priority, status, opened_at)
VALUES
(:work_order_id, :dvir_id, :defect_id, :vmrs_code, :priority, :status, :opened_at)
ON CONFLICT (dvir_id, defect_id) DO UPDATE
SET vmrs_code = EXCLUDED.vmrs_code,
priority = EXCLUDED.priority
RETURNING work_order_id
"""),
wo.model_dump(mode="json"),
).scalar_one()
return row
Compliance Thresholding and Routing
Anchor link to "Compliance Thresholding and Routing"The compliance_action on the incoming event already encodes the severity band, and the work order’s priority must mirror it so the shop queues the right work first. The mapping is fixed and matches every other page in this section:
OOS_HOLD(severity ≥ 70, or anyDOT_OOS_CRITERIAdefect): open the work order at priorityoosand hold the vehicle out of service. The vehicle may not be dispatched until the corresponding work order reachesverified. This floor is immovable — no CMMS status short of a certified repair clears it, per Out-of-Service Criteria and OOS Hold Triggers.REPAIR_QUEUE(severity 35–69, major): open at priorityurgentand route into the regulated 24-hour repair queue. The vehicle may operate only if the defect does not affect safe operation, and the repair must still be certified before the condition is cleared.SCHEDULED_PM(severity 0–34, minor): open at priorityscheduledand let Mechanic Assignment & Workload Balancing place it in the preventive-maintenance backlog.
The certification gate is the compliance heart of this loop. Section 396.11©(2) requires the carrier to certify that a defect affecting safe operation has been corrected before the vehicle is operated again, and the next driver’s review under § 396.11©(2)(iii) depends on that certification existing. Model the gate as a pure predicate over the work orders for a DVIR, and refuse to clear the vehicle until every affecting defect is verified:
def certification_gate(work_orders: list[WorkOrder]) -> bool:
"""Clear a vehicle only when every OOS/urgent work order for the DVIR is
verified. A merely 'completed' order is not yet a certified repair under
49 CFR 396.11(c)(2)."""
affecting = [wo for wo in work_orders if wo.priority in ("oos", "urgent")]
return all(wo.status == WorkOrderStatus.VERIFIED for wo in affecting)
The certification event this gate records should reference the mechanic identity and timestamp exactly as Certifying Repairs Under 396.11©(2) specifies, so an auditor can tie the certification to a real person and a real repair.
Production Integration and Platform Synchronization
Anchor link to "Production Integration and Platform Synchronization"At-least-once delivery in both directions is the defining operational fact. Every design decision below exists to make redelivery safe.
- Idempotent upsert, enforced in the database. The unique constraint on
(dvir_id, defect_id)is the single source of truth. A webhook retry, an event replay, or two consumers racing all converge on the same row. Never generate thework_order_idnon-deterministically before checking for an existing row. - Status reconciliation, not blind overwrite. Inbound completion webhooks arrive out of order — a
completedevent can land after a later correction. Advance status only along the legal pathopen → in_progress → completed → verified; reject a webhook that would move averifiedorder backward and log it, rather than reopening a certified repair. - Conflict handling on divergent state. If the CMMS reports a status that contradicts your record — the shop reopened a work order you had marked
verified— do not silently accept it. Route the conflict to a review queue and hold the certification, because a reopened repair means the § 396.11©(2) certification is no longer valid. High-volume conflict bursts belong in a dead-letter queue for controlled replay. - Cryptographic traceability. Carry the event’s
audit_hashonto the work order and into the certification record, hash-linking each status transition to its predecessor. This gives the same tamper-evident chain the Immutable Audit Trail and WORM Retention guide applies to inspection records, and satisfies the § 396.3 systematic-record requirement. - Verify the inbound signature. Treat CMMS webhooks the way you treat any external callback — verify the vendor signature before acting, using the same discipline as Idempotent Webhook Retry and Signature Verification.
Engineering Standards Checklist
Anchor link to "Engineering Standards Checklist"- Idempotent by construction — the
(dvir_id, defect_id)unique constraint makes every redelivered event and webhook a no-op; no duplicate work orders. - Status transitions are one-directional — advance only along
open → in_progress → completed → verified; a backward move is rejected and logged, never applied. - The gate demands
verified— acompletedwork order does not clear the certification gate; only a recorded carrier certification does. - OOS holds are immovable — a severity-70-and-above defect holds the vehicle until its work order is
verified, regardless of CMMS status. - Hash the chain — carry
audit_hashonto every work order and certification so a repair record is tamper-evident under § 396.3. - Signatures verified inbound — reject unsigned or mis-signed CMMS webhooks before they touch state.
- Conflicts quarantined — divergent CMMS state routes to review and holds certification rather than overwriting.
Frequently Asked Questions
Anchor link to "Frequently Asked Questions"Why key the work order on both dvir_id and defect_id instead of just the defect?
Because a defect id is only unique within a DVIR, and because idempotency must survive event replay. Keying on the pair (dvir_id, defect_id) guarantees that a redelivered DvirComplianceEvent maps to exactly one work order, so a webhook retry updates the existing row instead of opening a duplicate repair. It also lets an auditor trace a specific work order straight back to the specific defect on the specific inspection report that generated it.
Does a completed work order in the CMMS satisfy 49 CFR 396.11©(2)?
No. A completed status means the mechanic marked the repair done in the CMMS, but § 396.11©(2) requires the carrier to certify that the defect has been corrected. Your system records that certification and advances the work order to verified; only verified clears the certification gate. Treating completed as certification would dispatch a vehicle on an unverified repair.
What happens if the CMMS reopens a work order I already marked verified?
Hold the certification and route the conflict to review. A reopened repair means the condition that justified the § 396.11©(2) certification may not actually be corrected, so the prior certification can no longer be trusted. Do not accept the reopen silently and do not let the vehicle keep operating on the strength of a certification that the shop itself has contradicted.
How do I map a severity score to a work-order priority?
Use the same bands as the rest of the pipeline: 0–34 minor maps to scheduled, 35–69 major maps to urgent, and 70–100 critical (or any DOT_OOS_CRITERIA defect) maps to oos. The priority is derived directly from the severity_score on the compliance event so the shop queue and the compliance state never disagree.
Related
Anchor link to "Related"- Mapping DVIR Defects to CMMS Work Orders — the field-level defect-to-work-order translation this loop depends on.
- Certifying Repairs Under 396.11©(2) — the certification record the gate writes.
- Mechanic Assignment & Workload Balancing — where scheduled and urgent work orders are staffed.
- Idempotent Webhook Retry and Signature Verification — the retry and signature discipline applied to inbound CMMS webhooks.
- Immutable Audit Trail and WORM Retention — the tamper-evident chain the work-order and certification records join.