# Inventory Health Report

> Generate a per-SKU inventory health report from Shopify exports or generic sales and product CSVs, including safety stock, reorder points, EOQ, stockout risk, overstock signals, and replenishment guidance. Use when an agent needs inventory planning, replenishment analysis, stockout prevention, overstock review, or SKU-level order recommendations from CSV data.

- Skill: `useretrace/inventory-health-report` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add useretrace/inventory-health-report`
- Raw SKILL.md: https://api.skillmd.com/api/skills/useretrace/inventory-health-report/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: useretrace (https://skillmd.com/u/useretrace)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/useretrace/inventory-health-report

---


# Inventory Health Report

Unified per-SKU replenishment analysis. Computes safety stock, reorder point, EOQ, turnover, sell-through, days of stock, and demand variability (XYZ) — then classifies each SKU with an actionable status flag. Three outputs every run (CSV, PNG, PDF).

## When to use this skill

Activate when the user:
- Wants to know what to order, when, and how much
- Asks about safety stock, reorder points, or economic order quantity
- Has Shopify exports and wants replenishment recommendations
- Mentions stockout risk, overstock, or inventory planning
- Wants to assess inventory health across their catalog

## Prerequisites

Before running, ensure Python 3.9+ is available and install dependencies:

```bash
pip install -r "$SKILL_DIR/scripts/requirements.txt"
```

Resolve `SKILL_DIR` to the installed skill root first. If `pip install` fails due to permissions, try `pip install --user -r "$SKILL_DIR/scripts/requirements.txt"` or use a virtual environment.

## Input

- **Orders CSV** (required): Shopify Admin → Orders → Export, or any CSV with SKU, quantity, date, and price columns
- **Products CSV** (optional but recommended): Shopify Admin → Products → Export. Provides stock levels, cost data, and titles. Without it, only demand-side metrics are available.
- **Lead time** (recommended): Either a global value via `--lead-time` or a per-SKU column in the products CSV via `--lead-time-col`. Without lead time, Stockout Risk and Reorder Now flags are unavailable.

## Running the report

Resolve the installed skill root first. The exact path depends on where the skill was installed in the current environment.

```bash
SKILL_DIR="<resolved-installed-skill-dir>"

python "$SKILL_DIR/scripts/inventory_health.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --lead-time 14 \
  --output-dir ./health-output
```

### All flags

| Flag | Default | Description |
|------|---------|-------------|
| `--orders` | *(required)* | Orders/sales CSV |
| `--products` | — | Products CSV for stock, cost, titles |
| `--output-dir` | `./health-output` | Output directory |
| `--window` | `90` | Analysis window in days |
| `--lead-time` | — | Global lead time in days |
| `--lead-time-col` | — | Per-SKU lead time column in products CSV |
| `--service-level` | `0.95` | Target service level (0.50–0.9999) |
| `--ordering-cost` | — | Fixed cost per order in $ (for EOQ) |
| `--holding-cost` | `0.25` | Annual holding cost as fraction of product cost |
| `--overstock-days` | `180` | Days-of-stock threshold for overstock flag |
| `--sku-col` | auto | SKU column (generic CSVs) |
| `--date-col` | auto | Date column (generic CSVs) |
| `--quantity-col` | auto | Quantity column (generic CSVs) |
| `--revenue-col` | auto | Revenue column (generic CSVs) |
| `--cost-col` | auto | Cost column (generic CSVs) |
| `--stock-col` | auto | Stock column (generic CSVs) |
| `--products-sku-col` | auto | SKU column in products CSV when it differs from the orders file |
| `--csv-only` | `false` | Skip PNG and PDF generation (faster, CSV only) |

> **Lead time resolution:** When both `--lead-time` and `--lead-time-col` are provided, per-SKU values take priority. The global `--lead-time` fills in SKUs that don't have a per-SKU value.

### Examples

Shopify exports with 14-day lead time:
```bash
python "$SKILL_DIR/scripts/inventory_health.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --lead-time 14
```

90-day window with EOQ:
```bash
python "$SKILL_DIR/scripts/inventory_health.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --lead-time 14 \
  --ordering-cost 25 \
  --window 90
```

Higher service level for critical inventory:
```bash
python "$SKILL_DIR/scripts/inventory_health.py" \
  --orders orders_export.csv \
  --products products_export.csv \
  --lead-time 14 \
  --service-level 0.99
```

## Output

Three files every run:

1. **`inventory_health_report.csv`** — Per-SKU metrics: SKU, Title, Status, Demand Variability (X/Y/Z), Avg Daily Demand, Demand Std Dev, CV, Demand Trend %, Current Stock, Days of Stock, Sell-Through %, Turnover Ratio, Lead Time, Safety Stock, Safety Stock Reliability, Reorder Point, EOQ, Revenue, Units Sold, Cost per Unit.

Sorted by status priority (Stockout Risk first), then days of stock ascending within each status. This sort is intentional — the most urgent items appear at the top.

2. **`inventory_health_chart.png`** — Two panels: stock position scatter (days of stock vs sell-through, colored by status, sized by revenue) and status distribution bars (% SKUs vs % revenue).

3. **`inventory_health_report.pdf`** — Multi-page report: summary with status counts and key findings, analysis and recommendations per status flag, demand variability summary, service level guidance, caveats, numbered next steps, embedded chart, a "SKUs Requiring Action" table, and a "Full Catalog Reference" appendix.

## Status flags

Each SKU gets exactly one flag (priority cascade):

| Priority | Flag | Condition | Action |
|----------|------|-----------|--------|
| 1 | **Stockout Risk** | Days of stock < lead time | Emergency order |
| 2 | **Reorder Now** | Stock ≤ reorder point | Standard reorder |
| 3 | **Overstock** | Days of stock > 180 (configurable) | Reduce quantities |
| 4 | **No Stock** | Stock = 0 with active demand | Replenish immediately |
| 5 | **No Demand** | Zero sales in window | Review / discontinue |
| 6 | **Healthy** | None of above | Maintain cadence |

## Demand variability (XYZ)

Each SKU with active demand gets a demand predictability classification:

| Class | CV Range | Meaning | Safety stock reliability |
|-------|----------|---------|------------------------|
| **X** | < 0.5 | Stable, predictable | High — formula accurate |
| **Y** | 0.5 – 1.0 | Variable, possibly seasonal | Moderate — review seasonality |
| **Z** | ≥ 1.0 | Erratic, sporadic | Low — manual review recommended |

## Presenting results

After the script runs:
1. **Check degraded mode first** — if any data was missing (no lead time, no stock, no cost), tell the user upfront what's unavailable and why. "Without lead time, I can't flag stockout risk or calculate reorder points."
2. Lead with **status flag counts** — how many items need action, highlighting urgency
3. For **Stockout Risk and Reorder Now items**, quote the reorder point and EOQ (if available) as specific quantities: "SKU-123 has 15 units left with a reorder point of 40 — order at least 25 units"
4. Name the **top stockout-risk SKUs** by revenue — these are urgent
5. Highlight **erratic-demand items** (Z-class) where safety stock may be unreliable — note that the computed safety stock for these items is a rough guide, not a precise number
6. Present **overstock value** if cost data was available
7. Note the **service level used** (default 95%) and mention the A/B/C differentiation recommendation: "For your highest-revenue items, consider re-running at 99%"
8. For **Z-class items in Stockout Risk**, note that the safety stock number is less reliable — manual judgment needed
9. Show the PNG chart inline if the environment supports images
10. Point to the PDF for full analysis, caveats, and per-SKU detail
11. Reference the bundled `reference.md` for formula explanations

## Degraded modes

The skill works with progressively less data:
- **No lead time**: Stockout Risk and Reorder Now unavailable. Only Overstock, No Stock, No Demand, and Healthy flags.
- **No products CSV**: Only demand-side metrics (avg daily demand, demand variability). No stock, sell-through, turnover, or reorder metrics.
- **No cost data**: EOQ unavailable. All other metrics work.

When presenting orders-only results, acknowledge the limitation upfront: "Without product data, I can show demand metrics (velocity, variability, XYZ classification) but not stock adequacy, sell-through, or reorder calculations. Providing a products CSV would unlock the full analysis."

## Edge cases

- **Single SKU**: Classified normally
- **All healthy**: Reports zero action items
- **Zero demand across all SKUs**: Script exits with error (no orders in window)
- **Short window** (< 180 days): Caveat about seasonal misclassification
- **All Z-class (erratic demand)**: Explicit caveat that safety stock estimates are unreliable across the board

