fix: EUR/GBP data, PMI ForexFactory + TE, localStorage PMI persistence

macro/route.ts :
  - Eurostat EUR CPI : ajout unit=RCH_MOM, freq=M pour que chaque dimension
    ait une seule valeur → position value[]=timeIndex correcte (bug de mapping
    multi-dimensionnel corrigé)
  - Eurostat EUR GDP : passage de CLV10_MEUR (niveaux) à CLV_PCH_PRE (QoQ%
    directement) + toIndicator au lieu de toIndicatorPct
  - Eurostat EUR chômage : ajout freq=M pour unicité de dimension
  - eurostatSorted : fallback automatique EA20 → EA19 si données vides
  - BoE (GBP taux) : ajout User-Agent + Accept → évite la redirection HTML
  - PMI : ForexFactory JSON (semaine courante, données structurées) en source
    primaire + TE scraping enrichi (Accept, Sec-Fetch-*, Pragma) en fallback
  - toPmiIndicator : extrait en fonction globale réutilisable

CurrencyCard.tsx :
  - Préservation des valeurs PMI précédentes du cache localStorage si le
    serveur renvoie null (PMI publié le mois dernier, pas cette semaine)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Capucine Gest
2026-05-28 23:13:40 +02:00
co-authored by Claude Sonnet 4.6
parent e4e21755f2
commit b833baf495
2 changed files with 146 additions and 89 deletions
+14 -3
View File
@@ -100,13 +100,24 @@ export default function CurrencyCard({ currency, expectations, yields, onDiverge
const json: MacroData = await res.json();
if ("error" in json) throw new Error(String((json as Record<string,unknown>).error));
setData(json);
// PMI est scraped mensuellement → si le serveur renvoie null cette semaine
// (PMI pas encore publié), on conserve la valeur précédente du cache local.
const prevCache = loadCache<MacroData>(cacheKey);
const merged: MacroData = {
...json,
indicators: {
...json.indicators,
pmiMfg: json.indicators.pmiMfg ?? prevCache?.data.indicators.pmiMfg ?? null,
pmiServices: json.indicators.pmiServices ?? prevCache?.data.indicators.pmiServices ?? null,
},
};
setData(merged);
setFromCache(false);
setCacheAge(null);
saveCache(cacheKey, json);
saveCache(cacheKey, merged);
// Infer phase from policy rate trend
const rateInd = json.indicators.policyRate;
const rateInd = merged.indicators.policyRate;
if (rateInd?.trend === "up") setPhase("tightening");
else if (rateInd?.trend === "down") setPhase("easing");
else setPhase("hawkish_pause");