# Polleo Demand — Project Context for Claude Code

## What This Is
Polleo Demand is a demand forecasting system (currently v3.5) for Polleo Sport, a sports nutrition/retail company. It supports an S&OP cycle with weekly and monthly rhythm. The system must be usable by non-technical stakeholders (demand planners, KAMs, CMs) — no Python knowledge required.

## How It Runs
- One-click launcher: `Start_Polleo_Demand.bat` (uses `subprocess` with `stdin=subprocess.DEVNULL`, absolute paths)
- Streamlit web app (`app.py`) with 9 pages covering the full planning workflow
- Python 3.12 is the stable target. **Do NOT use Python 3.14** — it lacks scipy wheels and causes installation failures.
- pip installs require `--break-system-packages` flag

## Forecasting Architecture
- Built on Nixtla's **StatsForecast** library
- Channel-split forecasting: retail + wholesale forecasted separately, then summed
- Models used: AutoARIMA, AutoCES, AutoTheta, CrostonOptimized, ADIDA, IMAPA, TSB
- **NEVER use Holt / Holt-Winters** — explicitly removed due to confirmed instability from data analysis. Do not reintroduce anywhere.

## Critical Rules & Guardrails

### Promo Detection
- Threshold: 10% discount (raised from 5% — the lower threshold was too aggressive)
- Cleaning is **skipped** when >40% of weeks are flagged as promo OR 4+ consecutive recent weeks are flagged
- Ground-truth ERP promo calendar (`erp_promo_calendar.csv`) drives uplift (`sku_uplift.csv` / `cat_uplift.csv`) via `recalc_uplift_erp.py`, which is chained automatically at the end of `update_sales.py`.
- Statistical promo flags (`is_any_promo`, `retail_discount_pct`, `is_wholesale_spike`) are still written into `sales_clean.csv` because the GBR model in `forecast_engine.py` uses them as features — don't strip these.

### Sanity Bounds on Forecasts
- **Cap**: 2× recent 13-week average (prevents runaway forecasts)
- **Floor**: 50% of 8-week median (prevents zero/near-zero forecasts)
- These are essential — do not remove or weaken them

### Accuracy Expectations
- Bronze SKUs structurally drag accuracy due to low-volume volatility — this is expected, not a model failure
- Gold-tier SKUs benefit most from promo data improvements (higher promo frequency and volume)
- Accuracy is tracked by tier (Gold/Silver/Bronze) to separate structural vs. model issues

## Key Data Files
- `sales_clean.csv` — main sales history (retail, webshop, wholesale quantities + promo flags)
- `sku_plan_list.csv` — SKU master list with ABC tier (`oznaka`), XYZ classification, CV, wholesale share
- `vp_input.csv` / `mp_input.csv` — wholesale (VP) and retail (MP) planner inputs (aggregated)
- `vp_input_detail.csv` / `mp_input_detail.csv` — per-KAM/CM detail before aggregation
- `erp_promo_calendar.csv` — ground-truth promo calendar from ERP (SKU + year + week + promo type)
- `sku_uplift.csv` — per-SKU promo uplift factors (retail + wholesale spike)
- `cat_uplift.csv` — category-level promo uplift fallback
- `sku_category_map.csv` / `sku_subcat_map.csv` — SKU to category/subcategory mapping
- `sku_prices.csv` — pricing data per SKU
- `backtest_fa.csv` — backtest results (forecast vs actual by SKU/week/model)
- `kam_cm_config.json` — KAM/CM configuration
- `config_toml.txt` — app configuration

## KAM/CM Input Workflow
- Input collected via pre-filled Excel templates
- Color coding: green = previous entries, yellow = new input needed
- Multiple KAM/CM inputs are combined by summing quantities per SKU
- Template generation and combining happens in the app

## Active Improvement Areas (as of April 2026)
1. **ERP promo calendar integration** — highest leverage improvement. Replace noisy statistical promo detection with clean ERP-sourced baseline. Gold-tier SKUs benefit most. Wholesale retains spike detection logic. `erp_promo_calendar.csv` and `build_erp_promo.py` / `recalc_uplift_erp.py` are already in place.
2. **ABC-XYZ classification** — already computed in `sku_plan_list.csv` (columns: `ws_xyz`, `total_xyz`, `ws_cv`, `total_cv`). Integration into app UI (filter dropdowns, accuracy slicing by XYZ class) estimated at ~1 hour.
3. **Potential future**: tying model selection to XYZ class, `.bat` launcher auto-installing dependencies on new setups.

## Development Approach
- Iterative, versioned development with explicit rationale for each change
- Backtest-driven validation before committing to major changes
- Non-technical usability is a hard constraint
- When in doubt, run a backtest comparing before/after

## Users
- Lovro (primary developer / demand planner)
- mgelencir (colleague, co-uses the system)
- KAMs and CMs (provide wholesale/retail input through Excel templates)

## Common Pitfalls to Avoid
- Don't assume promo detection is working well — it's a known weak spot being replaced by ERP data
- Don't remove sanity bounds even if they seem to clip good forecasts — they prevent catastrophic failures
- Don't upgrade to Python 3.14+
- Don't add Holt/Holt-Winters back into the model pool
- Don't make any workflow require Python/terminal knowledge from end users
