feat(economic): EIA weekly crude oil inventory seeder (#2142) (#2168)

* feat(economic): EIA weekly crude oil inventory seeder (#2142)

- scripts/seed-economy.mjs: add fetchCrudeInventories() fetching WCRSTUS1, compute weeklyChangeMb, write economic:crude-inventories:v1 (10-day TTL)
- proto/worldmonitor/economic/v1/get_crude_inventories.proto: new proto with CrudeInventoryWeek and GetCrudeInventories RPC
- server/worldmonitor/economic/v1/get-crude-inventories.ts: RPC handler reading seeded key with getCachedJson(..., true)
- server/worldmonitor/economic/v1/handler.ts: wire in getCrudeInventories
- server/gateway.ts: add static cache tier for /api/economic/v1/get-crude-inventories
- api/health.js: crudeInventories in BOOTSTRAP_KEYS + SEED_META (maxStaleMin: 20160, 2x weekly cadence)
- src/services/economic/index.ts: add fetchCrudeInventoriesRpc() with circuit breaker
- src/components/EnergyComplexPanel.ts: surface 8-week sparkline and WoW change in energy panel
- src/app/data-loader.ts: call fetchCrudeInventoriesRpc() in loadOilAnalytics()

* fix: remove stray market-implications gateway entry from crude-inventories branch

* fix(crude-inventories): address ce-review P1/P2 findings before merge

- api/bootstrap.js: register crudeInventories in BOOTSTRAP_CACHE_KEYS + SLOW_KEYS (P1-001)
- server/_shared/cache-keys.ts: add crudeInventories key + tier to match bootstrap.js
- api/health.js: remove bundled marketImplications (belongs in separate PR) (P1-002)
- src/services/economic/index.ts: add isFeatureAvailable('energyEia') gate (P2-003)
- src/services/economic/index.ts: use getHydratedData('crudeInventories') on first load
- proto/get_crude_inventories.proto: weekly_change_mb → optional double (P2-004)
- scripts/seed-economy.mjs: CRUDE_INVENTORIES_TTL 10d → 21d (3× cadence) (P2-005)
- scripts/seed-economy.mjs: period format validation with YYYY-MM-DD regex (P3-007)
- src/app/data-loader.ts: warn on crude fetch rejection (P2-006)

* fix(crude-inventories): schema validation, MIN_ITEMS gate, handler logging, raw=true docs

- Handler: document raw=true param, log errors instead of silent catch
- Seeder: CRUDE_MIN_WEEKS=4 guard prevents quota-hit empty writes
- Seeder: isValidWeek() schema validation before Redis write

* chore: regenerate openapi docs after rebase (adds getCrudeInventories + getEconomicCalendar)

* fix(gateway): add list-market-implications to RPC_CACHE_TIER

* chore: exclude todos/ from markdownlint
This commit is contained in:
Elie Habib
2026-03-27 09:42:26 +04:00
committed by GitHub
parent c9e6c4969e
commit f3b0280227
17 changed files with 360 additions and 13 deletions

File diff suppressed because one or more lines are too long