# Changelog

## [Unreleased]

### Added
- **Producer capture — wine type totals strip**: Editable summary (Still / Sparkling / Fortified / Wine Component) between context dropdowns and Step 1 / Step 2. Saved as `wine_class_totals`; `grand_total` = sum of those classes. Fortified / wine-component lumps emit a synthetic size row and a matching back-page `TOTAAL` so recon does not fail with 300 vs 0.

### Security
- **npm audit (2026-08-05)**: Cleared most reported vulnerabilities without ejecting `react-scripts@5`.
  - Ran `npm audit fix` (axios, babel, brace-expansion, form-data, http-proxy-middleware, js-yaml, shell-quote, websocket-driver, ws, etc.).
  - Direct bumps: `axios` ^1.19.0, `http-proxy-middleware` ^2.0.10, `echarts` ^6.1.0 (XSS), `react-router-dom` ^7.18.2 (open-redirect / related advisories).
  - Overrides: `body-parser` ^1.20.6, `postcss` ^8.5.25, `svgo` ^2.8.3, `webpack-dev-server` 5.2.6.
  - Remaining: 2 high findings on `react-router` RSC CSRF (GHSA-qwww-vcr4-c8h2). Fix needs `react-router` ≥8.3 + React ≥19; not applicable to this CRA SPA (no RSC). Downgrading to 7.11 would reintroduce open-redirect. Production build verified.

### Added
- **Capture local draft**: Auto-saves capture form to `localStorage` (debounced) per user + submission. Restores on reload with a banner. Cleared on submit; logout clears all browser storage.

### Changed
- **Save draft is advisory-only for mismatches**: Draft save always persists totals when the API accepts them. Lump sync, reconciliation, and wine-type/step mismatches warn in the banner but no longer abort Save draft. Submit still requires a complete match.
- **Plain-language messages**: Capture, admin, review, and API feedback use `src/utils/userFacingMessages.js` — simpler wording, no BR-15 / TOTAAL / reconciliation jargon in fallbacks.
- **Review submission totals**: Left footer sums package/size volumes; right footer sums cultivar line items. A warning shows when they differ.
- **Capture wine type totals**: Strip inputs come from GET lookups `cultivars_by_heading` labels (not the four hardcoded Still / Sparkling / Fortified / Wine Component fields). `wine_class_totals` is saved under those heading keys.
- **Super Admin capture**: Role 4 may open capture with no assigned codes. Producer Code is a text field (Enter / blur looks up the return); API error messages (e.g. unknown PRODKODE) show on the form. Roles below 4 keep the dropdown.
- **Session persist on refresh**: Auth is stored as a named `sawisAuth` cookie (`path=/`) plus a `localStorage` backup. Session expiry is **401 only** — not 403 or “denied” in the response body.
- **Capture Step 1**: One accordion per package type (Cans, Glass, …) with sizes under it. Still and sparkling are not listed as separate container groups; wine-type split stays on the totals strip.
- **Admin submissions status actions**: Roles 2 / 3 / 4 can **Cancel** submissions when status is Open or Submitted, which locks editing. Roles 2 / 4 can **Open up** submissions from Cancelled or Missed back to Open.
- **Admin users**: Promote is hidden for Super Users (role 3); **Demote** sets them back to User (role 0). After Save / Promote / Demote the Manage sidebar reloads.
- **Capture return status**: Badge sits on the producer / period / territory row (not the page title). The form shell uses a status-coloured left border so Open / Submitted / Approved / Synced / Cancelled is obvious for that return.
- **Domestic reports filters**: Moved into the Domestic Sales card (exports Price Range layout) — Filters toggle, wrap-grid dropdowns, green Reset / Apply. Grape / vineyard tables unchanged.
- **Capture Step 1 editing labels**: Selected size and its wine-class / container headings show the standard **editing** badge.
- **Capture period dropdown**: Last 12 months from today’s date (not the selected period or a hardcoded month).
- **Past submissions table**: Columns are Period, Status, Producer Code, Territory, Actions. **ID** removed; **View** opens that submission in a capture modal (context locked). Capture context dropdown label is also **Producer Code**.
- **Logout / invalid session**: Clears all JS-visible cookies, `localStorage`, and `sessionStorage` (explicit sign-out and 401/403).
- **Producer capture — Submit for verification**: Confirmed flow uses `POST auth/domestic/submissions/{id}/submit` (no body); pre-check via `GET …/reconciliation`. Does not PUT submission `status`.
- **Admin portal — DAFF (role 1)**: Sees **Tools** only — no User management or SAWIS 7 Submissions. Direct URLs redirect to `/admin/tools`.
- **Admin portal — Super User (role 3)**: Sees **User management** and **SAWIS 7 Submissions** (no Tools). `/admin` lands on submissions; `/admin/tools` redirects away.
- **Vineyard Status reports**: `GenericPivotTable` uses **GET** (with filter query params) for URLs from `getVineyardStatusReports` / `Type: VineyardStatus`. Grape Production reports still use POST. CRA `setupProxy` now forwards `/vineyardStatus/*`.
- **Domestic Sales login required**: Navbar link and Home card are hidden when logged out. `/domestic/*` uses `AuthRouteGuard` and redirects to `/` if there is no session.
- **Domestic Sales tab bar**: Hidden entirely when the user lacks SAWIS 7 `can_capture` (no lone Reports pill).
- **Exports proxy / session**: CRA `setupProxy` now forwards all `/get*` and `/tables` export APIs (not only `/getFilters`). Export fetch failures no longer force logout unless the response is 401/403.

### Changed
- **Domestic reports**: Hide **Generate Report** and **Clear** toolbar buttons (filters **Apply** drives refresh; grape/vineyard unchanged).

### Fixed
- **Submissions Actions column**: Restored RDT column min-widths (removed `min-width: unset`) so Review/View/Open is no longer flex-crushed off-screen; labelled column **Actions**.
- **Capture litre inputs**: Typing no longer fights `0.00` reformatting — draft string while focused, two decimals on blur (`LitresInput`). Minus / paste negatives blocked; state handlers clamp to ≥ 0.
- **Submissions list Firefox layout**: Period is a month dropdown (Firefox has no `type=month` picker). Table CSS no longer forces `min-width: 0` / flex overrides that crushed columns into vertical character stacks. Restored `admin-portal.css` import.
- **User management drawer styles**: Restored missing `admin-users.css` import on `UsersListPage` (it was dropped when plain-language messages were added).
- **PUT assignment `domestic_producer`**: sends the logged-in user’s id (session, JWT, or users-list email match), not `0`.
- Navigating to Exports (`/reports`) while logged in no longer clears the session when chart/table calls 404 against the CRA server.

### Security (earlier)
- **npm audit (2026-03-05)**: Resolved 12 remaining vulnerabilities (11 low, 1 high).
  - **package.json overrides**: Added `@tootallnate/once`: `^3.0.1` to fix Incorrect Control Flow Scoping (GHSA-vpq2-c234-7xj6) in the jest/jsdom chain used by react-scripts, without downgrading react-scripts. Added `svgo`: `^2.8.1` to fix SVGO DoS via entity expansion (GHSA-xpqw-6gx7-v673) in postcss-svgo.
  - `npm audit` now reports 0 vulnerabilities.
- **npm audit**: Resolved all reported vulnerabilities.
  - Ran `npm audit fix` (ajv, axios, minimatch, qs, rollup, etc.).
  - **package.json overrides**: Bumped `webpack` to `5.104.1` (fixes buildHttp SSRF GHSA-8fgc-7cc6-rx7x, GHSA-38r7-794h-5758). Overrode `bfj` to `9.1.3` so the dependency tree no longer uses vulnerable `jsonpath` (GHSA-87r5-mp6g-5w5j). Overrode `serialize-javascript` to `^7.0.3` (fixes RCE GHSA-5c6j-r48x-rmvq in transitive deps from react-scripts/workbox).
  - **Node 18 compatibility**: Added `patches/serialize-javascript+7.0.4.patch` so that `serialize-javascript@7.x` (required for the RCE fix) works on Node 18, where `global.crypto` is not available; the patch uses `require('crypto').webcrypto` as fallback. Applied automatically via `patch-package` on `npm install`.
  - `npm audit` now reports 0 vulnerabilities. Build verified with `npm run build`.
