| name | maintainx-core-workflow-b |
| description | Execute MaintainX secondary workflow: Asset and Location management.
Use when managing equipment assets, organizing locations/facilities,
building asset hierarchies, and tracking equipment maintenance history.
Trigger with phrases like "maintainx asset", "maintainx location",
"equipment tracking", "asset management", "facility hierarchy".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Bash(curl:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
MaintainX Core Workflow B: Asset & Location Management
Overview
Manage equipment assets and locations in MaintainX. Assets represent equipment that requires maintenance; locations organize your facilities.
Prerequisites
- Completed
maintainx-install-auth setup
- Understanding of asset hierarchy concepts
- MaintainX account with asset management permissions
Asset Hierarchy Model
Organization
├── Location: Main Plant
│ ├── Sub-Location: Building A
│ │ ├── Asset: HVAC Unit A1
│ │ │ └── Sub-Asset: Compressor
│ │ └── Asset: Conveyor Line 1
│ └── Sub-Location: Building B
│ └── Asset: Boiler System
└── Location: Warehouse
└── Asset: Forklift Fleet
├── Sub-Asset: Forklift #1
└── Sub-Asset: Forklift #2
Instructions
Step 1: Query Locations
import { MaintainXClient } from '../api/maintainx-client';
interface Location {
id: string;
name: string;
address?: string;
parentId?: string;
children?: Location[];
}
async function getAllLocations(client: MaintainXClient): Promise<Location[]> {
const allLocations: Location[] = [];
let cursor: string | undefined;
do {
const response = await client.getLocations({ cursor, limit: 100 });
allLocations.push(...response.locations);
cursor = response.nextCursor || undefined;
} while (cursor);
return allLocations;
}
function buildLocationTree(locations: Location[]): [] {
locationMap = <, >();
: [] = [];
locations.( {
locationMap.(loc., { ...loc, : [] });
});
locations.( {
node = locationMap.(loc.)!;
(loc. && locationMap.(loc.)) {
parent = locationMap.(loc.)!;
parent.!.(node);
} {
rootLocations.(node);
}
});
rootLocations;
}
() {
prefix = .(indent);
locations.( {
.();
(loc. && loc.. > ) {
(loc., indent + );
}
});
}
() {
.();
locations = (client);
tree = (locations);
(tree);
}
Step 2: Query Assets
interface Asset {
id: string;
name: string;
serialNumber?: string;
model?: string;
manufacturer?: string;
status: 'OPERATIONAL' | 'NON_OPERATIONAL' | 'DECOMMISSIONED';
locationId?: string;
location?: Location;
parentAssetId?: string;
customFields?: Record<string, any>;
createdAt: string;
updatedAt: string;
}
async function getAllAssets(client: MaintainXClient): Promise<Asset[]> {
const allAssets: Asset[] = [];
let cursor: string | undefined;
do {
const response = await client.getAssets({ cursor, limit: 100 });
allAssets.push(...response.);
cursor = response. || ;
} (cursor);
allAssets;
}
(): <[]> {
response = client.({ locationId, : });
response.;
}
(): <> {
client.(assetId);
}
Step 3: Asset Analysis
interface AssetAnalysis {
totalAssets: number;
byStatus: Record<string, number>;
byLocation: Record<string, number>;
byManufacturer: Record<string, number>;
noLocation: Asset[];
}
async function analyzeAssets(client: MaintainXClient): Promise<AssetAnalysis> {
const assets = await getAllAssets(client);
const analysis: AssetAnalysis = {
totalAssets: assets.length,
byStatus: {},
byLocation: {},
byManufacturer: {},
noLocation: [],
};
assets.forEach(asset => {
const status = asset.status || 'UNKNOWN';
analysis.byStatus[status] = (analysis.byStatus[status] || 0) + 1;
if (asset.?.) {
loc = asset..;
analysis.[loc] = (analysis.[loc] || ) + ;
} {
analysis..(asset);
}
(asset.) {
analysis.[asset.] =
(analysis.[asset.] || ) + ;
}
});
analysis;
}
() {
.();
.();
.();
.(analysis.).( {
.();
});
.();
.(analysis.)
.( b[] - a[])
.(, )
.( {
.();
});
.();
.(analysis.)
.( b[] - a[])
.(, )
.( {
.();
});
(analysis.. > ) {
.();
}
}
Step 4: Asset Work Order History
async function getAssetMaintenanceHistory(
client: MaintainXClient,
assetId: string
) {
const workOrders = await client.getWorkOrders({
assetId,
limit: 100,
});
const history = {
total: workOrders.workOrders.length,
completed: workOrders.workOrders.filter(wo => wo.status === 'DONE').length,
open: workOrders.workOrders.filter(wo => wo.status === 'OPEN').length,
inProgress: workOrders.workOrders.filter(wo => wo.status === 'IN_PROGRESS').length,
recentWorkOrders: workOrders.workOrders.slice(0, 5),
};
return history;
}
async function () {
asset = (client, assetId);
history = (client, assetId);
.();
.();
.();
.();
.();
.();
.();
.();
.();
.();
.();
.();
.();
(history.. > ) {
.();
history..( {
.();
});
}
{ asset, history };
}
Step 5: Location-Based Asset View
async function getAssetsGroupedByLocation(client: MaintainXClient) {
const locations = await getAllLocations(client);
const assets = await getAllAssets(client);
const assetsByLocation: Map<string, Asset[]> = new Map();
assets.forEach(asset => {
const locId = asset.locationId || 'UNASSIGNED';
if (!assetsByLocation.has(locId)) {
assetsByLocation.set(locId, []);
}
assetsByLocation.get(locId)!.push(asset);
});
const locationMap = new Map(
locations.map(loc => [loc.id, loc.name])
);
console.log('=== Assets by Location ===\n');
assetsByLocation.forEach((locAssets, locId) => {
locName = locationMap.(locId) || locId;
.();
locAssets.( {
status = asset. === ? : ;
.();
});
});
assetsByLocation;
}
Step 6: Preventive Maintenance Planning
interface PMSchedule {
assetId: string;
assetName: string;
lastMaintenanceDate?: Date;
nextDueDate: Date;
frequency: string;
tasks: string[];
}
function generatePMSchedule(assets: Asset[]): PMSchedule[] {
const schedules: PMSchedule[] = [];
assets.forEach(asset => {
if (asset.status !== 'OPERATIONAL') return;
const name = asset.name.toLowerCase();
if (name.includes('hvac') || name.includes('air')) {
schedules.push({
assetId: asset.id,
assetName: asset.name,
nextDueDate: new Date(.() + * * * * ),
: ,
: [
,
,
,
,
,
],
});
} (name.()) {
schedules.({
: asset.,
: asset.,
: (.() + * * * * ),
: ,
: [
,
,
,
,
],
});
} (name.()) {
schedules.({
: asset.,
: asset.,
: (.() + * * * * ),
: ,
: [
,
,
,
,
],
});
}
});
schedules;
}
() {
created = [];
( schedule schedules) {
workOrder = client.({
: ,
: ,
: ,
: schedule.,
: schedule..(),
});
created.(workOrder);
}
created;
}
Output
- Complete location hierarchy view
- Asset inventory analysis
- Asset maintenance history
- Location-based asset groupings
- Preventive maintenance schedules
Error Handling
| Error | Cause | Solution |
|---|
| 404 Not Found | Invalid asset/location ID | Verify ID exists |
| Empty Results | No data or wrong filter | Check query parameters |
| Pagination issues | Missing cursor handling | Use pagination helper |
| Permission denied | Insufficient access | Verify user permissions |
Asset Status Reference
| Status | Description | Action |
|---|
| OPERATIONAL | Working normally | Schedule PM |
| NON_OPERATIONAL | Not functioning | Create repair WO |
| DECOMMISSIONED | Retired from use | Archive/remove |
Resources
Next Steps
For troubleshooting common issues, see maintainx-common-errors.