Asset Management
An Asset in ianaiERP represents a physical thing the business owns — a press, a folder, a forklift, a server. The original Asset is an Accounting entity (acquisition cost, depreciation, disposal). The EMS suite extends the same Asset row with operational fields: its work center, parent asset, runtime status, critical-asset flag, operating hours, and service dates.
There's only one Asset row per physical asset. The Accounting view (/asset) and the Equipment Detail view (/equipment/:assetId) both render the same underlying record from different angles.
Where it lives
- Create / edit / list:
/asset(Accounting view) - Operational detail:
/equipment/:assetId(Equipment view) - The
+ New Assetbutton on/assetopens the same form for both views.
Permissions:
| Action | Needs |
|---|---|
| View asset list / accounting fields | asset_read |
| Edit asset (any field) | asset_write |
| Update runtime status only | equipmentstatus_write (operator-level — does NOT grant accounting edits) |
| Move asset to a different parent | asset_write (uses MoveAssetSubtree RPC) |
The split lets the floor operator flip an asset DOWN without giving them the right to change its acquisition cost.
The new EMS fields
When you open the Asset form, a Equipment Management section appears alongside the accounting fields. None of these are required, so existing assets stay valid without backfill.
Work Center (work_center)
The work center this asset operates within. One WC has many assets; one asset belongs to at most one WC at a time.
- Picker: searchable FetchSelect from
/support/workcenter. - Used by:
- Equipment Hub status board grouping.
- The 5-minute cron that rolls up the WC's
current_runtime_statusfrom its critical assets. - The CAPA calculation (planned PM on a critical asset debits its WC's available capacity).
Leave blank for assets that aren't on the production floor (office equipment, vehicles).
Parent Asset (parent_asset) + hierarchy_depth
A self-referencing pointer for multi-level hierarchies like Plant → Line → Machine → Subassembly. Picker is the recursive Asset Tree Picker modal.
- Depth is capped at 5 (
Plant > Line > Press > Section > Subassembly). Deeper trees are rejected at the API level. - The system prevents cycles: you can't make an ancestor a child of one of its descendants.
- The
hierarchy_depthfield is computed automatically based on the parent chain. You can't set it directly. - The
child_countfield is read-only and shows how many direct children this asset has.
Moving a subtree
On the Equipment Detail page, the Move in hierarchy button opens an Asset Tree Picker. Pick the new parent (or "no parent" for a root) and the entire subtree is atomically re-rooted. hierarchy_depth is recomputed for every descendant in one transaction.
Rollup status
The 5-minute cron walks the tree bottom-up: a parent's effective runtime status is the worst of its descendants. The Equipment Hub status board's "Rollup view" uses this so a plant-level card can show 3 descendants DOWN even when the parent itself doesn't directly produce.
The critical_asset flag (below) controls whether a child's downtime is allowed to propagate to its WC's status. Hierarchy alone doesn't make a child critical.
Critical Asset (critical_asset)
Boolean. When true:
- The asset's DOWN/MAINTENANCE status does propagate to its work center's runtime status.
- Planned maintenance on this asset does subtract from the WC's CAPA-available minutes.
asset_status_changedSSE events are flagged with higher severity.
Use this for the bottleneck machine on each line. Press goes down → line stops. Folder goes down → line keeps running.
Defaults to false. Set on each line's primary machine after creating the asset.
Runtime Status (runtime_status)
The current operational state of the asset. One of:
RUNNING— currently producingSETUP— changeover or warm-upIDLE— operational but not producing right nowDOWN— unplanned downtime (breakdown, fault)MAINTENANCE— taken down for planned maintenance
Defaults to IDLE for new assets.
Changed by:
- Operator action on the Equipment Hub status board (Runtime Status Quick Menu — see Runtime Status).
StartMaintenanceEventRPC flips it toMAINTENANCEwhile a planned event runs.CompleteMaintenanceEventRPC flips it back toRUNNING(or whatever it was before).- Work-order operation state when integrated (start ops → asset goes
RUNNING; end ops → asset goesIDLE).
A status change broadcasts an asset_status_changed SSE event that updates the hub in real time and triggers the chip-pulse animation.
Total Operating Hours (total_operating_hours)
Lifetime running hours. Used by RUNTIME_HOURS-type PM schedules to know when the next service is due.
- In v1 this is manually updated (operator types in the current reading at the end of a shift, or maintenance enters it after service).
- When MFI/PLC sensor integration ships in a later version, this will be auto-updated from machine counters.
- Logged as an
AssetTransactionof typeMAINTENANCE(orINSPECTIONif just reading the meter).
Last Inspection (last_inspection_date)
Date of the most recent inspection. Updated automatically when a MaintenanceEvent of type INSPECTION is completed.
Next Service (next_service_date)
When the next scheduled service is due. Updated automatically when a MaintenanceSchedule is created or its last_done_at rolls forward. The earliest next_due_at across all schedules for this asset is mirrored here for quick display.
Warranty Until (warranty_until)
Manufacturer warranty expiration. Surfaced on the Equipment Detail Overview tab so technicians know whether to repair in-house or escalate to the OEM.
Assigned Workforce (assigned_workforce)
The primary operator or technician responsible for this asset. Picker is a FetchSelect from /support/workforce. Used for notifications (maintenance_due events route to this person) and reporting.
Equipment Detail page
/equipment/:assetId is the operational view of a single asset. It complements the Accounting view at /asset/:assetId.
Header actions:
- Edit Asset — opens the same AssetFormModal as
/asset. - Move in hierarchy — opens the Asset Tree Picker to re-parent this asset.
- Runtime Status Quick Menu — kebab-style menu to flip status (
RUNNING/SETUP/IDLE/DOWN/MAINTENANCE). Going toDOWNprompts for a reason text. - Breadcrumb — ancestor chain shown at the top (
Plant > Line A > Press > Print Head). Each segment links to that ancestor's detail page.
Tabs:
| Tab | Content |
|---|---|
| Overview | KPIs (MTBF, MTTR, total downtime hours YTD, repair cost YTD), warranty, last inspection. Toggle "include descendants" to roll up child stats. |
| Maintenance History | Time-ordered list of MaintenanceEvent rows linked to this asset. Filterable by event type (PM/Repair/Breakdown/etc.). |
| PM Schedule | All MaintenanceSchedule rows targeting this asset. One-click "Mark Done" inline. |
| Spare Parts | All SparePartLink rows pointing at this asset. Stock level + usage rate visible. |
| Children | Tree table of descendant assets, each with their runtime-status chip and current workorder. |
| WorkOrders | Open + recent work orders that route through this asset's WC. |
| Custom Fields | Tenant-configured custom-field values, including calculation fields. |
Asset Tree Picker
Used wherever a parent asset needs to be selected (asset form, Move in Hierarchy). A modal showing the full asset tree with:
- Search box to filter by name.
- Expand / collapse rows.
- Disabled selection on the current asset and its descendants (would create a cycle).
- A "No parent" option to make the asset a root.
Setup recipe (typical paper plant)
Plant: "Sandpoint Facility" (hierarchy_depth=0)
├── Line: "Press Line A" (hierarchy_depth=1, critical_asset=false)
│ ├── Machine: "Heidelberg Press 1" (hierarchy_depth=2, critical_asset=true, WC=Press Line A)
│ │ ├── Subassembly: "Print Head" (hierarchy_depth=3, critical_asset=false)
│ │ └── Subassembly: "Feeder" (hierarchy_depth=3, critical_asset=false)
│ └── Machine: "Folder Unit 7" (hierarchy_depth=2, critical_asset=true, WC=Folder Station)
└── Bench: "Manual Cutting Bench" (hierarchy_depth=1, critical_asset=false, WC=Cutting Bench)
- Only the leaf machines are
critical_asset=true. - Sub-assemblies are tracked for maintenance/cost rollup but don't independently floor their parent's WC.
- The Plant and Line are organizational nodes only.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Can't pick parent in form | hierarchy_depth would exceed 5, OR you're picking an ancestor (would cycle). Picker disables both. |
| Asset doesn't show on Equipment Hub status board | No work_center set, OR the asset is at hierarchy_depth > 0 and you're in Rollup view (which only shows roots). |
| WC stays GREEN even when critical asset is DOWN | Asset isn't flagged critical_asset = true. Open the asset form and tick the box. |
| Status changes aren't appearing on the hub | SSE not connected (check the websocket/SSE in browser devtools), OR the equipmentstatus_write permission is missing for the user trying to change it. |
| MTBF / MTTR are blank | No MaintenanceEvent rows of type BREAKDOWN or REPAIR yet. They need at least two events to compute mean-time stats. |