Files
worldmonitor/tests
Elie Habib aeef68dd56 fix(relay): envelope-aware Redis reads restore chokepoint transit chart (#3139)
* fix(relay): envelope-aware Redis reads for PortWatch/CorridorRisk/stocks-bootstrap

PR #3097 migrated 91 seed producers to the contract-mode envelope shape
{_seed, data}, but ais-relay's private upstashGet() reads raw JSON and
does not unwrap the envelope. Three callsites in the relay now see the
wrapper metadata as the payload and silently corrupt downstream:

- seedTransitSummaries() iterates {_seed, data} as chokepoint IDs and
  writes supply_chain:transit-summaries:v1 with keys "_seed" and "data",
  both mapping to empty-history summary objects. Every chokepoint's
  transitSummary.history is therefore empty, which gates off the
  time-series chart in SupplyChainPanel and MapPopup waterway popup.
- loadWsbTickerSet() reads market:stocks-bootstrap:v1 and sees
  data.quotes === undefined, silently disabling WSB ticker matching.

Fix: add envelopeRead(key) next to envelopeWrite — mirrors the
server/_shared/redis.ts::getCachedJson semantics (envelope-aware by
default; legacy raw shapes pass through unchanged). Swap the three
upstashGet calls that target contract-mode canonical keys.

After the relay re-seeds at its 10-min cadence, transit-summaries:v1
will contain a proper {hormuz_strait, suez, ...} map and the chart
comes back in the panel and map popup.

Unit tests cover contract-mode unwrap, legacy passthrough, null, and
the array-with-numeric-indices false-positive edge case. Existing
static assertions updated to guard against regression to raw
upstashGet on these keys.

* fix(backtest): envelope-aware reads in resilience backtest scripts

backtest-resilience-outcomes.mjs reads economic:fx:yoy:v1, infra:outages:v1,
and conflict:ucdp-events:v1 — all migrated to the {_seed, data} envelope by
PR #3097. The private redisGetJson helper did not unwrap, so AUC computation
was silently running against the envelope wrapper instead of the country
event maps (same class of bug as PR #3139's relay fix, offline blast radius).

validate-resilience-backtest.mjs uses the same read pattern across multiple
family keys and is fixed for the same reason.

Both scripts now import unwrapEnvelope from _seed-envelope-source.mjs (the
canonical ESM source of truth used by seed-chokepoint-flows.mjs,
seed-energy-spine.mjs, seed-forecasts.mjs, and others). Legacy raw shapes
still pass through unchanged.

* fix(relay): envelopeRead for OREF_REDIS_KEY bootstrap (Greptile P1)

orefPersistHistory() writes OREF_REDIS_KEY via envelopeWrite at line 1133,
but the bootstrap reader at line 1214 was still using raw upstashGet.
cached.history was therefore undefined and Array.isArray() always false,
so OREF alert history was never restored from Redis after a relay restart
— every cold start hit the upstream API unnecessarily.

Also adds the two regression guards Greptile flagged as missing:
- loadWsbTickerSet() reading market:stocks-bootstrap:v1 via envelopeRead
- orefBootstrapFromRedis reading OREF_REDIS_KEY via envelopeRead

Same class of bug as the three callsites fixed earlier in this PR.
2026-04-17 08:12:07 +04:00
..