Northwind Components ERP — Operations Skill
API
Base URL provided at solve time. Primary endpoints:
| Endpoint |
Key query params |
/orders?wave=&customer_id=&required_date= |
Wave filter, customer |
/orders/<order_id> |
Single order detail |
/products , /products/<sku> |
Active flag, safety_stock, overstock_threshold, weight_lb, unit_cost, supplier_id |
/customers , /customers/<customer_id> |
account_status, risk_flag, tier, margin_band |
/warehouses |
WH_NORTH, WH_CENTRAL, WH_WEST; zip per warehouse |
/inventory?warehouse_id=&sku= |
on_hand, reserved, quarantined — no buffer field |
/purchase_orders?supplier_id=&sku=&status= |
status: open, confirmed, received, cancelled; eta field |
/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed= |
Returns zone_distance, service_days, total_cost (field name, not total_cost_usd) |
/incidents?start=&end=&supplier_id=&sku=&incident_type=&status= |
Date filter on open_date; severity, resolution_cost, incident_type |
/suppliers |
quality_status: approved, watch, quality_hold |
/boms , /boms/<bom_id> |
Components with quantity_per_kit, warehouse_id |
Effective Availability
Always compute effective available as:
effective = on_hand − reserved − quarantined
When a memo mentions "normal operating buffer," also subtract safety_stock:
effective_buffered = max(0, on_hand − reserved − quarantined − safety_stock)
Always clamp negative effective to 0 before using in gap calculations:
gap = max(0, required_quantity − max(0, effective))
Decimal precision:
- Currency: 2 decimal places (
round(val, 2))
- Percentages: 1 decimal place (
round(val, 1))
- Duration (days): 2 decimal places
Enforced Enum Conventions
Every task uses controlled enumerations. Never deviate from the allowed values in the answer template. Common patterns:
Customer exception (precedence order):
account_status == "blocked" → "account_blocked" (takes priority over risk_flag)
risk_flag == "fraud_watch" → "fraud_watch"
risk_flag == "credit_watch" → "credit_watch"
account_status == "review_required" → "review_required"
- Otherwise →
"none"
Blocked status always wins over risk flags when both are present.
Inventory status (order of evaluation):
- If any line SKU is inactive AND any active SKU has shortage →
"inactive_and_shortage"
- If any line SKU is inactive (no shortage) →
"inactive_sku"
- If any active SKU has
effective < quantity → "shortage"
- If any active SKU has
effective >= quantity but effective < quantity + safety_stock → "low_stock"
- Otherwise →
"ready"
Line action (allocation/transfer tasks):
"ship" — requested warehouse can release full line quantity
"transfer" — other warehouse can cover the shortage
"backorder" — cannot be cleared from current effective stock
"manual_review" — account, risk, or product status prevents automatic release
Replenishment final_action (BOM/kit build tasks):
"no_action_stocked" — sufficiently stocked
"transfer_only" — covered by inter-warehouse transfers
"purchase_required" — new purchase requisition needed
"timely_po_covered" — existing open/confirmed PO covers the gap
"overstock_excluded" — site effective exceeds overstock_threshold
Exclusion reasons: "none", "target_overstock", "timely_po_covers_gap", "stocked_no_gap"
Recommendation codes (supplier scorecards, in precedence order):
"ESCALATE_SUPPLIER" — quality_hold + 3+ incidents, OR any critical RMA, OR 3+ RMAs + ≥15000 cost
"PROCESS_REVIEW" — WORK_ORDER incidents ≥ 3 AND WORK_ORDER > RMA count
"WATCHLIST" — quality_status in (watch, quality_hold), OR count ≥ 4, OR cost ≥ 12000, OR severe ≥ 2
"MONITOR" — none of the above
Procurement control decisions:
"freeze_new_replenishment" — quality_hold status
"buyer_review_required" — watch status with open incidents or critical incidents
"monitor_only" — no quality concerns
Field Pitfalls
- Shipping quote: API returns
total_cost, not total_cost_usd. Map it to the answer field total_cost_usd.
- Inventory fields:
on_hand, reserved, quarantined — no qty_ prefix, no buffer field.
- Safety stock: Use
safety_stock from the products endpoint as the threshold for low-stock detection. Do not confuse it with overstock_threshold.
- effective >= 0: Always clamp. Negative effective means 0 available.
- PO timeliness: A PO is "timely" only when
warehouse_id matches the planning site, status is "open" or "confirmed", and eta is on or before the earliest build date that needs the SKU. PO total quantity (not capped at gap) is the timely_po_qty.
- Overstock classification:
site_effective > overstock_threshold triggers overstock_excluded / target_overstock. Check this BEFORE gap-based classification.
- Received POs: Already counted in inventory. Do not double-count as timely PO coverage.
- Cancelled POs: Ignore entirely.
Ordering Rules
- Records/lines: Sort by
order_id ascending, then line_id ascending.
- SKU lists: Sort ascending by SKU string.
- Transfer requests: Sort by
sku ascending, then quantity descending, then from_warehouse_id ascending.
- Supplier scorecard rows: Sort by
supplier_id ascending.
- Top escalation: Sort by
incident_count descending, then total_resolution_cost descending, then supplier_id ascending.
- Blocked/manual-review/backorder order ID lists: Sort ascending.
Calculations
Incident duration:
- Closed:
(close_date − open_date).days
- Open:
(analysis_date − open_date).days
Incident percentage: round(incident_count / total_filtered_incidents × 100, 1)
Transfer source selection: Sort candidate warehouses by effective stock descending; pull from the largest source first. Never transfer more than the source's effective stock.
Kit build component requirement:
total_required = sum over all kits(build_quantity × quantity_per_kit)
Combine quantities across all BOMs that share a component.
Shipping weight: Sum over all order lines: quantity × weight_lb. If zero, default to 1.0.
SOP: Expedite Queue Decision
- Fetch orders for wave, products, customers, inventory, shipping quotes.
- For each order in the memo (sorted by order_id):
a. Classify inventory status across all lines.
b. Classify customer exception using precedence rules above.
c. Determine final_decision: customer issues (account_blocked → reject_hold; fraud_watch/credit_watch → manual_review; review_required → manual_review) take priority over inventory issues (inactive → manual_review; shortage → backorder; low_stock → delayed_release; ready → ship_now).
d. Map next_action to the most specific trigger.
e. Compute shipping quote from the order's warehouse, destination_zip, total weight, and speed.
- Build summary with counts, blocked/manual/backorder/inactive order lists.
SOP: Kit Build Replenishment
- Fetch BOMs, products, all-warehouse inventory, purchase orders.
- Compute per-SKU total required across all target builds.
- For each component (sorted by SKU):
a. Compute site effective and gap.
b. Identify timely POs (same site, open/confirmed, eta ≤ earliest build date). Timely_po_qty = full PO quantity.
c. Subtract timely_po_qty from gap. If gap remains, seek transfers from other warehouses (sort sources by effective descending). Transfer only up to source effective.
d. Any remaining gap becomes purchase_requisition_qty.
e. Classify final_action: overstock first, then timely PO coverage, then transfer/purchase/no-action.
- Populate transfer_requests, purchase_requisitions, excluded_components.
- Summary: component_count, total_purchase_units, total_purchase_cost, total_transfer_units, timely_po_covered_units (gap units covered by timely POs, not full PO quantity).
SOP: Allocation Desk (Mixed-Warehouse)
- Fetch orders for wave, products, customers, all-warehouse inventory.
- Determine if effective should include safety_stock buffer (check memo for "normal operating buffer").
- For each line (sorted by order_id, line_id):
a. Check customer status → blocked_orders, primary_reason.
b. Check product active → manual_review for inactive.
c. If customer blocked/fraud/credit/review → manual_review with appropriate primary_reason.
d. Else check inventory: ship if eff ≥ qty; transfer if another WH can cover gap; backorder otherwise.
e. For transfer, pick the best single source warehouse (most available).
- Order rollup: classify each order based on its line actions (single action → map; mixed → "mixed_actions").
- blocked_orders: orders where customer has account_blocked, fraud_watch, or credit_watch risk.
SOP: Supplier Incident Scorecard
- Fetch incidents within the date window (inclusive). Fetch all suppliers.
- Group incidents by supplier_id. Only include suppliers with at least one filtered incident.
- Per supplier: compute counts, costs, durations, percentages.
- Apply recommendation policy in strict precedence order — first matching condition wins.
- Build top_escalation_suppliers list (only ESCALATE_SUPPLIER, ordered as specified).
- Identify highest_cost_supplier_id and highest_share_supplier_id.
SOP: Procurement Quality Control
- Fetch incidents for target suppliers within the analysis window.
- Fetch supplier quality_status and all open/confirmed POs.
- Per supplier: count recent incidents, RMAs, severe/critical, open incidents, affected SKUs.
- Sample up to 5 incident IDs (sorted ascending).
- Decision: quality_hold → freeze_new_replenishment; watch with open/critical incidents → buyer_review_required; otherwise → monitor_only.
- held_po_ids: all open/confirmed PO IDs for non-monitor_only suppliers.
- release_supplier_ids: monitor_only suppliers (sorted).
1---2name: reflect-3-attempt-01-473description: Northwind Components ERP — Operations Skill4---5# Northwind Components ERP — Operations Skill67## API89Base URL provided at solve time. Primary endpoints:1011| Endpoint | Key query params |12|---|---|13| `/orders?wave=&customer_id=&required_date=` | Wave filter, customer |14| `/orders/<order_id>` | Single order detail |15| `/products` , `/products/<sku>` | Active flag, safety_stock, overstock_threshold, weight_lb, unit_cost, supplier_id |16| `/customers` , `/customers/<customer_id>` | account_status, risk_flag, tier, margin_band |17| `/warehouses` | WH_NORTH, WH_CENTRAL, WH_WEST; zip per warehouse |18| `/inventory?warehouse_id=&sku=` | on_hand, reserved, quarantined — no `buffer` field |19| `/purchase_orders?supplier_id=&sku=&status=` | status: open, confirmed, received, cancelled; eta field |20| `/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed=` | Returns zone_distance, service_days, **total_cost** (field name, not total_cost_usd) |21| `/incidents?start=&end=&supplier_id=&sku=&incident_type=&status=` | Date filter on open_date; severity, resolution_cost, incident_type |22| `/suppliers` | quality_status: approved, watch, quality_hold |23| `/boms` , `/boms/<bom_id>` | Components with quantity_per_kit, warehouse_id |2425## Effective Availability2627Always compute effective available as:2829```30effective = on_hand − reserved − quarantined31```3233When a memo mentions "normal operating buffer," **also subtract `safety_stock`**:3435```36effective_buffered = max(0, on_hand − reserved − quarantined − safety_stock)37```3839Always clamp negative effective to 0 before using in gap calculations:4041```42gap = max(0, required_quantity − max(0, effective))43```4445Decimal precision:46- Currency: **2 decimal places** (`round(val, 2)`)47- Percentages: **1 decimal place** (`round(val, 1)`)48- Duration (days): **2 decimal places**4950## Enforced Enum Conventions5152Every task uses controlled enumerations. Never deviate from the allowed values in the answer template. Common patterns:5354**Customer exception** (precedence order):551. `account_status == "blocked"` → `"account_blocked"` (takes priority over risk_flag)562. `risk_flag == "fraud_watch"` → `"fraud_watch"`573. `risk_flag == "credit_watch"` → `"credit_watch"`584. `account_status == "review_required"` → `"review_required"`595. Otherwise → `"none"`6061Blocked status always wins over risk flags when both are present.6263**Inventory status** (order of evaluation):641. If any line SKU is **inactive** AND any active SKU has shortage → `"inactive_and_shortage"`652. If any line SKU is inactive (no shortage) → `"inactive_sku"`663. If any active SKU has `effective < quantity` → `"shortage"`674. If any active SKU has `effective >= quantity` but `effective < quantity + safety_stock` → `"low_stock"`685. Otherwise → `"ready"`6970**Line action** (allocation/transfer tasks):71- `"ship"` — requested warehouse can release full line quantity72- `"transfer"` — other warehouse can cover the shortage73- `"backorder"` — cannot be cleared from current effective stock74- `"manual_review"` — account, risk, or product status prevents automatic release7576**Replenishment final_action** (BOM/kit build tasks):77- `"no_action_stocked"` — sufficiently stocked78- `"transfer_only"` — covered by inter-warehouse transfers79- `"purchase_required"` — new purchase requisition needed80- `"timely_po_covered"` — existing open/confirmed PO covers the gap81- `"overstock_excluded"` — site effective exceeds overstock_threshold8283**Exclusion reasons**: `"none"`, `"target_overstock"`, `"timely_po_covers_gap"`, `"stocked_no_gap"`8485**Recommendation codes** (supplier scorecards, in precedence order):861. `"ESCALATE_SUPPLIER"` — quality_hold + 3+ incidents, OR any critical RMA, OR 3+ RMAs + ≥15000 cost872. `"PROCESS_REVIEW"` — WORK_ORDER incidents ≥ 3 AND WORK_ORDER > RMA count883. `"WATCHLIST"` — quality_status in (watch, quality_hold), OR count ≥ 4, OR cost ≥ 12000, OR severe ≥ 2894. `"MONITOR"` — none of the above9091**Procurement control decisions**:92- `"freeze_new_replenishment"` — quality_hold status93- `"buyer_review_required"` — watch status with open incidents or critical incidents94- `"monitor_only"` — no quality concerns9596## Field Pitfalls9798- **Shipping quote**: API returns `total_cost`, not `total_cost_usd`. Map it to the answer field `total_cost_usd`.99- **Inventory fields**: `on_hand`, `reserved`, `quarantined` — no `qty_` prefix, no `buffer` field.100- **Safety stock**: Use `safety_stock` from the products endpoint as the threshold for low-stock detection. Do not confuse it with `overstock_threshold`.101- **effective >= 0**: Always clamp. Negative effective means 0 available.102- **PO timeliness**: A PO is "timely" only when `warehouse_id` matches the planning site, `status` is `"open"` or `"confirmed"`, and `eta` is on or before the earliest build date that needs the SKU. PO total quantity (not capped at gap) is the `timely_po_qty`.103- **Overstock classification**: `site_effective > overstock_threshold` triggers `overstock_excluded` / `target_overstock`. Check this BEFORE gap-based classification.104- **Received POs**: Already counted in inventory. Do not double-count as timely PO coverage.105- **Cancelled POs**: Ignore entirely.106107## Ordering Rules108109- **Records/lines**: Sort by `order_id` ascending, then `line_id` ascending.110- **SKU lists**: Sort ascending by SKU string.111- **Transfer requests**: Sort by `sku` ascending, then `quantity` descending, then `from_warehouse_id` ascending.112- **Supplier scorecard rows**: Sort by `supplier_id` ascending.113- **Top escalation**: Sort by `incident_count` descending, then `total_resolution_cost` descending, then `supplier_id` ascending.114- **Blocked/manual-review/backorder order ID lists**: Sort ascending.115116## Calculations117118**Incident duration**:119- Closed: `(close_date − open_date).days`120- Open: `(analysis_date − open_date).days`121122**Incident percentage**: `round(incident_count / total_filtered_incidents × 100, 1)`123124**Transfer source selection**: Sort candidate warehouses by effective stock descending; pull from the largest source first. Never transfer more than the source's effective stock.125126**Kit build component requirement**:127```128total_required = sum over all kits(build_quantity × quantity_per_kit)129```130Combine quantities across all BOMs that share a component.131132**Shipping weight**: Sum over all order lines: `quantity × weight_lb`. If zero, default to 1.0.133134## SOP: Expedite Queue Decision1351361. Fetch orders for wave, products, customers, inventory, shipping quotes.1372. For each order in the memo (sorted by order_id):138 a. Classify inventory status across all lines.139 b. Classify customer exception using precedence rules above.140 c. Determine final_decision: customer issues (account_blocked → reject_hold; fraud_watch/credit_watch → manual_review; review_required → manual_review) take priority over inventory issues (inactive → manual_review; shortage → backorder; low_stock → delayed_release; ready → ship_now).141 d. Map next_action to the most specific trigger.142 e. Compute shipping quote from the order's warehouse, destination_zip, total weight, and speed.1433. Build summary with counts, blocked/manual/backorder/inactive order lists.144145## SOP: Kit Build Replenishment1461471. Fetch BOMs, products, all-warehouse inventory, purchase orders.1482. Compute per-SKU total required across all target builds.1493. For each component (sorted by SKU):150 a. Compute site effective and gap.151 b. Identify timely POs (same site, open/confirmed, eta ≤ earliest build date). Timely_po_qty = full PO quantity.152 c. Subtract timely_po_qty from gap. If gap remains, seek transfers from other warehouses (sort sources by effective descending). Transfer only up to source effective.153 d. Any remaining gap becomes purchase_requisition_qty.154 e. Classify final_action: overstock first, then timely PO coverage, then transfer/purchase/no-action.1554. Populate transfer_requests, purchase_requisitions, excluded_components.1565. Summary: component_count, total_purchase_units, total_purchase_cost, total_transfer_units, timely_po_covered_units (gap units covered by timely POs, not full PO quantity).157158## SOP: Allocation Desk (Mixed-Warehouse)1591601. Fetch orders for wave, products, customers, all-warehouse inventory.1612. Determine if effective should include safety_stock buffer (check memo for "normal operating buffer").1623. For each line (sorted by order_id, line_id):163 a. Check customer status → blocked_orders, primary_reason.164 b. Check product active → manual_review for inactive.165 c. If customer blocked/fraud/credit/review → manual_review with appropriate primary_reason.166 d. Else check inventory: ship if eff ≥ qty; transfer if another WH can cover gap; backorder otherwise.167 e. For transfer, pick the best single source warehouse (most available).1684. Order rollup: classify each order based on its line actions (single action → map; mixed → "mixed_actions").1695. blocked_orders: orders where customer has account_blocked, fraud_watch, or credit_watch risk.170171## SOP: Supplier Incident Scorecard1721731. Fetch incidents within the date window (inclusive). Fetch all suppliers.1742. Group incidents by supplier_id. Only include suppliers with at least one filtered incident.1753. Per supplier: compute counts, costs, durations, percentages.1764. Apply recommendation policy in strict precedence order — first matching condition wins.1775. Build top_escalation_suppliers list (only ESCALATE_SUPPLIER, ordered as specified).1786. Identify highest_cost_supplier_id and highest_share_supplier_id.179180## SOP: Procurement Quality Control1811821. Fetch incidents for target suppliers within the analysis window.1832. Fetch supplier quality_status and all open/confirmed POs.1843. Per supplier: count recent incidents, RMAs, severe/critical, open incidents, affected SKUs.1854. Sample up to 5 incident IDs (sorted ascending).1865. Decision: quality_hold → freeze_new_replenishment; watch with open/critical incidents → buyer_review_required; otherwise → monitor_only.1876. held_po_ids: all open/confirmed PO IDs for non-monitor_only suppliers.1887. release_supplier_ids: monitor_only suppliers (sorted).