WHO maintenance & CMMS gap — implementation checklist
Companion to docs/who-lifecycle-gap-checklist.md and docs/who-inventory-nomenclature-gap-checklist.md. Those cover the lifecycle-stage and inventory/nomenclature gaps; this one covers section 6 ("Maintenance management system for medical devices") and section 7 ("Computerized maintenance management systems") of the same WHO document — Inventory and maintenance management information system for medical devices (WHO, 2025) — publication page.
Section 7 is WHO's own definition of what a CMMS should contain, which is the most direct yardstick available for Ovahol specifically, since Ovahol is a CMMS. Most of both sections are already well covered — better than expected in a couple of places (work order SLA derivation, spare parts). Three concrete items are worth tracking; two more are refinements to gaps already logged in the lifecycle checklist rather than new work.
Priority 1 — Mean time to repair (MTTR) metric — done
WHO calls out MTTR (average time to restore a device to service after a failure) as a core corrective-maintenance KPI. Ovahol already captured the raw data — estimated_duration_minutes and actual_duration_minutes on WorkOrderResponse (internal/modules/maintenance/dto/work_order.go) — but there was no aggregated MTTR figure anywhere in the dashboard/stats endpoints. The data existed; the rollup didn't.
- [x] Added an MTTR calculation to
WorkOrderService.GetStats(internal/modules/maintenance/service/work_order.go), sourced from a newavg_mttr_minutescolumn on the existingGetWorkOrderResolutionMetricsquery (internal/modules/maintenance/repository/sql/work_order.sql): average wall-clockcompleted_at - created_atacross completedCORRECTIVEwork orders (chosen overactual_duration_minutessince it's nullable/technician-entered and would undercount devices waiting on parts/availability — wall-clock time better matches WHO's "time to restore to service" framing, and mirrors the existingavg_resolution_minutesmetric's own convention). Not broken down by priority or device category — deferred as a possible follow-up, not required for the KPI itself. - [x] Surfaced on the facility maintenance dashboard (
ResponseMetricsStrip.vue, fed fromFacilityDashboardContent.vue) alongside the existing response-metrics tiles, and on the work orders list page (ListWorkOrders.vue) next to Avg Resolution/Avg Execution. - [x] Trending over time. Added a
GetMTTRTrendquery (internal/modules/maintenance/repository/sql/work_order.sql) that buckets the same MTTR calculation by completion month over a trailing window (default 180 days, overridable via?days=, capped at 730), exposed atGET /work-orders/stats/mttr-trend. The original all-timeavg_mttr_minutesonGetStatsis unchanged — this is an additive, separate endpoint. Surfaced as a monthly bar chart (MTTRTrendChart.vue, using the existing@unovis/vuechart setup already established byBudgetTrendChart.vue) on the work orders Overview tab.
Priority 2 — Failure trend analysis — done
WHO recommends aggregate reporting on failure patterns as part of a comprehensive maintenance system's data-analysis component. Ovahol already captured FailureCode on every fault report (internal/modules/maintenance/ dto/fault_report.go), but there was no report that aggregated by failure code over time or by device model/category — the classification data was collected and then never rolled up.
- [x] Added a failure-trend endpoint:
GetFailureTrends(internal/modules/maintenance/repository/sql/fault_report.sql) groups fault reports byfailure_codeand device model within a trailing time window (fr.reported_at >= $1, default 90 days, overridable via?days=), giving the model cross-tab directly rather than as a separate "optional" step — matches the doc's own example ("this pump model has had 8 sensor failures in 90 days") without extra client-side combination logic. Exposed atGET /fault-reports/failure-trends(internal/modules/maintenance/routes/fault_report.go), capped at the top 50 rows by count. - [x] Surfaced as a "Recurring Failure Patterns" dashboard card (
frontend/src/features/tenant/fault-report/views/ListFaultReports.vue), following the same ranked-bar-list pattern as the existing By Status/By Location panels on the same page, fed through a newfetchFailureTrendsaction onfaultReportStore(same shape as the existingfetchStats).
Priority 3 (deferred) — EHR/ERP/IoT integration
WHO's comprehensive-maintenance-system checklist includes integration with hospital IT systems (electronic health records, enterprise resource planning, IoT device telemetry) for automated data exchange and workflow sync. Nothing like this exists in Ovahol today, and it's a large, separate integration surface — not scoped in detail here. Flagging it the same way as predictive maintenance in the lifecycle checklist: worth revisiting once the more foundational gaps (inspection/calibration records, UDI) are in place, since IoT-driven predictive maintenance specifically depends on having structured inspection/calibration history to build on.
Refinements to the existing lifecycle checklist — done
Section 6.4 describes inspection and calibration in more structural detail than what this checklist's cross-reference originally scoped. Audited 2026-08-31 against the actual performance_check schema (internal/database/tenant_migrations/versions/041_performance_check.sql, built in an earlier session) and found both refinements already fully incorporated — not scoped-down as the doc assumed:
- [x] Inspection: all four WHO triggers present as a
triggercolumn CHECK-constrained toROUTINE/PRE_USE/POST_REPAIR/REGULATORY, and all four check categories present asvisual_check_passed/functional_check_passed/safety_check_passed/software_validation_passedbooleans (safety and software/firmware validation both included, not just visual/functional/accuracy). - [x] Calibration: the full four-step process is captured —
reference_standard+baseline_value(baseline measurement),adjustment_notes(adjustment),verification_value(re-test/verification), andcertificate_number(documentation) — not just a single certificate/next-due-date pair.
Already well covered — no action needed
- Preventive maintenance:
PMSchedule(frequency, next/last completed date) matches WHO's description directly. - Corrective maintenance workflow:
WorkOrder(CORRECTIVE) +FaultReport.ConvertToWorkOrdercovers diagnose → repair → restore. - Work order management/automation: status workflow, assignment, notifications, requester confirmation — this is Ovahol's most mature area relative to WHO's checklist.
- SLA / priority-driven response times: checked directly —
faultSeverityRulesininternal/modules/maintenance/service/ fault_report.goalready derives a work order priority and a due-date SLA from fault severity (critical → 1 day, high → 3, medium → 7, low → 14 days) when a fault report is converted to a work order. This is the same mechanism as WHO's priority/response-time table (Table 6). Note it's currently only applied on the fault-report-to-work-order path, not universally enforced on directly-created work orders — worth a look if that inconsistency ever causes confusion, but not a real gap against what WHO describes. - Spare parts & inventory control: checked directly —
SparePartsService(internal/modules/maintenance/service/ spare_parts.go) has full CRUD, stock movement tracking, spare-part-to- model links, per-work-order usage tracking, and a maintenance/spend summary dashboard (MaintenanceSummaryResponse). More developed than WHO's checklist item requires. - CMMS definition & scope (§7.1): WHO's own definition — centralize maintenance data, manage assets, schedule maintenance, track work orders, spare parts, recalls/alerts, nomenclature, operational status — matches Ovahol's actual feature set closely.
- Deployment model (§7.4): Ovahol is a custom-built system (Docker Compose, deployable on-prem or cloud), which WHO's own comparison table rates as the most flexible/tailored CMMS category — fully customizable regulatory compliance and integration, unlike commercial off-the-shelf options. Architecture validation, not a gap.