docs: document flat BOM and assembly costing endpoints

Add section 8.4 to SPECIFICATION.md describing the flat BOM flattening
and assembly cost roll-up endpoints with example request/response JSON.

- GET /api/items/{pn}/bom/flat — consolidated leaf parts with
  rolled-up quantities and cycle detection
- GET /api/items/{pn}/bom/cost — per-line extended costs and total
  assembly cost using standard_cost

Update endpoint count from 74 to 76 in SPECIFICATION.md and README.md.
Add checklist entries for flat BOM and assembly costing features.
This commit is contained in:
Forbes
2026-02-07 01:35:56 -06:00
parent a4f32b2b49
commit 3704adb584
2 changed files with 55 additions and 4 deletions

View File

@@ -37,7 +37,7 @@ Silo treats **part numbering schemas as configuration, not code**. Multiple numb
┌─────────────────────────────────────────────────────────────┐
│ Silo Server (silod) │
│ - REST API (74 endpoints) │
│ - REST API (76 endpoints) │
│ - Authentication (local, LDAP, OIDC) │
│ - Schema parsing and validation │
│ - Part number generation engine │
@@ -469,6 +469,53 @@ child_revision: null # means "latest"
Assembly metadata YAML controls default behavior per assembly.
### 8.4 Flat BOM and Assembly Costing
Two endpoints provide procurement- and manufacturing-oriented views of the BOM:
**Flat BOM** (`GET /api/items/{partNumber}/bom/flat`) walks the full assembly tree and returns a consolidated list of **leaf parts only** (parts with no BOM children). Quantities are multiplied through each nesting level and duplicate parts are summed.
```
Assembly A (qty 1)
├── Sub-assembly B (qty 2)
│ ├── Part X (qty 3) → total 6
│ └── Part Y (qty 1) → total 2
└── Part Z (qty 4) → total 4
```
Response:
```json
{
"part_number": "A",
"flat_bom": [
{ "part_number": "X", "description": "...", "total_quantity": 6 },
{ "part_number": "Y", "description": "...", "total_quantity": 2 },
{ "part_number": "Z", "description": "...", "total_quantity": 4 }
]
}
```
**Assembly Cost** (`GET /api/items/{partNumber}/bom/cost`) builds on the flat BOM and multiplies each leaf's `total_quantity` by its `standard_cost` to produce per-line extended costs and a total assembly cost.
```json
{
"part_number": "A",
"total_cost": 124.50,
"cost_breakdown": [
{ "part_number": "X", "total_quantity": 6, "unit_cost": 10.00, "extended_cost": 60.00 },
{ "part_number": "Y", "total_quantity": 2, "unit_cost": 7.25, "extended_cost": 14.50 },
{ "part_number": "Z", "total_quantity": 4, "unit_cost": 12.50, "extended_cost": 50.00 }
]
}
```
Both endpoints detect BOM cycles and return **HTTP 409** with the offending path:
```json
{ "error": "cycle_detected", "detail": "BOM cycle detected: A → B → A" }
```
---
## 9. Physical Inventory
@@ -619,6 +666,8 @@ POST /api/items/{partNumber}/file # Upload file [edito
# BOM
GET /api/items/{partNumber}/bom # List direct children
GET /api/items/{partNumber}/bom/expanded # Multi-level BOM (recursive)
GET /api/items/{partNumber}/bom/flat # Flattened BOM (leaf parts, rolled-up quantities)
GET /api/items/{partNumber}/bom/cost # Assembly cost roll-up
GET /api/items/{partNumber}/bom/where-used # Where-used (parent lookup)
GET /api/items/{partNumber}/bom/export.csv # Export BOM as CSV
GET /api/items/{partNumber}/bom/export.ods # Export BOM as ODS
@@ -673,11 +722,13 @@ POST /api/inventory/{partNumber}/move
- [x] YAML schema parser for part numbering
- [x] Part number generation engine
- [x] CLI tool (`cmd/silo`)
- [x] API server (`cmd/silod`) with 74 endpoints
- [x] API server (`cmd/silod`) with 76 endpoints
- [x] MinIO integration for file storage with versioning
- [x] BOM relationships (component, alternate, reference)
- [x] Multi-level BOM (recursive expansion with configurable depth)
- [x] Where-used queries (reverse parent lookup)
- [x] Flat BOM flattening with quantity roll-up and cycle detection
- [x] Assembly cost roll-up using standard_cost
- [x] BOM CSV and ODS export/import
- [x] Reference designator tracking
- [x] Revision history (append-only) with rollback and comparison