System Diagram

The Plant & Equipment Asset Management data model, mapped — 57 models, 176 relationships

🔍 For serious exploration, open the Interactive Diagram Viewer — pan, mouse-wheel zoom, fit-to-screen, full-screen, per-module tabs, the full 176-relationship ERD, and a focus mode that draws one model and its neighbours at a chosen depth. Organisation, Person, Asset and Evidence are org/role/equipment/evidence columns that fan out to nearly everything, so the viewer hides those links by default — a toggle brings them back. The diagrams below are the readable, static summary of the principal links only.


Architecture Overview

Ten areas mirror the sidebar menu. Every arrow means "one row of the left model is referenced by many rows of the right model".

flowchart LR
    subgraph FLEET["🚜 Fleet & assets"]
        AssetClass --> Asset
        Asset --> AssetComponent
        Asset --> AssetAssignment
        Asset --> TyrePosition
        Asset --> Tyre
    end

    subgraph UTIL["📈 Utilisation"]
        Asset --> UsageEntry
        Asset --> MeterReading
        Asset --> AvailabilityEvent
        Asset --> FuelTransaction
    end

    subgraph INSP["🔍 Inspections & defects"]
        Inspection --> InspectionResponse
        Asset --> Defect
        InspectionResponse --> Defect
    end

    subgraph WORK["🛠️ Workshop & work orders"]
        WorkRequest --> WorkOrder
        WorkOrder --> WorkOrderTask
        WorkOrder --> LabourEntry
        AssetMaintenancePlan --> WorkOrder
    end

    subgraph STORE["📦 Stores & parts"]
        InventoryItem --> InventoryBalance
        StoreLocation --> InventoryBalance
        WorkOrder --> PartIssue
    end

    subgraph BUY["🧾 Purchasing"]
        PurchaseRequisition --> Quote
        PurchaseRequisition --> PurchaseOrder
        PurchaseOrder --> PurchaseOrderLine
        PurchaseOrder --> GoodsReceipt
        PurchaseOrder --> SupplierInvoice
    end

    subgraph LIFE["💰 Cost & lifecycle"]
        Asset --> CostTransaction
        RenewalProgram --> RenewalCandidate
        Asset --> Disposal
        Asset --> Risk
    end

    subgraph PEOPLE["🎓 People & compliance"]
        Person --> OperatorLicence
        Person --> OperatorCompetency
        Person --> TrainingRecord
    end

    subgraph GOV["✅ Performance & governance"]
        ServiceLevel --> PerformanceResult
        Audit --> AuditFinding
        AuditFinding --> ImprovementAction
    end

    subgraph ADMIN["🏢 Administration"]
        Organisation --> Person
        Organisation --> Depot
        InspectionTemplate --> InspectionItemTemplate
        MaintenanceTemplate --> MaintenanceTemplateTask
    end

    Defect --> WorkRequest
    Asset --> AssetMaintenancePlan
    Asset --> WorkOrder
    WorkOrder --> CostTransaction
    RenewalCandidate --> Disposal

(Asset is the hub of the model — utilisation, condition, work, cost, risk and renewal all reference it. Person has the most links because every maintenance, purchasing and governance act records who: reported, approved, supervised, inspected, issued, received, assessed, closed.)


Fleet, Assets and Structure

The equipment being managed. Asset, AssetComponent, AssetClass and BusinessUnit each self-nest; an asset carries a class, a home depot, a custodian and a business unit.

erDiagram
    Organisation ||--o{ BusinessUnit : "organisation_id"
    BusinessUnit ||--o{ BusinessUnit : "parent_id"
    Organisation ||--o{ AssetClass : "organisation_id"
    AssetClass ||--o{ AssetClass : "parent_id"
    Organisation ||--o{ Asset : "organisation_id"
    AssetClass ||--o{ Asset : "asset_class_id"
    Asset ||--o{ Asset : "parent_asset_id"
    BusinessUnit ||--o{ Asset : "business_unit_id"
    Depot ||--o{ Asset : "home_depot_id"
    Asset ||--o{ AssetComponent : "asset_id"
    AssetComponent ||--o{ AssetComponent : "parent_component_id"
    Asset ||--o{ AssetAssignment : "asset_id"
    Asset ||--o{ TyrePosition : "asset_id"
    Asset ||--o{ Tyre : "current_asset_id"
    TyrePosition ||--o{ Tyre : "current_position_id"

Utilisation, Meters and Availability

How hard each asset works, and when it is down. MeterReading and AvailabilityEvent link back to the work order that caused them.

erDiagram
    Asset ||--o{ UsageEntry : "asset_id"
    Asset ||--o{ MeterReading : "asset_id"
    WorkOrder ||--o{ MeterReading : "work_order_id"
    Asset ||--o{ AvailabilityEvent : "asset_id"
    WorkOrder ||--o{ AvailabilityEvent : "work_order_id"
    Asset ||--o{ FuelTransaction : "asset_id"
    Supplier ||--o{ FuelTransaction : "supplier_id"

Inspections and Defects

Condition and safety. A templated inspection produces item-level responses; a failed response raises a defect that can restrict the asset.

erDiagram
    AssetClass ||--o{ InspectionTemplate : "asset_class_id"
    InspectionTemplate ||--o{ InspectionItemTemplate : "inspection_template_id"
    Asset ||--o{ Inspection : "asset_id"
    InspectionTemplate ||--o{ Inspection : "inspection_template_id"
    Inspection ||--o{ InspectionResponse : "inspection_id"
    InspectionItemTemplate ||--o{ InspectionResponse : "item_template_id"
    Asset ||--o{ Defect : "asset_id"
    AssetComponent ||--o{ Defect : "component_id"
    Inspection ||--o{ Defect : "inspection_id"
    Defect ||--o{ InspectionResponse : "defect_id"

Workshop and Work Orders

The maintenance response. A work order is raised from a work request, a maintenance plan or directly against an asset, and gathers tasks, labour and parts.

erDiagram
    AssetClass ||--o{ MaintenanceTemplate : "asset_class_id"
    MaintenanceTemplate ||--o{ MaintenanceTemplateTask : "maintenance_template_id"
    Asset ||--o{ AssetMaintenancePlan : "asset_id"
    MaintenanceTemplate ||--o{ AssetMaintenancePlan : "maintenance_template_id"
    Asset ||--o{ WorkRequest : "asset_id"
    Defect ||--o{ WorkRequest : "defect_id"
    WorkRequest ||--o{ WorkOrder : "work_request_id"
    Asset ||--o{ WorkOrder : "asset_id"
    AssetMaintenancePlan ||--o{ WorkOrder : "maintenance_plan_id"
    WorkOrder ||--o{ WorkOrderTask : "work_order_id"
    WorkOrder ||--o{ LabourEntry : "work_order_id"

Stores and Purchasing

Materials and the requisition-to-invoice chain. Parts are issued from a store location; a requisition compares quotes, converts to a purchase order, is receipted, and matched to a supplier invoice.

erDiagram
    Depot ||--o{ StoreLocation : "depot_id"
    Supplier ||--o{ InventoryItem : "preferred_supplier_id"
    InventoryItem ||--o{ InventoryBalance : "inventory_item_id"
    StoreLocation ||--o{ InventoryBalance : "store_location_id"
    WorkOrder ||--o{ PartIssue : "work_order_id"
    InventoryItem ||--o{ PartIssue : "inventory_item_id"
    PurchaseRequisition ||--o{ PurchaseRequisitionLine : "requisition_id"
    PurchaseRequisition ||--o{ Quote : "requisition_id"
    Supplier ||--o{ Quote : "supplier_id"
    PurchaseRequisition ||--o{ PurchaseOrder : "requisition_id"
    Supplier ||--o{ PurchaseOrder : "supplier_id"
    PurchaseOrder ||--o{ PurchaseOrderLine : "purchase_order_id"
    PurchaseOrder ||--o{ GoodsReceipt : "purchase_order_id"
    GoodsReceipt ||--o{ GoodsReceiptLine : "goods_receipt_id"
    PurchaseOrderLine ||--o{ GoodsReceiptLine : "purchase_order_line_id"
    PurchaseOrder ||--o{ SupplierInvoice : "purchase_order_id"

Cost and Lifecycle

Whole-of-life economics and the renewal decision. Cost transactions accumulate against the asset; scored renewal candidates feed the ten-year program; end-of-life assets are disposed.

erDiagram
    Asset ||--o{ CostTransaction : "asset_id"
    WorkOrder ||--o{ CostTransaction : "work_order_id"
    Organisation ||--o{ Budget : "organisation_id"
    Asset ||--o{ HireRate : "asset_id"
    Asset ||--o{ Risk : "asset_id"
    AssetClass ||--o{ Risk : "asset_class_id"
    RenewalProgram ||--o{ RenewalCandidate : "renewal_program_id"
    Asset ||--o{ RenewalCandidate : "asset_id"
    Asset ||--o{ Disposal : "asset_id"
    RenewalCandidate ||--o{ Disposal : "renewal_candidate_id"
    PurchaseOrder ||--o{ Disposal : "trade_in_purchase_order_id"

People and Governance

Operator authorisation and the assurance layer. Licences, competencies and training sit on the person; service levels are measured; audits raise findings that drive improvement actions.

erDiagram
    Person ||--o{ OperatorLicence : "person_id"
    Person ||--o{ OperatorCompetency : "person_id"
    AssetClass ||--o{ OperatorCompetency : "asset_class_id"
    Person ||--o{ TrainingRecord : "person_id"
    Organisation ||--o{ ServiceLevel : "organisation_id"
    ServiceLevel ||--o{ PerformanceResult : "service_level_id"
    Organisation ||--o{ ImprovementAction : "organisation_id"
    Organisation ||--o{ Audit : "organisation_id"
    Audit ||--o{ AuditFinding : "audit_id"
    Asset ||--o{ AuditFinding : "asset_id"
    ImprovementAction ||--o{ AuditFinding : "improvement_action_id"
    Organisation ||--o{ Approval : "organisation_id"

Application Flow — Inspection to Renewal

The order in which the system is actually used, and what gates each step.

flowchart TD
    A["🔍 Pre-start / periodic inspection"] --> B{"Item failed?"}
    B -->|yes| C["⚠️ Defect raised<br/><i>severity assessed</i>"]
    B -->|no| Z["✅ Asset available"]
    C --> D{"Serious?"}
    D -->|MAJOR / CRITICAL| E["⛔ Asset RESTRICTED<br/><i>operating restriction recorded</i>"]
    D -->|minor| F
    E --> F["🧾 Work request raised → approved"]
    F --> G["🛠️ Work order planned + assigned"]
    G --> H{"Parts needed?"}
    H -->|in stock| I["📦 Part issued from store"]
    H -->|reorder| J["🧾 Requisition → 3 quotes → PO → receipt → invoice"]
    I --> K["🔧 Tasks + labour booked"]
    J --> K
    K --> L["✅ Work order COMPLETED<br/><i>quality-checked + closed</i>"]
    L --> M["🔧 Defect → REPAIRED · asset → AVAILABLE"]
    M --> N["💰 Cost transactions accumulate against the asset"]
    N --> O["📊 Renewal candidate scored<br/><i>condition · age · use · cost · risk</i>"]
    O --> P{"Priority?"}
    P -->|retain| Q["Continue operate & maintain"]
    P -->|replace| R["♻️ Disposal — auction / trade-in / tender"]

Reading the Diagrams

  • A ||--o{ B means one row of A is referenced by many rows of B (the label is the foreign-key column on B).
  • These static diagrams show principal links only — the org/role/equipment columns that appear on nearly every model (organisation_id, *_person_id, *_by_id, asset_id, work_order_id, evidence_id) are omitted for readability. The interactive viewer's Full ERD shows all 176, with the organisation/person/asset/evidence noise toggleable.
  • Asset is the hub of the model and Person has the most links, because every maintenance, purchasing and governance act records which asset and who performed each role — the viewer's Focus mode is the fastest way to see one model's neighbourhood.
  • Two foreign keys were dropped in translation to break true reference cycles: BusinessUnit.manager_person_id (Person ↔ BusinessUnit) and WorkRequest.work_order_id (WorkRequest ↔ WorkOrder — the surviving edge is WorkOrder.work_request_id). Four self-references are kept: BusinessUnit.parent_id, AssetClass.parent_id, Asset.parent_asset_id and AssetComponent.parent_component_id.
  • One pointer is deliberately not a foreign key in spirit: IntegrationMessage and the source_system / source_reference / external_reference columns are governed references to records that live in external systems (finance, telematics, document management), not edges into them.

Diagrams are derived from the generated schema metadata (apps/uralla/generated/json/uralla_relationship_metadata.json). If the DSL schema changes, regenerate the metadata (python -m codegen.cli all uralla), rebuild the viewer (python apps/uralla/scripts/build_diagram_viewer.py) and update this page.