# Polleo Demand — Management Brief
*Knowledge document for Claude project context. Drop into Claude.ai project knowledge to generate presentations, executive summaries, KPI commentary, etc.*

---

## 1. What Polleo Demand is

A demand forecasting and S&OP system for Polleo Sport (sports nutrition / retail). It produces a rolling 13-week SKU-level demand plan that drives:

- **Supply** — purchase order timing, safety stock, coverage alerts.
- **Wholesale (VP)** — KAM commitments on top of the statistical baseline.
- **Retail (MP)** — CM commitments on top of the statistical baseline.
- **CFO view** — stock value roll-forward, revenue forecast, working-capital exposure.

Designed for **non-technical users** (demand planners, KAMs, CMs). One-click launcher, web UI, no Python knowledge required.

Status: production, **v4.0**. Architecture is moving toward a modular monolith deployed to internal IT Docker. Next feature in pipeline: a DP-facing **Promo Planner**.

---

## 2. Planning rhythm — weekly + monthly

| Cadence | Activities | KPIs reviewed |
|---|---|---|
| **Weekly** | Run forecast engine, refresh KAM/CM inputs, generate 13-week plan, push bridge to Supply | Weekly **FA**, **FA signed**, **BIAS**, **Hit Rate**; coverage alerts (`order_now`, `order_next_week`) |
| **Monthly (S&OP)** | Consolidate weekly plans into monthly view, compare actuals vs plan, accuracy review by tier/category | Monthly **FA**, **FA signed**, **BIAS**; tier mix; top error contributors |

Weekly is operational. Monthly is the management/S&OP rhythm.

---

## 3. Forecast Accuracy KPIs (the headline numbers for management)

All four KPIs are measured per SKU × week, then aggregated. Both **weekly** and **monthly** views exist.

### Definitions

| KPI | Formula (per week) | Reads as | Higher / lower better |
|---|---|---|---|
| **FA** (Forecast Accuracy) | `max(0, 1 − |F − A| / A) × 100%` | "How close was the forecast in magnitude?" | **Higher is better** (100% = perfect, 0% = >100% error) |
| **FA signed** | `F / A × 100%` | "Did we over- or under-forecast?" | **Closer to 100% is better**. >100% = over-forecast, <100% = under-forecast |
| **BIAS** | `(F − A) / A × 100%` | Direction & magnitude of systematic miss | **Closer to 0% is better**. Positive = over-forecast |
| **Hit Rate** | % of SKU-weeks with `|F − A| / A ≤ 30%` | Operational quality — "how many SKUs landed in the ±30% band?" | **Higher is better** |

`F` = forecast, `A` = actual sales.

### Why both FA and FA signed?

- **FA** is a one-number health check (0–100%, can't tell direction).
- **FA signed** tells management *which way* we're missing (over vs under).
- A planner with FA = 70% and FA signed = 95% is **under-forecasting by 30% on average** — different intervention than FA = 70% and FA signed = 130%.

### Weekly vs monthly aggregation rule (important)

The system uses **two different aggregation rules** and management should know which they're looking at:

- **Weekly view** → per-week-average. Compute FA per week first, then average across selected weeks. *Mirrors what a planner experiences cadence-by-cadence.*
- **Monthly view** → sum-then-divide. Sum forecast and actual across all weeks in the month, then compute FA on totals. *Mirrors how finance views monthly performance — cancellation within the month is "real".*

Both are correct but answer different questions. **Don't compare a 4-week-average FA to a monthly FA directly** — same data, different numbers.

---

## 4. How accuracy is measured (the data behind the KPIs)

Two sources are merged:

1. **`backtest_fa.csv`** — historical out-of-sample backtest. Each week, the engine forecasts a SKU using only data available before that week, then compares to the actual sale once it lands. Built by `run_backtest.py`.
2. **`forecast_log.csv`** — every live forecast the engine generates is logged with `(sku, target_year, target_week, forecast)`. Once the target week's actual lands in `sales_clean.csv`, FA is computed for that row.

The merged dataset is filtered to `actual > 0` (zero-actual weeks are not informative for accuracy).

This means: **the accuracy you see is real out-of-sample, not in-sample fit.** That's the legitimate measurement.

### Three FA views (separate tabs in the app)

| View | What it measures | Used for |
|---|---|---|
| **Global FA** | Total model forecast vs total actual sales | Headline number. Includes both stat model + KAM/CM on-top. |
| **KAM/CM projections FA** | Only the KAM/CM on-top commitments vs the *channel* actual (VP → wholesale, MP → retail) | Holds each KAM/CM accountable for their own input — separates planner skill from model skill. |
| **Model-only FA** | Statistical forecast vs sales, with the channel a planner committed on **stripped from both sides** | Isolates pure model performance, removes planner influence. |

When management asks "how accurate is the model?" → **Model-only FA**.
When they ask "how accurate is the plan?" → **Global FA**.
When they ask "how reliable are KAM commitments?" → **KAM/CM projections FA**.

---

## 5. Slicing dimensions for accuracy review

Accuracy is **never a single number** — it's structural. The system slices by:

- **Tier (oznaka)** — Gold / Silver / Bronze. Bronze SKUs structurally drag accuracy due to low-volume volatility. **This is expected, not a model failure.** Always show tier breakdown when discussing FA.
- **XYZ class** — variability classification (`ws_xyz`, `total_xyz` in `sku_plan_list.csv`). X = stable, Z = erratic. Z-class SKUs cap how high FA can possibly go.
- **Category** — fitness/clothing/gadgets/etc. Identifies which assortment areas are easy vs hard to forecast.
- **Top error contributors** — top-15 SKUs by absolute error usually account for the bulk of total error. Drill-down view in the app exposes them.
- **Exclude top-N** toggle — lets you re-compute FA after pretending the worst offenders don't exist, to see whether the headline is dragged by a long tail or by a handful of structural problem-children.

**Management framing:** "We track FA at three levels — overall, by tier, and by top contributors — so a single noisy SKU can't hide systemic issues, and structural Bronze noise can't make the model look worse than it is."

---

## 6. Forecasting architecture (technical summary for the brief)

- Built on **Nixtla StatsForecast** library.
- **Channel-split** — retail and wholesale forecasted separately, then summed. (Wholesale is lumpier; separating gets better stat fit.)
- **Model pool**: AutoARIMA, AutoCES, AutoTheta, CrostonOptimized, ADIDA, IMAPA, TSB. Best model is selected per SKU by backtest performance.
- **Holt / Holt-Winters explicitly excluded** — confirmed unstable on this data.
- **Horizon**: 13 weeks rolling.

### Guardrails (why catastrophic forecasts don't happen)

| Guardrail | Threshold | Purpose |
|---|---|---|
| **Cap** | 2 × recent 13-week average | Prevents runaway forecasts on model glitches |
| **Floor** | 50% of 8-week median | Prevents zero / near-zero forecasts dropping shelves |
| **Promo cleaning skip** | If >40% of weeks flagged as promo OR 4+ consecutive recent weeks flagged | Prevents over-aggressive promo "cleaning" that would distort baseline |

These are non-negotiable. They turn rare catastrophic misses into ordinary misses.

### Promo handling

- **Ground truth**: `erp_promo_calendar.csv` — actual promo dates from ERP.
- **Uplift**: `sku_uplift.csv` (per-SKU) / `cat_uplift.csv` (category fallback) — computed via `recalc_uplift_erp.py`.
- **Threshold** for statistical promo flagging: 10% discount (raised from 5% which was too aggressive — too many false positives).
- Statistical promo flags still computed and fed to the GBR feature model — they survive alongside the ERP signal.

---

## 7. KAM/CM input workflow

- Pre-filled Excel templates per KAM/CM. Color coding: **green = previous entries, yellow = new input needed**.
- Multi-sheet uploads supported (one sheet per buyer).
- When the same SKU appears across multiple sheets: **MAX per (sku, type)** across buyers, then SUM.
- KAM/CM inputs are applied as **on-top** to the statistical baseline, not as replacements.
- Per-KAM detail is preserved in `vp_input_detail.csv` / `mp_input_detail.csv` — enables per-customer exclusion analysis (e.g., "what if KAM X doesn't deliver?").

---

## 8. Output handoff to other modules

- **Supply module** reads `forecast_for_supply.csv`, built as `TOTAL = baseline × factor + VP on-top + MP on-top`. Auto-refreshes when the demand plan is saved.
- **Stock projection** uses this bridge to roll stock forward 15 weeks. Combines WH stock + store stock (HR/AT/SLO).
- **Long-tail SKUs** (stock but no forecast) get a 13-week trailing-average demand proxy so CFO sees the full picture.

---

## 9. Current state of accuracy work

Accuracy expectations management should hear:

- **Gold-tier FA**: highest, benefits most from promo data improvements (higher promo frequency and volume).
- **Bronze-tier FA**: structurally lower — low-volume volatility is irreducible. Tracking trend matters more than level.
- **Overall FA without exclusions**: tracked weekly. Use the "exclude top-N" toggle to see whether headline drag is broad or concentrated.

Active improvement areas:

1. **ERP promo calendar integration** — replacing noisy statistical promo detection with clean ERP-sourced baseline. Highest leverage on Gold tier. *Status: data in place, calibration in progress.*
2. **ABC-XYZ classification UI integration** — XYZ already computed (`ws_xyz`, `total_xyz`), pending exposure in app filters and accuracy slicing. *Est. ~1 hour to wire up.*
3. **Promo Planner (DP-facing)** — next feature build. Will let DPs schedule promos and see forecast impact in real time before committing.
4. **Possible**: tying model selection directly to XYZ class.

---

## 10. People & ownership

- **Monika** — primary demand planner (daily user).
- **Lovro** (lljutic@polleosport.com) — builder of the system; covers DP role during Monika's holiday. Not a daily user.
- **KAMs / CMs** — provide wholesale/retail input via templates.
- **Management audience** — uses S&OP monthly review primarily.

---

## 11. Suggested presentation structure (slide outline)

For a 20–30 min management deck:

1. **Title** — Polleo Demand: from spreadsheet to S&OP system
2. **What it does** — one diagram: ERP → sales → forecast engine → demand plan → supply / VP / MP / CFO
3. **Weekly rhythm** — what happens each Monday, who touches what
4. **Monthly rhythm (S&OP)** — accuracy review, KPI dashboard, top contributors
5. **The 4 KPIs explained simply** — FA, FA signed, BIAS, Hit Rate (one slide, with the "FA = magnitude, FA signed = direction" framing)
6. **Three FA views** — Global / KAM·CM / Model-only — and what management asks each one
7. **Current performance** — headline numbers (pull live from app), with tier breakdown
8. **Why Bronze drags** — structural volatility, not model failure; what we track instead (trend, hit rate)
9. **Top error contributors** — drill-down example (which 5 SKUs hurt FA most last month, and what we're doing)
10. **Guardrails** — cap, floor, promo-cleaning skip; why catastrophes don't happen
11. **ERP promo integration** — before/after on a Gold SKU
12. **What's next** — Promo Planner, XYZ slicing in UI, modular monolith deploy
13. **Asks / decisions** — anything you need management to approve

### Slides to *not* include
- Code details, library names, file paths — management won't engage.
- Per-SKU lists — drill-down is for the app, not the deck.
- Apology slides about Bronze accuracy — frame it as "structural noise we measure and isolate," not "we're bad at Bronze."

---

## 12. KPI cheat-sheet to paste into the deck

> **FA (Forecast Accuracy)** — 0–100%. How close the forecast was in magnitude. Higher is better.
>
> **FA signed** — % of actual we forecasted. 100% = perfect. <100% = under-forecast. >100% = over-forecast.
>
> **BIAS** — systematic direction of error. 0% = balanced. Positive = chronic over-forecast.
>
> **Hit Rate** — % of SKU-weeks within ±30% of actual. Operational quality measure.
>
> **Weekly view** = average of per-week numbers. **Monthly view** = sum-then-divide on the month's totals. Different by design — don't compare across.

---

## 13. Reference — where to look in the app

| Page | What it shows |
|---|---|
| **Forecast Accuracy** | All three FA views (Global / KAM·CM / Model-only), weekly + monthly tables, exclusions, top errors, downloads |
| **Demand Planning** | Per-SKU / per-category baseline + factors + VP/MP on-top, what-if toggles |
| **Stock projection** (Supply) | 15-week stock roll-forward, units + €, per-KAM VP exclusion |
| **Dashboard** | Top-level health, exceptions, snapshots |
| **Update sales** | Weekly data refresh entry point |

---

*End of brief.*
