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

View File

@@ -494,6 +494,32 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-crude-inventories:
get:
tags:
- EconomicService
summary: GetCrudeInventories
description: GetCrudeInventories retrieves the 8 most recent weeks of US crude oil stockpile data from EIA (WCRSTUS1).
operationId: GetCrudeInventories
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCrudeInventoriesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
@@ -1399,3 +1425,34 @@ components:
type: string
unit:
type: string
GetCrudeInventoriesRequest:
type: object
description: GetCrudeInventoriesRequest is the request message for GetCrudeInventories.
GetCrudeInventoriesResponse:
type: object
properties:
weeks:
type: array
items:
$ref: '#/components/schemas/CrudeInventoryWeek'
latestPeriod:
type: string
description: Timestamp of the most recent EIA data point (ISO 8601).
description: GetCrudeInventoriesResponse contains the 8 most recent weeks of US crude oil inventory data.
CrudeInventoryWeek:
type: object
properties:
period:
type: string
description: ISO week period (YYYY-MM-DD, Monday of the EIA report week).
stocksMb:
type: number
format: double
description: Total crude oil stocks in millions of barrels.
weeklyChangeMb:
type: number
format: double
description: |-
Week-over-week change in millions of barrels. Positive = build (bearish), negative = draw (bullish).
Absent for the oldest week when no prior week is available for comparison.
description: CrudeInventoryWeek represents one week of US crude oil stockpile data from EIA WCRSTUS1.