Files
worldmonitor/scripts
Elie Habib c072edc89f fix(economy): GSCPI shape mismatch with ais-relay payload (#3072)
* fix(economy): GSCPI shape mismatch with ais-relay payload

`seed-economy.mjs` was reporting `[StressIndex] GSCPI not in Redis yet
(ais-relay lag or first run) — excluding` even when GSCPI was current
in Redis. The Stress Index then computed on 5/6 components instead
of 6/6 every run.

Root cause: shape mismatch.
- ais-relay.cjs (`seedGscpi()`) writes the FRED-compatible payload
  `{ series: { series_id, title, units, frequency, observations: [...] } }`
- seed-economy.mjs `fetchGscpiFromRedis()` was reading the legacy
  flat shape `{ observations: [...] }` (top-level), so
  `Array.isArray(parsed.observations)` was always false → null returned
  → "not in Redis yet" log, even though 343 monthly observations were
  sitting in `economic:fred:v1:GSCPI:0`

Fix: extract the parsing into `extractGscpiObservations()` which checks
both shapes (`parsed.series.observations` first, then top-level
`parsed.observations` for back-compat). The "not in Redis yet" message
will now correctly fire only when the relay is genuinely behind.

Verified against live Redis: returns `{ observations: 343 entries,
latest 2026-03-01 = 0.68 }` instead of null.

Tests added in tests/gscpi-shape-extraction.test.mjs (3 cases:
ais-relay shape, legacy flat shape, malformed payload).

* style(economy): single @type cast in extractGscpiObservations

PR #3072 review (P2): cast `parsed` to `any` once into a local instead
of repeating the inline `/** @type {any} */` annotation on every access.
Same behavior, less visual noise.
2026-04-13 22:03:27 +04:00
..