feat: alerts store — track APEX notifications with unseen badge - #28
Merged
Conversation
Tracks ALERTS_ALERTS (bulk), ALERTS_ALERT (single), and ALERTS_ALERTS_DELETED messages into a Zustand entity store, mirroring the refined-prun alertsStore pattern. https://claude.ai/code/session_013u5JnLg2kZSaDHnHDBzmKJ
Wire payload shows exchange values arrive as objects with id/name/code/_type. https://claude.ai/code/session_013u5JnLg2kZSaDHnHDBzmKJ
- Header: show (N) in prun-yellow next to SHOW APEX when unseen alerts exist - content.tsx: expose window.apxm.alerts after UI mounts for console inspection https://claude.ai/code/session_013u5JnLg2kZSaDHnHDBzmKJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds full support for APEX's notification/alerts system (
ALERTS_*WebSocket messages), mirroring the pattern used by refined-prun'salertsStore. Unseen alerts are surfaced in the UI via a gold badge on the SHOW APEX button, and awindow.apxmdebug handle makes store inspection easy from the browser console.What changed
New:
stores/entities/alerts.tsA Zustand entity store keyed by
alert.id, created withcreateEntityStore— the same factory used by contracts, ships, flights, etc. No persistence (alerts are session-lived; the server re-sends them on reconnect).New types in
types/prun-api.tsPrunApi.Alert— matches the wire format exactly:id,type,contextId,naturalId,time(DateTime),data(AlertData[]),seen,readPrunApi.AlertData—{ key: string; value: string | AlertDataEntity }. The value field is polymorphic: simple keys likecommoditycarry a plain string, entity keys likeexchangecarry an object withid / name / code / _type. This was confirmed against a live WS capture.PrunApi.AlertType— union of ~20 known string literals (PRODUCTION_ORDER_FINISHED,SHIP_FLIGHT_ENDED,COMEX_ORDER_FILLED, etc.) plusstringas a fallback for types not yet seen in the wild.Three message handlers in
stores/message-handlers.tsALERTS_ALERTSsetMany+setFetched('websocket')— bulk dump on loginALERTS_ALERTsetOne— new or updated single alertALERTS_ALERTS_DELETEDremoveOneloop overalertIdsAll handlers go through the existing
extractPayloadhelper and follow the same guard/warn pattern as every other handler in the file.stores/entities/index.tsuseAlertsStoreandAlertsStoreexporteduseAlertsStore.getState().clear()added toclearAllEntityStores()(called on reconnect)useAlertsStoreadded to theallStoresbatch array so it participates in the two-layer shadow-batching system that prevents React error #185 during login burstsUI: unseen badge on SHOW APEX (
components/layout/Header.tsx)When any stored alert has
seen === false, a gold(N)appears inline to the right of the SHOW APEX text. The selector iteratesentities.values()directly (no intermediate array) and returns a plain number, so the header only re-renders when the count actually changes.Console debug handle (
entrypoints/content.tsx)After the React overlay mounts,
window.apxmis set with a reference to the store. Useful for verifying alerts are being received without needing the diagnostic overlay:Batch pipeline note
Alert store mutations go through
beginEntityBatch/endEntityBatchlike every other entity store. No special handling needed —createEntityStore's shadow state mechanism takes care of it automatically once the store is added to theallStoresarray inindex.ts.Generated by Claude Code