Data model - ION Manual

Overview

When you integrate against ION, eight or nine entities cover about 95% of what you touch. Each entity below shows what it represents, how it connects to the others, and what it maps to in adjacent systems such as ERP, MES, PLM, and QMS. The full schema lives in schema.graphql and the API Playground.

Entity map

The core entities connect through these relationships:

Parts

A Part is the library entry. It holds a part number, description, revision, and the design intent. A Part is not the physical thing on the shelf. That physical thing is a PartInventory.

Field Notes
id, partNumber Org-unique within revision. partNumber is your SKU.
description Free text.
revision Engineering revision letter or string.
partType PART or TOOL.
trackingType SERIAL, LOT, or unset (untracked).
status RELEASED or ARCHIVED.
sourcingStrategy MAKE, BUY, or DUAL_SOURCE.
purchaseType RECEIVABLE_INVENTORY, RECEIVABLE_NON_INVENTORY, or NON_RECEIVABLE_NON_INVENTORY.
partSubtypes Many-to-many with PartSubtype. These are categorization tags.
cost, leadTime Optional planning fields.
revisedFromId Links this revision to its predecessor.

Query a part:

query GetPart {
  part(id: "42") {
    id
    partNumber
    description
    revision
    partType
    trackingType
    status
    partSubtypes { id name }
  }
}

Maps to: “SKU” or “Item Master” in ERP. “PartNumber” in PLM.

PartSubtype

A PartSubtype is a categorization tag attached to a Part. Subtypes group parts that share routing, inspection, or planning behavior. Examples include “Mounting hardware”, “Critical-to-quality fasteners”, and “Long-lead-time stock”. A part can have multiple subtypes. Query the subtypes:

query Subtypes {
  partSubtypes(first: 50) {
    edges {
      node {
        id
        name
        description
      }
    }
  }
}

Maps to: “Item Family”, “Commodity Code”, or “Product Line” in ERP. Don’t confuse a subtype with revision lineage. Revision lineage is revisedFromId on Part.

PartInventory

A PartInventory is a physical instance of a Part. It can be a serialized unit, a lot, or a quantity at a location. This is the entity that gets installed onto assemblies, consumed in runs, or shipped.

Field Notes
serialNumber If the part is serialized.
lotNumber If the part is lot-tracked.
quantity For non-serialized inventory (count).
status Such as AVAILABLE, WIP, KITTED, INSTALLED, ON_ORDER, SCRAPPED, or UNAVAILABLE.
part Reference to its Part.
location Where it physically lives.
madeOnAssemblyParentPartInventory If installed onto an assembly, points up the build tree.
entity Polymorphic id used for file attachments and similar.

Query a part inventory record:

query Inventory {
  partInventory(id: "9876") {
    id
    serialNumber
    lotNumber
    quantity
    status
    part { id partNumber description }
    location { id name }
    madeOnAssemblyParentPartInventory { id serialNumber }
  }
}

Maps to: “Serial” or “Lot” in MES. “Inventory unit” or “Stockable item” in WMS. “Asset” in PLM.

Assemblies (as-built BOM)

An as-built BOM is the parent and child tree of PartInventory units that compose a finished assembly. ION represents this tree two ways. The madeOnAssemblyParentPartInventory reference on each PartInventory points up the tree. The BuildRequirement records define which parts to install where to complete the assembly. To traverse the tree downward:

query AbomTree {
  partInventory(id: "9876") {
    id
    serialNumber
    part { partNumber }
    buildRequirements {
      id
      part { partNumber }
      quantity
      abomInstallations {
        id
        partInventory {
          id
          serialNumber
          part { partNumber }
        }
      }
    }
  }
}

To walk up the tree, follow madeOnAssemblyParentPartInventory recursively. Maps to: “Bill of Materials” in ERP. “Assembly tree” in PLM. “Bill of Build” in MES.

The mBOM (manufacturing BOM) is the planned structure. The aBOM (as-built) is what was actually installed at run time. Both have GraphQL types in ION.

Procedures and run steps

A Procedure is the manufacturing routing template. It defines what should happen on the floor. A Procedure is composed of steps. Query a procedure with its steps:

query Proc {
  procedure(id: "12") {
    id
    title
    version
    steps {
      id
      title
      position
      type
      fields {
        id
        name
        type
      }
    }
  }
}

Maps to: “Routing” in ERP. “Recipe” or “Standard Operating Procedure” in MES. “Work Instruction” in QMS.

Runs and run steps

A Run is one execution of a Procedure against a specific PartInventory. Run steps are the per-execution instances of the procedure’s steps. A run step is where operators record measurements, sign off, and report quality issues.

Field Notes
id, title
status Such as TODO, IN_PROGRESS, or COMPLETE.
procedure Template.
partInventory What’s being built.
steps Ordered execution instances (RunStep).
runBatch If the run participates in a batch, see Run batches.

Query a run with its steps:

query GetRun {
  run(id: "1234") {
    id
    title
    status
    procedure { id title version }
    partInventory { id serialNumber part { partNumber } }
    steps {
      id
      position
      status
      endTime
      fields { id name value }
    }
  }
}

Maps to: “Work Order” in ERP. “Production Order” in MES. “Build” or “Job” colloquially.

Build requirements

A BuildRequirement is a line item on an aBOM. It defines how many of a given part to install to complete the assembly. Operators install against build requirements during a run. Each install is a row of abomInstallations (an ABomInstallation) that links the PartInventory consumed to the build requirement satisfied. For the user-facing flow, see Editing build requirements.

Issues

An Issue is a quality event. It can be a nonconformance, deviation, supplier problem, or observation. Issues attach to runs, run steps, or part inventories. Issues follow a defined lifecycle. The states are Pending, In Progress, In Review, and Resolved. Disposition types determine what happens to the affected inventory. Query open issues by disposition:

query OpenIssues {
  issues(filters: { status: { eq: IN_PROGRESS } }) {
    edges {
      node {
        id
        title
        status
        issueDispositionType { id title }
        assignedTo { id name }
        runStep { id }
      }
    }
  }
}

For more information, see Issue states, dispositions, and resolutions. Maps to: “Nonconformance Report” (NCR) in QMS. “CAPA” precursor in QMS. “Defect” in PLM. “Incident” in ServiceNow-style systems.

Purchase orders

For supply chain integrations:

query OpenPOs {
  purchaseOrders(filters: { isOpen: { eq: true } }) {
    edges {
      node {
        id
        prettyStr
        status
        supplier { id name }
        purchaseOrderLines {
          id
          part { partNumber }
          quantity
          receivedQuantity
        }
      }
    }
  }
}

Maps to: “PO” in ERP. Receiving against a PO updates PartInventory records.

File attachments

Files attach to entities polymorphically through the entity ID. For the upload flow and the entity { id } lookup pattern, see File upload.

The entity polymorphic ID

ION gives every attachable object a uniform ID through an entities reference. Most major entities expose an entity { id } field. This field is the target for several features:

Don’t confuse this field with the entity’s own id. When an integration calls for an entityId, fetch the parent’s entity.id first.

Field-mapping cheat sheet

When you bridge from another system, use this rough translation:

Your system says… ION calls it…
SKU, Item Master, or Part Number Part.partNumber
Item Family, Commodity, or Group PartSubtype.name (a part can belong to multiple subtypes)
Lot or Batch number PartInventory.lotNumber
Serial or Asset Tag PartInventory.serialNumber
On-hand quantity PartInventory.quantity
BOM line item BuildRequirement
Work Order or Production Order Run
Routing, Recipe, or Process Procedure
Operation, Step, or Op Step (template) or RunStep (execution)
NCR or Nonconformance Issue
Disposition (Use As Is, Rework, Scrap) IssueDispositionType
PO PurchaseOrder
PO line PurchaseOrderLine
Vendor or Supplier PurchaseOrder.supplier (a Supplier)
Workcenter or Cell Location (typed WORKCENTER)
Tote, Bin, or Rack Location (other types)
User group or Role Role
User User
Tenant or Org Organization

Etag-based concurrency

Every mutable entity returns an _etag on read. Pass it back on update and delete mutations. ION rejects writes whose etag doesn’t match the current value. A mismatch returns a 409. For more information, see Error codes 409. When you integrate, read then write inside a short window. Propagate the etag through your service.

Discovering the rest of the schema

You can find anything not on this page three ways:

  1. API Playground: an interactive schema explorer at /api-reference/playground.
  2. schema.graphql: committed to this repository and kept in sync with the production schema.
  3. __schema introspection: programmatic access.