executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
maintainx-core-workflow-aExecute MaintainX primary workflow: Work Order lifecycle management. Use when creating, updating, and managing work orders through their full lifecycle, from creation to completion with all status transitions. Trigger with phrases like "maintainx work order", "create work order", "work order lifecycle", "maintenance task", "manage work orders".
Independent GitHub snapshot · Automated classification · Original documentation governs
Master the complete work order lifecycle in MaintainX - from creation through completion. Work orders are the core unit of maintenance operations.
maintainx-install-auth setup ┌─────────────┐
│ OPEN │
│ (Created) │
└──────┬──────┘
│
▼
┌─────────────┐
│ IN_PROGRESS │◄────┐
│ (Started) │ │
└──────┬──────┘ │
│ │
┌────────────┴────────────┤
│ │
▼ │
┌─────────────┐ │
│ ON_HOLD │──────────────────┘
│ (Waiting) │
└─────────────┘
│
│ (Resume or Close)
▼
┌─────────────┐
│ DONE │
│ (Completed) │
└─────────────┘
// src/workflows/work-order-lifecycle.ts
import { MaintainXClient } from '../api/maintainx-client';
interface CreateWorkOrderInput {
title: string;
description?: string;
priority: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH';
assigneeIds?: string[];
assetId?: string;
locationId?: string;
dueDate?: Date;
categories?: string[];
customFields?: Record<string, any>;
}
export async function createWorkOrder(
client: MaintainXClient,
input: CreateWorkOrderInput
) {
const workOrder = await client.createWorkOrder({
title: input.title,
description: input.description,
priority: input.priority,
assignees: input.assigneeIds,
assetId: input.assetId,
locationId: input.locationId,
dueDate: input.dueDate?.toISOString(),
});
console.log(`Created work order: ${workOrder.id}`);
console.log(`Status: ${workOrder.status}`);
console.log(`Priority: ${workOrder.priority}`);
return workOrder;
}
// Example: Create emergency repair work order
async function createEmergencyRepair(client: MaintainXClient) {
return createWorkOrder(client, {
title: 'URGENT: Conveyor Belt Failure - Line 3',
description: `
## Problem
Conveyor belt stopped unexpectedly on production line 3.
Loud grinding noise before failure.
## Impact
- Production halted
- Estimated loss: $5,000/hour
## Initial Assessment
- Belt appears worn
- Motor may need inspection
- Safety lockout applied
## Required
1. Inspect motor and belt
2. Replace worn components
3. Test operation before restart
`,
priority: 'HIGH',
assetId: 'asset_conveyor_003',
locationId: 'loc_production_floor',
});
}
// Assign technicians to work order
async function assignWorkOrder(
client: MaintainXClient,
workOrderId: string,
assigneeIds: string[]
) {
// Note: Check MaintainX API for update endpoint availability
// This may require PATCH /workorders/{id}
// For now, create new work order with assignments
// or use MaintainX web interface for assignment updates
console.log(`Assigning work order ${workOrderId} to:`, assigneeIds);
// If update endpoint available:
// return client.updateWorkOrder(workOrderId, { assignees: assigneeIds });
}
// Find available technicians
async function findAvailableTechnicians(client: MaintainXClient) {
const users = await client.getUsers({ limit: 100 });
// Filter to maintenance technicians
const technicians = users.users.filter(
user => user.role === 'TECHNICIAN' || user.role === 'MAINTENANCE'
);
return technicians;
}
// Status transition logic
type WorkOrderStatus = 'OPEN' | 'IN_PROGRESS' | 'ON_HOLD' | 'DONE';
interface StatusTransition {
from: WorkOrderStatus;
to: WorkOrderStatus;
reason?: string;
}
const validTransitions: StatusTransition[] = [
{ from: 'OPEN', to: 'IN_PROGRESS' },
{ from: 'IN_PROGRESS', to: 'ON_HOLD', reason: 'Waiting for parts' },
{ from: 'IN_PROGRESS', to: 'DONE' },
{ from: 'ON_HOLD', to: 'IN_PROGRESS' },
{ from: 'ON_HOLD', to: 'DONE' },
];
function isValidTransition(from: WorkOrderStatus, to: WorkOrderStatus): boolean {
return validTransitions.some(t => t.from === from && t.to === to);
}
async function transitionWorkOrder(
client: MaintainXClient,
workOrderId: string,
newStatus: WorkOrderStatus,
notes?: string
) {
const workOrder = await client.getWorkOrder(workOrderId);
const currentStatus = workOrder.status as WorkOrderStatus;
if (!isValidTransition(currentStatus, newStatus)) {
throw new Error(
`Invalid transition: ${currentStatus} -> ${newStatus}`
);
}
console.log(`Transitioning ${workOrderId}: ${currentStatus} -> ${newStatus}`);
if (notes) {
console.log(`Notes: ${notes}`);
}
// Update via API if available, or via MaintainX interface
// return client.updateWorkOrder(workOrderId, { status: newStatus });
}
interface CompletionReport {
workOrderId: string;
completedBy: string;
completedAt: Date;
timeSpent: number; // minutes
partsUsed: { partId: string; quantity: number }[];
notes: string;
attachments?: string[];
}
async function completeWorkOrder(
client: MaintainXClient,
report: CompletionReport
) {
console.log('=== Work Order Completion Report ===');
console.log(`Work Order: ${report.workOrderId}`);
console.log(`Completed By: ${report.completedBy}`);
console.log(`Completed At: ${report.completedAt.toISOString()}`);
console.log(`Time Spent: ${report.timeSpent} minutes`);
if (report.partsUsed.length > 0) {
console.log('Parts Used:');
report.partsUsed.forEach(p =>
console.log(` - Part ${p.partId}: ${p.quantity}`)
);
}
console.log(`Notes: ${report.notes}`);
// Mark as complete
// await transitionWorkOrder(client, report.workOrderId, 'DONE', report.notes);
return report;
}
// Complete work order workflow
async function executeMaintenanceWorkflow(client: MaintainXClient) {
// 1. Create work order
const workOrder = await createWorkOrder(client, {
title: 'Scheduled PM - HVAC Unit Inspection',
description: `
Monthly preventive maintenance inspection for HVAC unit.
## Checklist
- [ ] Check filters
- [ ] Inspect belts
- [ ] Verify refrigerant levels
- [ ] Clean coils
- [ ] Test thermostat
- [ ] Document readings
`,
priority: 'MEDIUM',
assetId: 'asset_hvac_001',
locationId: 'loc_building_a',
});
console.log(`\n1. Work order created: ${workOrder.id}`);
// 2. Assign to technician
const technicians = await findAvailableTechnicians(client);
if (technicians.length > 0) {
console.log(`\n2. Would assign to: ${technicians[0].firstName} ${technicians[0].lastName}`);
}
// 3. Start work (transition to IN_PROGRESS)
console.log('\n3. Transitioning to IN_PROGRESS');
// await transitionWorkOrder(client, workOrder.id, 'IN_PROGRESS');
// 4. Complete work
console.log('\n4. Completing work order');
await completeWorkOrder(client, {
workOrderId: workOrder.id,
completedBy: 'tech_001',
completedAt: new Date(),
timeSpent: 45,
partsUsed: [
{ partId: 'part_filter_20x25', quantity: 2 },
],
notes: 'Replaced filters. All readings normal. Next PM due in 30 days.',
});
return workOrder;
}
// Find work orders by various criteria
async function queryWorkOrders(client: MaintainXClient) {
// Open high-priority work orders
const urgent = await client.getWorkOrders({
status: 'OPEN',
priority: 'HIGH',
limit: 20,
});
console.log(`Urgent open: ${urgent.workOrders.length}`);
// Work orders for specific asset
const assetWOs = await client.getWorkOrders({
assetId: 'asset_pump_001',
limit: 50,
});
console.log(`Asset work orders: ${assetWOs.workOrders.length}`);
// Overdue work orders
const today = new Date().toISOString();
const overdue = await client.getWorkOrders({
status: 'OPEN',
// Filter by dueDate in application logic
});
const overdueWOs = overdue.workOrders.filter(
wo => wo.dueDate && new Date(wo.dueDate) < new Date()
);
console.log(`Overdue: ${overdueWOs.length}`);
return { urgent, assetWOs, overdueWOs };
}
| Error | Cause | Solution |
|---|---|---|
| 400 Bad Request | Missing title | Ensure title field is provided |
| 404 Not Found | Invalid asset/location ID | Verify IDs exist in system |
| 403 Forbidden | Insufficient permissions | Check user role and plan tier |
| Invalid transition | Wrong status flow | Follow valid transition paths |
| Field | Required | Description |
|---|---|---|
| title | Yes | Short description of task |
| description | No | Detailed instructions |
| priority | No | NONE, LOW, MEDIUM, HIGH |
| status | Auto | OPEN, IN_PROGRESS, ON_HOLD, DONE |
| assignees | No | Array of user IDs |
| assetId | No | Associated equipment |
| locationId | No | Facility/area |
| dueDate | No | ISO 8601 timestamp |
For asset and location management, see maintainx-core-workflow-b.