--- name: nomenclature-context-sse-dispatch description: How handleSSEUpdate in NomenclatureContext.jsx routes an SSE message's object/operation to state mutations metadata: type: project --- `frontend/src/contexts/NomenclatureContext.jsx`'s `handleSSEUpdate(message)`: 1. Special-cases `object === 'nomenclature' | 'nomenclature_entry' | 'extra_combination'` and `object === 'invoice' | 'notice'` — these just fan out to `subscribersRef` callbacks and return early, bypassing the nomenclature-array logic entirely. 2. Otherwise maps `message.object` (the SSE `sseObjectType`, e.g. `'vehicle'`) to a `nomenclatureKey` (e.g. `'vehicles'`) via `getNomenclatureKeyFromSSE`, which just looks up `NOMENCLATURES_CONFIG` by `sseObjectType` — this mapping is operation-agnostic, so it already works correctly for any new operation string on an existing object type (no changes needed there when adding new operations). 3. Inside `setNomenclatures(prev => {...})`, an `if/else if` chain on `operation` decides how to mutate `prev[nomenclatureKey]`: - `'insert'`: skip if `id` already present, else `insertSorted`. - `'update'`: `updateSorted` (removes old, re-inserts at sorted position, or falls back to `insertSorted` if the item wasn't present at all). - Falls through to `return prev` (no-op) for anything unhandled — this was true even for the backend's own long-standing `'deleted'` action before this session; there was no delete/removal handling of any kind until Phase B of `.claude/plans/finalize-history-void.md` added `'archived'` (filter out by id) and `'voided'` (update-in-place if present, safe no-op if not) as new `else if` branches alongside `insert`/`update`. `insertSorted`/`updateSorted` (same file, ~line 62 and ~90) are the two shared mutation helpers — always spread-based (`[...array]`, `.filter`, `.map`), never in-place `.push`/`.splice` on the original array. Any new operation case should reuse these two helpers rather than writing new sort/insert logic.