Asset Management

Why this is a runtime problem, not a CRUD problem

Fixed assets look deceptively simple: a list of laptops, vehicles, machines and buildings with serial numbers. The reality is harder. Each asset carries a depreciation schedule that must reconcile to the general ledger, a custody chain that survives reorganisations, a maintenance plan whose cost history feeds total-cost-of-ownership reports, and a disposal path that auditors can replay. The flow is acquire → activate → transfer → maintain → depreciate → dispose — and every transition must be permissioned, scoped to the right organisation and site, and recorded with the actor, timestamp, and reason.

A spreadsheet captures the register and immediately drifts. A data-app builder produces a list view but cannot encode "only finance may see net book value" or "cross-org transfer requires a delegated permission". AuraBoot models the asset master, the depreciation ledger and the maintenance order as first-class entities; the lifecycle is a state machine whose transitions are commands; permissions, scopes and field masks are evaluated by the runtime before any handler runs.

Data model summary

The Asset Management plugin ships four cooperating models:

  • am_asset — Fixed asset master. States draft → in_use → idle → under_maintenance → disposed. Carries asset_code, original value, current net value, depreciation method, useful life, warranty expiry, current custodian, department, location and serial number.
  • am_location — Structured location tree (site → building → floor → room) referenced by am_asset.location_id; replaces free-text location for plants that need spatial reporting.
  • am_maintenance_order — Work order against an asset. States pending → in_progress → completed; types routine | repair | overhaul | inspection; carries scheduled date, actual cost, technician, and next-due date.
  • am_depreciation_schedule — Periodic depreciation ledger. One row per asset per period (2026-05), with this-period charge, accumulated total, and post-period net value. Drives the current_value rollup on am_asset.

The plugin declares no external dependencies — it installs cleanly on any AuraBoot instance and integrates with Finance (general-ledger export), Procurement (purchase-order linkage) and Org (custodian directory) through references rather than hard coupling.

Key commands

The solution defines roughly 30 commands. Six representative ones cover the lifecycle:

CommandShapeRiskIdempotentWhy it matters
am.asset.createCreatewritetrueRegisters a new asset in draft; auto-generates asset_code
am.asset.activateStateTransitionwritetrue`draft
am.asset.transferActionwritetrueRe-assigns custody and/or department; emits an asset_transfer audit row
am.maintenance.completeStateTransitionwritetrueCloses a work order, records actual cost, sets the next-due date
am.asset.depreciateActionwritetruePosts the period charge to am_depreciation_schedule; updates net value
am.asset.disposeStateTransitionirreversiblefalseTerminal transition; requires scrap_reason and a confirmation gate

A button labelled "Transfer asset" is wired to am.asset.transfer — not to a raw PUT /api/am_asset. The same command is reachable from automation rules ("auto-transfer on org move"), from BPM steps inside the purchase-approval process, and — because am.asset.depreciate declares riskLevel: write, idempotent: true — from a scheduled job that runs the monthly close.

Permission example

A realistic asset-management role: "Site Maintenance Lead — Plant North".

  • RBAC: granted am.asset.view, am.maintenance.*, am.asset.transfer within own site; not granted am.asset.dispose (held by Asset Administrator) or am.asset.depreciate (Finance only).
  • Org scope (Layer 3 — ABAC): visibility limited to am_asset rows whose location.site = Plant North; the same predicate scopes am_maintenance_order lookups.
  • Cross-org transfer override (Layer 3 — ABAC): am.asset.transfer between sites requires a delegated permission token issued by the receiving site's Asset Manager. The runtime evaluates the delegation chain before the command handler runs; without it the transfer is rejected with policy.deny.cross_org_transfer.
  • Technician scope (Layer 3 — ABAC): individual technicians see only am_maintenance_order rows where technician_id = ${currentUser} or where they are on the site's on-call roster.
  • Cost-field mask (Layer 5 — field-level): non-finance roles see purchase_price, current_value and maintenance_cost masked to ***; the field is hidden from list exports as well, so a maintenance lead cannot CSV their way around the mask.

All five layers are evaluated in order — RBAC → tenant → ABAC scope → ReBAC → field mask — so a single declarative role configuration covers what would otherwise be hand-coded branching across the asset register, the maintenance board, and every report.

Process orchestration

The maintenance work-order lifecycle is a BPMN diagram. Each task is bound to a command:

                    ┌─────────────────────┐
                    │ Work order created  │  ←  am.maintenance.create  (pending)
                    └──────────┬──────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Schedule + assign tech      │  ←  am.maintenance.assign
                └──────────────┬──────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Asset → under_maintenance   │  ←  am.asset.start_maintenance
                └──────────────┬──────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Execute (in_progress)       │  ←  am.maintenance.start
                └──────────────┬──────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Record cost + parts used    │  ←  am.maintenance.record_cost
                └──────────────┬──────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Complete + set next-due     │  ←  am.maintenance.complete
                └──────────────┬──────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Asset → in_use              │  ←  am.asset.complete_maintenance
                └─────────────────────────────┘

A failed inspection branches to am.asset.dispose (terminal) or loops back to a follow-up repair order; the BPM engine carries the asset's current state, and every am.asset.* transition validates against the work-order's status so the two ledgers cannot drift.

Agent integration

Three command classes are intentionally exposed to AI agents:

  1. Read-and-summarise Commands (am.asset.list_due_for_maintenance, am.depreciation.monthly_summary) — read-only, idempotent, low risk. Agents can call freely.
  2. Drafting Commands (am.maintenance.draft_from_alert) — write, idempotent, reversible. The agent drafts a work order from an IoT alert; a human assigns and starts it via the existing commands.
  3. Operational nudges (am.asset.flag_idle) — write, idempotent. The agent notices an asset with zero utilisation for 90 days and flags it for review; cannot transition it.

What is not exposed: am.asset.dispose (irreversible), am.asset.transfer across organisations (delegated permission required), am.asset.depreciate (financial). These declare agentHint: "Human-only"; the platform's agent surface excludes them.

How to get it

  • Community: the open-core runtime — Meta, Command pipeline, five-layer permission model, BPM engine — is all open-source. The asset-management plugin manifest is published as a reference; copy it and adapt.
  • Standard: white-label the base platform; build your own asset-shaped plugins on top.
  • Professional: get the Asset Management solution package — pre-wired models, commands, dashboards, roles, and the depreciation engine.
  • Enterprise: same package plus delegated-permission templates for multi-site groups, GL export to the finance plugin, mobile barcode scanning, and SLA-backed support.

See Pricing for the full edition comparison.

Enterprise note — Cross-organisation delegated permissions, the depreciation-engine GL export connector, mobile barcode/QR scanning bundled with offline maintenance capture, and Observability Pro per-asset cost trace spans are commercial-only capabilities. The open-core runtime described above is identical across editions.

Next steps

  • System overview — how plugins, commands, and the runtime fit together
  • Command pipeline — the execution contract used by every command above
  • Permissions — the five-layer model used by the Site Maintenance Lead role
  • Plugin manifest — how a solution package declares its plugin dependencies
  • Agent readiness — designing agentHint and risk fields for safe execution