# Phase 3 — Inventory operations rollout

## Scope shipped
- **Inventory ledger** (`clients/{clientId}/inventoryLedger/{eventId}`): sale, purchase, refund, adjustment, wastage with `beforeQty` / `afterQty`, `sourceRef`, `createdAt`, `createdByUid`.
- **Atomic writes**: POS checkout/refund, purchase confirm, dashboard order confirm, inventory manual adjustment — stock + ledger in one RTDB `update` where applicable.
- **Weighted SKU + PLU**: product fields (`isWeighted`, `pluCode`, weights, reorder); POS weight modal + optional **Web Serial** scale; order lines carry `uom`, `weightSource`, `weightDeviceId`.
- **Reorder suggestions** on purchase-add (min–max).
- **Dead stock** heuristic (60 days no sale + stock &gt; 0) on inventory + analytics KPI.
- **Guardrails**: negative stock blocked on web order confirm, POS checkout, inventory adjustment; wastage via `shrinkage` reason → ledger `wastage`.

## Staged rollout (recommended)
1. **Shadow / verify**: spot-check `inventoryLedger` events after real POS sales and purchases; reconcile `beforeQty`/`afterQty` vs product stock.
2. **Reorder live**: set `reorderEnabled` + min/max on a few SKUs; validate purchase suggestions.
3. **Weighted pilot**: enable `isWeighted` on one counter SKU; test manual weight then one **Chrome/Edge** machine with USB serial scale.
4. **Full**: train staff on adjustment reasons; weekly dead-stock review from analytics + inventory panels.

## Permissions
- Inventory **manual adjustment / wastage**: same gate as inventory page (`products` panel).
- Purchase-add / POS: unchanged existing panel keys (`purchase-add`, `pos`).

## Compatibility notes
- **Web Serial** for scales: Chromium desktop; always keep **manual weight** path (mandatory fallback).
- Ledger volume: monitor RTDB size; if needed, introduce monthly path (e.g. `inventoryLedgerByMonth/YYYYMM/...`) in a follow-up migration.
