TGM Expert provides comprehensive maintenance management through a unified Maintenance Record system, along with failures, preventive maintenance planning, and root cause analysis.
Table of Contents¶
- Overview
- Maintenance Records
- Record Types
- API Endpoints
- Backward Compatibility
- Notes & Chat
- Failures
- Maintenance Plans
- Root Cause Analysis
- SLA & Reminders
- Database Schema
Overview¶
Unified Maintenance Record Model¶
As of V86, inspections, interventions, and work orders have been unified into a single maintenance_records table with a record_type discriminator. This simplifies the data model, reduces code duplication, and provides a consistent API surface.
MaintenanceRecord
┌─────────────────┐
│ record_type: │
│ INSPECTION or │
│ INTERVENTION │
└────────┬────────┘
│
┌─────────────┼─────────────┐
│ │ │
Inspections Interventions Shared
(diagnostic) (corrective) fields
Maintenance Workflow¶
Maintenance Plan (scheduled)
│
▼
MaintenanceRecord (INSPECTION)
│
Issue Found? ────────> Failure Record
│ │
▼ ▼
MaintenanceRecord RCA (if major)
(INTERVENTION)
│
▼
Completed
Maintenance Types¶
| Type | Description |
|---|---|
| Preventive | Scheduled, time-based maintenance |
| Predictive | Condition-based, using sensor data |
| Corrective | Reactive, fixing failures |
| Emergency | Urgent unplanned repairs |
Maintenance Records¶
Entity Structure¶
The MaintenanceRecord entity unifies what were previously separate Inspection, Intervention, and WorkOrder entities. A recordType field (INSPECTION or INTERVENTION) distinguishes the type.
{
"id": 1,
"recordType": "INSPECTION",
"reportNumber": "INS-2026-0001",
"title": "Monthly Turbine Inspection",
"status": "OPEN",
"priority": "MEDIUM",
"maintenanceType": "PREVENTIVE",
"plannedDate": "2026-03-01",
"startDate": null,
"scheduleDate": "2026-02-25",
"creationDate": "2026-02-20T10:00:00Z",
"costAllocation": "CAPEX",
"actionPlan": "Follow standard turbine inspection checklist",
"comments": null,
"relevantInformation": "Unit has been running continuously for 6 months",
"recommendations": null,
"estimatedRevenueShortFall": 0,
"isRiskComponents": false,
"productInterruption": "NONE",
"unitStatus": "RUNNING",
"operatingMode": "NORMAL",
"waterLevel": "NORMAL",
"systemIsolationCompleted": false,
"inspectionType": "ROUTINE",
"inspectionNature": "VISUAL",
"inspectionLevel": "LEVEL_1",
"reasonForInspection": "Scheduled quarterly inspection",
"customFields": {
"weatherConditions": "Clear"
},
"units": [{"id": 100, "name": "Turbine Unit 1"}],
"users": [{"id": 50, "name": "John Smith"}],
"initiators": [{"id": 45, "name": "Operations Manager"}],
"departments": [{"id": 10, "name": "Mechanical"}],
"subAssemblies": [],
"components": [{"id": 1000, "name": "Governor Valve"}],
"createdAt": "2026-02-20T10:00:00Z",
"updatedAt": "2026-02-20T10:00:00Z"
}
Shared Fields (All Record Types)¶
| Field | Type | Description |
|---|---|---|
id |
Long | Unique identifier |
recordType |
Enum | INSPECTION or INTERVENTION |
reportNumber |
String | Unique report number (auto-generated) |
title |
String | Title of the maintenance record |
status |
Enum | Current status (see Status section) |
priority |
Enum | Priority level |
maintenanceType |
String | Preventive, Corrective, etc. |
plannedDate |
Date | Planned execution date |
startDate |
Date | Actual start date |
scheduleDate |
Date | Scheduled date |
creationDate |
DateTime | When the record was created |
costAllocation |
String | Cost allocation category |
actionPlan |
Text | Description of planned actions |
comments |
Text | General comments |
relevantInformation |
Text | Relevant context |
recommendations |
Text | Post-completion recommendations |
estimatedRevenueShortFall |
Decimal | Estimated revenue impact |
isRiskComponents |
Boolean | Whether risk components are involved |
productInterruption |
String | Product interruption status |
unitStatus |
String | Unit status during maintenance |
operatingMode |
String | Operating mode during maintenance |
waterLevel |
String | Water level (hydro-specific) |
systemIsolationCompleted |
Boolean | Whether system isolation is done |
sevenDaysReminderSent |
Boolean | 7-day reminder flag |
threeDaysReminderSent |
Boolean | 3-day reminder flag |
sameDayReminderSent |
Boolean | Same-day reminder flag |
customFields |
JSONB | Custom field values |
deleted |
Boolean | Soft-delete flag |
Inspection-Specific Fields¶
These fields are only populated when recordType = INSPECTION:
| Field | Type | Description |
|---|---|---|
inspectionType |
String | Type of inspection (ROUTINE, PERIODIC, etc.) |
inspectionNature |
String | Nature of the inspection |
inspectionLevel |
String | Inspection level |
reasonForInspection |
String | Reason for the inspection |
calendarPlanning |
String | Calendar planning info |
meteringParameter1-5 |
String | Metering parameter readings |
periodicity |
String | Inspection periodicity |
periodicityHash |
String | Hash for periodicity detection |
hasardAnalysisCompleted |
Boolean | JSA completed |
hasardAnalysisJsaNumber |
String | JSA document number |
maintenanceJsa |
String | Maintenance JSA info |
maintenanceTimes |
String | Maintenance time details |
processedIndex |
Integer | Processed index for batch processing |
initialInspection |
Boolean | Whether this is an initial inspection |
woGroupInformation |
String | Work order group info |
scheduleFollowUp |
String | Follow-up scheduling info |
locationId |
Long | FK to locations table |
Intervention-Specific Fields¶
These fields are only populated when recordType = INTERVENTION:
| Field | Type | Description |
|---|---|---|
reasonForIntervention |
String | Reason for the intervention |
eventNature |
String | Nature of the triggering event |
eventDescriptionType |
String | Event description type |
plannedOutageDuration |
String | Planned outage duration |
isProjectRelated |
Boolean | Whether project-related |
isMultiTeamsWork |
Boolean | Whether multiple teams involved |
immediate |
Boolean | Whether this is an emergency intervention |
interventionJsa |
String | Intervention JSA info |
Relationships (Link Tables)¶
| Relationship | Link Table | Description |
|---|---|---|
| Units | maintenance_records_unit_links |
Units being maintained |
| Users | maintenance_records_users_links |
Assigned technicians |
| Initiators | maintenance_records_initiator_links |
Who requested the work |
| Departments | maintenance_records_departments_links |
Involved departments |
| Sub-assemblies | maintenance_records_sub_assembly_links |
Sub-assemblies involved |
| Components | maintenance_records_components_links |
Components being worked on |
| Inspection Components | inspection_components_maintenance_record_links |
Inspection component results |
Record Types¶
INSPECTION¶
Inspections are diagnostic maintenance records. They represent scheduled or unplanned assessments of equipment condition.
Use cases: - Routine periodic inspections - Condition-based assessments - Pre/post-outage inspections - Regulatory compliance checks
INTERVENTION¶
Interventions are corrective maintenance records. They represent actions taken to fix, maintain, or improve equipment.
Use cases: - Corrective repairs - Preventive maintenance tasks - Emergency repairs - Equipment improvements
API Endpoints¶
Primary Endpoint: /api/maintenance-records¶
This is the primary unified endpoint for all maintenance records.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/maintenance-records |
List all maintenance records |
| GET | /api/maintenance-records/{id} |
Get a specific record |
| POST | /api/maintenance-records |
Create a record |
| PUT | /api/maintenance-records/{id} |
Update a record |
| DELETE | /api/maintenance-records/{id} |
Delete a record |
Filtering¶
Use query parameters to filter results. The GenericSpecificationBuilder supports any field:
# Get all inspections
GET /api/maintenance-records?recordType=INSPECTION
# Get all open interventions
GET /api/maintenance-records?recordType=INTERVENTION&status=OPEN
# Get high-priority records for a specific unit
GET /api/maintenance-records?priority=HIGH&units.id=100
# Pagination
GET /api/maintenance-records?page=0&size=25&sort=createdAt,desc
Create an Inspection¶
curl -X POST https://api.tgm-expert.com/api/maintenance-records \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"recordType": "INSPECTION",
"title": "Quarterly Turbine Inspection",
"maintenanceType": "PREVENTIVE",
"priority": "MEDIUM",
"plannedDate": "2026-03-01",
"inspectionType": "ROUTINE",
"inspectionNature": "VISUAL",
"reasonForInspection": "Scheduled quarterly inspection"
}'
Create an Intervention¶
curl -X POST https://api.tgm-expert.com/api/maintenance-records \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"recordType": "INTERVENTION",
"title": "Seal Replacement - Unit 1",
"maintenanceType": "CORRECTIVE",
"priority": "HIGH",
"plannedDate": "2026-02-10",
"reasonForIntervention": "Worn seals detected during inspection",
"immediate": false
}'
Response Format¶
{
"data": {
"id": 1,
"recordType": "INSPECTION",
"reportNumber": "INS-2026-0001",
"title": "Quarterly Turbine Inspection",
"status": "OPEN",
...
},
"message": "Success"
}
Paginated List Response¶
{
"data": [
{"id": 1, "recordType": "INSPECTION", ...},
{"id": 2, "recordType": "INTERVENTION", ...}
],
"total": 150,
"page": 0,
"size": 25
}
Backward Compatibility¶
Legacy API Endpoints (Deprecated)¶
The following endpoints are maintained for backward compatibility. They delegate to the unified MaintenanceRecordService with automatic recordType filtering.
| Legacy Endpoint | Maps To | Auto-filter |
|---|---|---|
GET /api/inspections |
GET /api/maintenance-records?recordType=INSPECTION |
recordType=INSPECTION |
POST /api/inspections |
POST /api/maintenance-records |
Forces recordType=INSPECTION |
GET /api/interventions |
GET /api/maintenance-records?recordType=INTERVENTION |
recordType=INTERVENTION |
POST /api/interventions |
POST /api/maintenance-records |
Forces recordType=INTERVENTION |
These endpoints will be removed in a future release. Migrate to /api/maintenance-records as soon as possible.
Database Views¶
SQL views are created for backward compatibility with raw SQL queries, reports, and external tools:
-- Returns only inspection-type records with legacy column names
SELECT * FROM inspections;
-- Returns only intervention-type records with legacy column names
SELECT * FROM interventions;
Link table views are also available:
- inspections_unit_links, inspections_users_links, etc.
- interventions_unit_links, interventions_users_links, etc.
These views are read-only. All writes go through maintenance_records directly.
Entity Type Normalization¶
For polymorphic references (Notes, SLA breach records), the backend normalizes legacy entity type strings:
| Legacy Value | Normalized To |
|---|---|
Inspection |
MaintenanceRecord |
Intervention |
MaintenanceRecord |
WorkOrder |
MaintenanceRecord |
The NoteService automatically converts these values when querying, so clients using old entity types will still retrieve the correct notes.
Backup Tables¶
The original tables are preserved as backups after the V86 migration:
- inspections_backup_v86
- interventions_backup_v86
- All link tables: *_backup_v86
These will be dropped in a future release after confirming all systems have migrated.
Migration Traceability¶
Every migrated record in maintenance_records has:
- legacy_type — 'inspection' or 'intervention' (the original table)
- legacy_id — the original ID from the source table
Inspection records preserve their original IDs. Intervention records receive new auto-generated IDs (use legacy_id to trace back to the original interventions table).
Notes & Chat¶
Notes¶
Notes are polymorphic — they reference a maintenance record via entity_type + entity_id.
# Get notes for a maintenance record
GET /api/notes?entityType=MaintenanceRecord&entityId=1
# Get note count
GET /api/notes/count-by-entity?entityType=MaintenanceRecord&entityId=1
# Create a note
POST /api/notes
{
"entityType": "MaintenanceRecord",
"entityId": 1,
"content": "Seal inspection completed. Minor wear detected.",
"isPrivate": false
}
The author is automatically set from the authenticated user's security context.
Chat¶
Chat conversations can be linked to a maintenance record via the maintenance_record_id column on chat_conversations.
# Get conversation for a maintenance record
GET /api/chat/conversations/maintenance-record/{maintenanceRecordId}
# Create a conversation linked to a maintenance record
POST /api/chat/conversations
{
"name": "Turbine Inspection Discussion",
"type": "GROUP",
"maintenanceRecordId": 1,
"participantIds": [50, 55]
}
Failures¶
Failure Entity¶
{
"id": 1,
"title": "Governor Valve Seal Leak",
"type": "MECHANICAL",
"severity": "MODERATE",
"status": "RESOLVED",
"unit": {"id": 100, "name": "Turbine Unit 1"},
"component": {"id": 1000, "name": "Governor Valve"},
"occurredAt": "2026-02-05T14:30:00Z",
"detectedAt": "2026-02-05T14:35:00Z",
"resolvedAt": "2026-02-10T15:00:00Z",
"downtimeHours": 120,
"impact": "Unit tripped, unplanned outage",
"resolution": "Replaced worn seals, unit returned to service",
"estimatedLoss": 50000.00
}
Failure Types¶
| Type | Description |
|---|---|
MECHANICAL |
Mechanical failure |
ELECTRICAL |
Electrical failure |
HYDRAULIC |
Hydraulic system failure |
INSTRUMENTATION |
Sensor/control failure |
STRUCTURAL |
Structural damage |
HUMAN_ERROR |
Operator error |
EXTERNAL |
External factors |
Failure Severity¶
| Severity | Description |
|---|---|
MINOR |
No operational impact |
MODERATE |
Reduced performance |
MAJOR |
Significant impact |
CRITICAL |
Complete failure |
API Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/failures |
List failures |
| GET | /api/failures/{id} |
Get failure |
| POST | /api/failures |
Record failure |
| PUT | /api/failures/{id} |
Update failure |
| DELETE | /api/failures/{id} |
Delete failure |
| POST | /api/failures/{id}/resolve |
Mark resolved |
Record Failure¶
curl -X POST https://api.tgm-expert.com/api/failures \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Governor Valve Seal Leak",
"type": "MECHANICAL",
"severity": "MODERATE",
"unitId": 100,
"componentId": 1000,
"occurredAt": "2026-02-05T14:30:00Z",
"impact": "Unit tripped, unplanned outage",
"causeId": 5
}'
Maintenance Plans¶
Maintenance plans define recurring preventive maintenance schedules. They can auto-generate MaintenanceRecord entries when due.
Maintenance Plan Entity¶
{
"id": 1,
"name": "Quarterly Turbine Maintenance",
"type": "PREVENTIVE",
"frequency": "QUARTERLY",
"status": "ACTIVE",
"unit": {"id": 100, "name": "Turbine Unit 1"},
"components": [
{"id": 1000, "name": "Governor Valve"},
{"id": 1001, "name": "Servo Motor"}
],
"tasks": [
"Inspect seals and gaskets",
"Check oil levels",
"Test emergency stop",
"Calibrate sensors"
],
"estimatedDuration": 8,
"estimatedCost": 5000.00,
"lastExecutedAt": "2025-12-15",
"nextDueAt": "2026-03-15",
"leadTimeInDays": 7,
"assignedTo": {"id": 55, "name": "Mike Johnson"}
}
Plan Frequencies¶
| Frequency | Description |
|---|---|
DAILY |
Every day |
WEEKLY |
Every week |
BIWEEKLY |
Every 2 weeks |
MONTHLY |
Every month |
QUARTERLY |
Every 3 months |
SEMIANNUAL |
Every 6 months |
ANNUAL |
Every year |
CUSTOM |
Custom interval |
Plan-to-Record Connection¶
When a maintenance plan is executed (either manually or by the scheduler), it creates a MaintenanceRecord with:
- recordType derived from the plan type (PREVENTIVE → INSPECTION, CORRECTIVE → INTERVENTION)
- maintenancePlanId FK linking back to the originating plan
API Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/maintenance-plans |
List plans |
| GET | /api/maintenance-plans/{id} |
Get plan |
| POST | /api/maintenance-plans |
Create plan |
| PUT | /api/maintenance-plans/{id} |
Update plan |
| DELETE | /api/maintenance-plans/{id} |
Delete plan |
| GET | /api/maintenance-plans/due |
Get due plans |
| POST | /api/maintenance-plans/{id}/execute |
Execute plan |
Create Plan¶
curl -X POST https://api.tgm-expert.com/api/maintenance-plans \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Monthly Oil Analysis",
"type": "PREDICTIVE",
"frequency": "MONTHLY",
"unitId": 100,
"componentIds": [1000, 1001],
"tasks": [
"Collect oil sample",
"Send to lab",
"Review results"
],
"estimatedDuration": 2,
"assignedToId": 55,
"leadTimeInDays": 3
}'
Root Cause Analysis¶
RCA Entity¶
{
"id": 10,
"title": "Governor Valve Seal Failure Analysis",
"status": "IN_PROGRESS",
"failure": {"id": 1, "title": "Governor Valve Seal Leak"},
"methodology": "5_WHY",
"team": [
{"id": 50, "name": "John Smith", "role": "Lead"},
{"id": 55, "name": "Mike Johnson", "role": "Member"}
],
"startedAt": "2026-02-11",
"dueDate": "2026-02-25",
"rootCauses": [
{
"cause": "Seal material degradation",
"category": "MATERIAL",
"evidence": "Visual inspection showed hardened seal material"
}
],
"correctiveActions": [
{
"action": "Replace with upgraded seal material",
"assignedTo": {"id": 55},
"dueDate": "2026-03-01",
"status": "IN_PROGRESS"
}
],
"preventiveActions": [
{
"action": "Update maintenance plan to include seal inspection",
"assignedTo": {"id": 50},
"dueDate": "2026-02-28",
"status": "PENDING"
}
],
"lessons": "Seal materials should be reviewed for compatibility with operating conditions"
}
RCA Methodologies¶
| Method | Description |
|---|---|
5_WHY |
5 Whys analysis |
FISHBONE |
Ishikawa diagram |
FMEA |
Failure Mode and Effects |
FTA |
Fault Tree Analysis |
PARETO |
Pareto analysis |
API Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/rca |
List RCAs |
| GET | /api/rca/{id} |
Get RCA |
| POST | /api/rca |
Create RCA |
| PUT | /api/rca/{id} |
Update RCA |
| POST | /api/rca/{id}/causes |
Add root cause |
| POST | /api/rca/{id}/actions |
Add corrective action |
| POST | /api/rca/{id}/complete |
Complete RCA |
SLA & Reminders¶
Service Level Agreements¶
SLAs can be configured for maintenance records. The entity type for SLA breach records is MAINTENANCE_RECORD.
{
"id": 1,
"name": "Critical Inspection SLA",
"entityType": "MAINTENANCE_RECORD",
"targetResolutionHours": 24,
"warningThresholdHours": 18,
"priority": "CRITICAL"
}
The SlaBreachDetectionScheduler monitors all maintenance records and creates breach records when SLA thresholds are exceeded.
Automated Reminders¶
The MaintenanceReminderScheduler sends reminders at three intervals:
- 7 days before planned date (sevenDaysReminderSent)
- 3 days before planned date (threeDaysReminderSent)
- Same day as planned date (sameDayReminderSent)
The OverdueMaintenanceScheduler checks for records past their planned date and creates notifications.
Database Schema¶
Core Table: maintenance_records¶
CREATE TABLE maintenance_records (
id BIGSERIAL PRIMARY KEY,
record_type VARCHAR(20) NOT NULL, -- 'INSPECTION' or 'INTERVENTION'
report_number VARCHAR(255) UNIQUE,
title VARCHAR(500),
status VARCHAR(50),
priority VARCHAR(50),
maintenance_type VARCHAR(100),
planned_date DATE,
start_date DATE,
schedule_date DATE,
creation_date TIMESTAMP(6),
-- Shared fields
cost_allocation VARCHAR(255),
action_plan TEXT,
comments TEXT,
relevant_information TEXT,
recommendations TEXT,
estimated_revenue_short_fall DECIMAL,
is_risk_components BOOLEAN DEFAULT FALSE,
product_interruption VARCHAR(255),
unit_status VARCHAR(100),
operating_mode VARCHAR(100),
water_level VARCHAR(100),
system_isolation_completed BOOLEAN DEFAULT FALSE,
seven_days_reminder_sent BOOLEAN DEFAULT FALSE,
three_days_reminder_sent BOOLEAN DEFAULT FALSE,
same_day_reminder_sent BOOLEAN DEFAULT FALSE,
custom_fields JSONB,
deleted BOOLEAN DEFAULT FALSE,
-- Inspection-specific (NULL for interventions)
inspection_type VARCHAR(100),
inspection_nature VARCHAR(100),
inspection_level VARCHAR(100),
reason_for_inspection TEXT,
calendar_planning VARCHAR(255),
metering_parameter_1 VARCHAR(255),
metering_parameter_2 VARCHAR(255),
metering_parameter_3 VARCHAR(255),
metering_parameter_4 VARCHAR(255),
metering_parameter_5 VARCHAR(255),
periodicity VARCHAR(255),
periodicity_hash VARCHAR(255),
hasard_analysis_completed BOOLEAN,
hasard_analysis_jsa_number VARCHAR(255),
maintenance_jsa VARCHAR(255),
maintenance_times VARCHAR(255),
processed_index INTEGER,
initial_inspection BOOLEAN,
wo_group_information VARCHAR(500),
schedule_follow_up VARCHAR(255),
location_id BIGINT REFERENCES locations(id),
-- Intervention-specific (NULL for inspections)
reason_for_intervention TEXT,
event_nature VARCHAR(255),
event_description_type VARCHAR(255),
planned_outage_duration VARCHAR(255),
is_project_related BOOLEAN,
is_multi_teams_work BOOLEAN,
immediate BOOLEAN,
intervention_jsa VARCHAR(255),
-- Traceability
legacy_type VARCHAR(50), -- 'inspection' or 'intervention'
legacy_id BIGINT, -- original ID from source table
maintenance_plan_id BIGINT REFERENCES maintenance_plans(id),
-- Audit
created_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
published_at TIMESTAMP(6),
created_by_id BIGINT,
updated_by_id BIGINT
);
Link Tables¶
-- Units associated with a maintenance record
CREATE TABLE maintenance_records_unit_links (
id BIGSERIAL PRIMARY KEY,
maintenance_record_id BIGINT REFERENCES maintenance_records(id),
unit_id BIGINT REFERENCES units(id)
);
-- Same pattern for:
-- maintenance_records_users_links (user_id)
-- maintenance_records_initiator_links (user_id)
-- maintenance_records_departments_links (department_id)
-- maintenance_records_sub_assembly_links (sub_assembly_id)
-- maintenance_records_components_links (component_id)
-- inspection_components_maintenance_record_links (inspection_component_id)
Key Indexes¶
CREATE INDEX idx_maintenance_records_record_type ON maintenance_records(record_type);
CREATE INDEX idx_maintenance_records_status ON maintenance_records(status);
CREATE INDEX idx_maintenance_records_planned_date ON maintenance_records(planned_date);
CREATE INDEX idx_maintenance_records_report_number ON maintenance_records(report_number);
CREATE INDEX idx_maintenance_records_legacy ON maintenance_records(legacy_type, legacy_id);
Webhook Events¶
| Event | Description |
|---|---|
MAINTENANCE_RECORD_CREATED |
A new record was created |
MAINTENANCE_RECORD_UPDATED |
A record was updated |
MAINTENANCE_RECORD_DELETED |
A record was deleted |
Legacy events (INSPECTION_CREATED, INTERVENTION_CREATED, etc.) are deprecated aliases.
Corrective Actions¶
Corrective actions link to maintenance records (interventions) via maintenance_record_id:
ALTER TABLE corrective_actions
ADD COLUMN maintenance_record_id BIGINT REFERENCES maintenance_records(id);
Rollback¶
A revert script is available at docs/revert_v86_maintenance_records.sql. This script:
1. Drops backward-compatible views
2. Restores polymorphic references (notes, SLA breach records) to legacy entity types
3. Drops unified link tables and maintenance_records table
4. Restores backup tables to original names
5. Removes V86 from Flyway history
Important: After running the revert script, all Spring Boot, Flutter SDK, Angular SDK, and Flutter Inspector code must also be reverted to use the separate Inspection/Intervention entities.