58 lines
2.4 KiB
Markdown
58 lines
2.4 KiB
Markdown
# Contract: BOM Decomposition Mapping
|
|
|
|
Version: 1.0
|
|
|
|
## Purpose
|
|
|
|
Defines the canonical way to represent a BOM row that decomposes one external/vendor item into
|
|
multiple internal component or LOT rows.
|
|
|
|
This is not an alternate-choice mapping.
|
|
All mappings in the row apply simultaneously.
|
|
|
|
Use this contract when:
|
|
- one vendor part number expands into multiple LOTs
|
|
- one bundle SKU expands into multiple internal components
|
|
- one external line item contributes quantities to multiple downstream rows
|
|
|
|
See `README.md` for full JSON and Go examples.
|
|
|
|
## Canonical Shape
|
|
|
|
- A BOM row contains one quantity plus zero or more mapping entries in one array field.
|
|
- `component_mappings[]` is the only canonical persisted decomposition format.
|
|
- Each mapping entry has:
|
|
- `component_ref`
|
|
- `quantity_per_item`
|
|
- Project-specific field names are allowed only if the semantics stay identical.
|
|
|
|
## Quantity and Persistence Rules
|
|
|
|
- Downstream quantity is always `row.quantity * mapping.quantity_per_item`.
|
|
- The persisted row payload is the source of truth.
|
|
- The same mapping shape must be used for persistence, API read/write payloads, and downstream expansion logic.
|
|
- If the mapping array is empty, the row contributes nothing downstream.
|
|
- Row order is defined by `sort_order`.
|
|
- Mapping entry order may be preserved for UX, but business logic must not depend on it.
|
|
|
|
## UI and Validation Rules
|
|
|
|
- The first mapping row is not special. Every mapping row is equally editable and removable.
|
|
- `quantity_per_item` is edited per mapping row, not once for the whole BOM row.
|
|
- Blank mapping rows may exist temporarily in draft UI state, but they must not be persisted.
|
|
- New UI rows should default `quantity_per_item` to `1`.
|
|
- Before persistence:
|
|
- trim `component_ref`
|
|
- drop empty `component_ref` rows
|
|
- reject `quantity_per_item <= 0`
|
|
- merge duplicate `component_ref` values by summing quantities
|
|
- preserve first-seen order when merging duplicates
|
|
|
|
## Forbidden Patterns
|
|
|
|
- Do not introduce alternate persisted shapes such as `primary_lot`, `secondary_lots`, `main_component`, or `bundle_lots`.
|
|
- Do not split the component and its quantity across unrelated fields outside the mapping array.
|
|
- Do not treat the first mapping row as a special primary component.
|
|
- Do not compute downstream decomposition from temporary UI-only fields instead of the persisted mapping array.
|
|
- Do not store the same decomposition in multiple competing formats.
|