Files
worldmonitor/tests/country-chokepoint-index.test.mts
Elie Habib 5c1fcc18fe fix(supply-chain): flow-weighted per-sector chokepoint exposure (#3017)
* fix(supply-chain): flow-weighted per-sector chokepoint exposure (#2968)

COUNTRY_PORT_CLUSTERS is country-level, producing identical scores for
all sectors. Replace with flow-weighted model that reads bilateral HS4
trade data (exporter shares) to differentiate sector exposure by actual
supplier routing through chokepoints.

* fix(chokepoint): short-cache fallback when bilateral data is transiently unavailable

loadBilateralProducts() now returns { products, transient } instead of
just products|null. When bilateral HS4 data is unavailable due to a
transient state (lazy fetch in-flight or Comtrade 429), the fallback
exposures are cached for 60s instead of 24h. This prevents nine sectors
from being stuck on country-level fallback scores for a full day when
the bilateral payload arrives moments after the first lazy fetch.

Replaced cachedFetchJson with manual getCachedJson + setCachedJson to
vary the TTL based on whether bilateral data was available.

* fix(lazy-hs4): distinguish 429 from server errors, fix raw key writes

Two fixes in _bilateral-hs4-lazy.ts:

1. fetchComtradeBilateral now returns { products, rateLimited, serverError }
   instead of null for all non-2xx. Transient 500/503 no longer writes a
   24h rateLimited sentinel, allowing immediate retry on next request.
   Only real 429s write the sentinel.

2. All setCachedJson calls now pass raw=true to match the raw=true reads.
   Seeds write these keys unprefixed; without raw=true on writes, lazy-fetch
   results were invisible to readers in prefixed environments.

* fix(chokepoint): treat lazy server-error path as transient

comtradeSource 'lazy' with empty products is the upstream 500/timeout
path from _bilateral-hs4-lazy.ts. Without including it in the transient
check, fallback exposures were still cached for 24h on server errors.
2026-04-12 20:29:50 +04:00

8.3 KiB