fix: OIS indisponible sur toutes les cards + transparence sur l'instrument utilisé

Le fetch /api/rate-probabilities n'avait aucun fallback cache côté client
(contrairement aux autres widgets) et pouvait planter en bloc si InvestingLive
timeoutait (fetch sans AbortController) - une seule panne coupait les 8 devises
d'un coup au lieu de dégrader devise par devise.

- route.ts : try/catch pour toujours renvoyer un JSON valide
- page.tsx : fallback localStorage si le fetch échoue
- investinglive.ts : timeout 8s sur les fetches vers investinglive.com
- fetch-rate-data.mjs / rateprobability.ts : le pipeline écrit maintenant la
  source réelle utilisée par devise (Rate Monitor USD, futures Euribor/SONIA
  pour EUR/GBP, InvestingLive pour les 5 autres) et la carte l'affiche
- CurrencyCard.tsx : SourcesPopup corrigé (CME FedWatch retiré, plus de fausse
  mention "Rate Monitor" pour les devises qui n'en ont pas)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
caty21
2026-07-14 23:05:37 +02:00
parent 55eca6e2f0
commit 3a384eb820
6 changed files with 81 additions and 21 deletions
+19 -7
View File
@@ -13,11 +13,23 @@ export interface RateProbabilitiesResponse {
}
export async function GET() {
const data = await fetchAllCBPaths();
const currencies = Object.keys(data);
console.log(`[rate-prob] fetched ${currencies.length} CBs: ${currencies.join(", ")}`);
return NextResponse.json(
{ data, fetchedAt: new Date().toISOString() } satisfies RateProbabilitiesResponse,
{ headers: { "Cache-Control": "no-store" } }
);
try {
const data = await fetchAllCBPaths();
const currencies = Object.keys(data);
console.log(`[rate-prob] fetched ${currencies.length} CBs: ${currencies.join(", ")}`);
return NextResponse.json(
{ data, fetchedAt: new Date().toISOString() } satisfies RateProbabilitiesResponse,
{ headers: { "Cache-Control": "no-store" } }
);
} catch (e) {
// Ne jamais laisser une exception (ex: timeout InvestingLive) faire planter la route
// entière — ça faisait échouer le fetch() client pour les 8 devises d'un coup au lieu
// de dégrader currency par currency. On renvoie un JSON valide (vide) : le client bascule
// sur son cache localStorage plutôt que de rester bloqué sur "Données OIS indisponibles".
console.error(`[rate-prob] fatal error: ${e instanceof Error ? e.message : e}`);
return NextResponse.json(
{ data: {}, fetchedAt: new Date().toISOString() } satisfies RateProbabilitiesResponse,
{ headers: { "Cache-Control": "no-store" } }
);
}
}
+5 -1
View File
@@ -222,8 +222,12 @@ export default function Dashboard() {
}
// ── Probabilités de taux (rateprobability.com OIS) ───────────────────
if (rateProbRes.status === "fulfilled" && rateProbRes.value?.data) {
if (rateProbRes.status === "fulfilled" && rateProbRes.value?.data && Object.keys(rateProbRes.value.data).length > 0) {
setRateProbabilities(rateProbRes.value.data as RateProbData);
saveCache("rateProbabilities", rateProbRes.value.data);
} else {
const cached = loadCache<RateProbData>("rateProbabilities");
if (cached) setRateProbabilities(cached.data);
}
setLastRefresh(new Date());