> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firstresonance.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate to the new aBOM API

> Update API, ION Actions, webhooks, and SQL from the legacy AbomItems model to BuildRequirements and AbomInstallations.

## Actions needed

This project will introduce breaking changes.

1. **API**: If you are using the API to call any of the below mutations or a query that uses any of the below fields, you will need to update your mutations/queries.
2. **Actions**: If you have any ION actions (rules) using any of the objects below, those will be disabled when this project is released and you will need to update those after release.
3. **Webhooks**: If you have any webhooks listening to any of the objects below, you will need to update your webhook listeners after release.
4. **Analytics**: If you have any SQL queries referencing `abom_items` or `abom_edges` those will need to be updated.

If the above does not apply to you then no changes necessary!

## Changes overview

Below shows an example of a car assembly that is partially installed and the differences between the old structure and the new structure.

Old structure:

```mermaid fullWidth="false" theme={null}
graph TB
  i1([
    inventory 1
    car assembly
    SN 45
  ])
  i2([
    inventory 2
    SN 12
  ])
  i3([
    inventory 3
    SN 13
  ])
  ab1[
    abom item 1
    car assembly
    qty 1
  ]
  ab2[
    abom item 2
    wheel assembly
    qty 1
  ]
  ab3[
    abom item 3
    wheel assembly
    qty 1
  ]
  ab4[
    abom item 4
    wheel assembly
    qty 2
  ]
  ab5[
    abom item 5
    fastener
    qty 50
  ]
  i1 --- ab1
  ab1 ---> ab2
  ab1 ---> ab3
  ab1 ---> ab4
  ab1 ---> ab5
  ab2 --- i2
  ab3 --- i3

  classDef green fill:#9f6,stroke:#333,stroke-width:2px;
  class i1,i2,i3 green
  
```

New structure:

```mermaid fullWidth="false" theme={null}
graph TB
  i1([
    inventory 1
    car assembly
    SN 45
  ])
  i2([
    inventory 2
    SN 12
  ])
  i3([
    inventory 3
    SN 13
  ])
  br1[
    build requirement 1
    wheel assembly
    qty 4
  ]
  br2[
    build requirement 2
    fastener
    qty 50
  ]
  i1 ---> br1
  i1 ---> br2
  br1 --abom installation--- i2 
  br1 --abom installation--- i3

  classDef green fill:#9f6,stroke:#333,stroke-width:2px;
  class i1,i2,i3 green
  
```

Old structure:

* aBOM items represent both the requirement and fulfillment of the installation
* aBOM items are used to link to inventories
* aBOM edges connect aBOM items
* aBOM items change as items are partially installed/removed. New ones get created or deleted, or quantities change

New structure:

* Build requirements belong to parent inventories and represent what needs to be installed
* Build requirements do not change as items are installed into them
* aBOM installations link inventories to a build requirement. The addition of an aBOM installation is an install. The removal of an aBOM installation is an uninstall

## Mutation/query changes

* AbomItems will be replaced by `BuildRequirements` and `AbomInstallations`, where the requirement and fulfillment (install) are clearly delineated
* AbomEdges will be replaced by `PartInventoryBuildRequirements`

Below shows the full list of items that are going away.

### Going away

#### Mutations

* `InstallKitOnAbomItemChildren`
* `CreateAbomItem`
* `DeleteAbomItem`
* `UpdateAbomItem`

#### GQL Objects/Queries

* `AbomItems`
* `ABomEdges`
* `ABomItemReferenceDesignators`

#### Fields

* `PartInventory.abomItems`
* `PartInventory.abomChildren`
* `PartInventory.abomParents`
* `PartInventory.allChildren`
* `PartInventory.allParents`
* `Part.abomItems`
* `MBomItem.abomItems`
* `MBomItemReferenceDesignator.abomItems`
* `AbomItemReferenceDesignator.abomItem`

(and any count fields generated from these relationships)<br />

### Examples

#### API: Installing a part

Old structure:

Previously, you would have to update an existing `abom_item` with an inventory to install that inventory. The `abom_item` at that point may get swapped if the inventory being installed is already linked ot an `abom_item`

<Tabs>
  <Tab title="Update aBOM item">
    ```graphql theme={null}
    mutation UpdateABomItem($input: UpdateABomItemInput!) {
        updateAbomItem(input: $input) {
            abomItem {
                id updatedById partInventoryId
            }
        }
    }
    ```
  </Tab>

  <Tab title="Inputs">
    ```graphql theme={null}
    {
        "input": {
            "id": 1,
            "partInventoryId": 1,
            "etag": "etag"
        }
    }
    ```
  </Tab>
</Tabs>

New structure:

Now installing a part is done via creating an aBOM installation. aBOM installations link inventories to `buildRequirements`. Conversely, uninstalling a part is done by deleting aBOM installations.

<Tabs>
  <Tab title="Create aBOM installation">
    ```graphql theme={null}
    mutation CreateABomInstallation($input: CreateABomInstallationInput!) {
        createAbomInstallation(input: $input) {
            abomInstallation {
                buildRequirementId
                buildRequirementReferenceDesignatorId
                partInventoryId
                quantity
            }
        }
    }
    ```
  </Tab>

  <Tab title="Inputs">
    ```graphql theme={null}
    {
        "input": {
            "buildRequirementId": 1,
            "partInventoryId": 3,
            "quantity": 1
        }
    }

    ```
  </Tab>
</Tabs>

#### SQL: Query for an inventory's aBOM

Old structure:

```sql theme={null}
select 
parent_part.part_number,
parent_part.description,
parent_inventory.serial_number,
parent_inventory.lot_number,
parent_inventory.quantity,
child_part.part_number,
child_part.description,
child_inventory.serial_number,
child_inventory.lot_number,
child_abom_item.quantity as 'installed quantity'

from parts_inventory parent_inventory
inner join parts parent_part on parent_part.id = parent_inventory.part_id
inner join abom_items parent_abom_item on parent_inventory.id = ai.part_inventory_id
inner join abom_edges ae on ae.parent_abom_item_id = parent_abom_item.id
inner join abom_items child_abom_item on child_abom_item.id = ae.child_abom_item_id
inner join parts_inventory child_inventory on child_abom_item.part_inventory_id = child_inventory.id
inner join parts child_part on child_part.id = child_abom_item.part_id

where parent_inventory.id = 105
```

New structure:

```sql theme={null}
select 
parent_part.part_number,
parent_part.description,
parent_inventory.serial_number,
parent_inventory.lot_number,
parent_inventory.quantity,
child_part.part_number,
child_part.description,
child_inventory.serial_number,
child_inventory.lot_number,
ai.quantity as 'installed quantity'

from parts_inventory parent_inventory
inner join parts parent_part on parent_part.id = parent_inventory.part_id
inner join part_inventory_build_requirements pibr on pibr.part_inventory_id = parent_inventory.id
inner join abom_installations ai on pibr.build_requirement_id = ai.build_requirement_id
inner join parts_inventory child_inventory on ai.part_inventory_id = child_inventory.id
inner join parts child_part on child_part.id = child_abom_item.part_id

where parent_inventory.id = 105
```
