info-canicule/src/lib/meteofrance-auth.ts
Florian 290f9be7b9 fix+perf: corrections de revue (currentEcheance, dayOfYear, SWR, last-good, doc apikey)
- vigilance: currentEcheance basée sur productDatetime (jour calme renvoyait J1 à tort)
- normales: dayOfYear extrait en Europe/Paris pour 'now' (UTC mélangeait les jours après minuit)
- meteofrance-auth + CLAUDE.md: header `apikey:` documenté correctement (pas Authorization Bearer)
- cache: SWR — envelope {v, fu}, hard TTL = ttl*6, refresh background avec lock anti-stampede
- vigilance: snapshot last-good (TTL 30j) écrit à chaque fetch, fallback final si MF+ODS KO
- vigilance: nettoyage variable url morte dans fetchOpendatasoft

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:58:03 +02:00

36 lines
1.4 KiB
TypeScript

// Accès à l'API Météo France (portail-api.meteofrance.fr) via API Key longue durée.
//
// Le portail propose 2 modes : (a) token OAuth2 court 1h (pas adapté en prod
// sans flow refresh) et (b) API Key permanente / longue durée. On utilise (b).
//
// Configuration via env :
// METEOFRANCE_API_KEY → clé permanente, envoyée en header `apikey: <key>`
// (PAS `Authorization: Bearer` — c'est le format des
// tokens OAuth2 courts, pas des API Keys du portail).
//
// Quand la clé approche de l'expiration (cf. duration choisie à la création),
// régénérer côté portail puis mettre à jour le vault `Infra/Météo France API`,
// puis `make env` + redeploy. Voir CLAUDE.md projet info-canicule.
const BASE = 'https://public-api.meteofrance.fr';
export async function fetchMF(path: string, init: RequestInit = {}): Promise<Response> {
const key = process.env.METEOFRANCE_API_KEY;
if (!key) {
throw new Error('METEOFRANCE_API_KEY missing in env');
}
// Le portail Météo France utilise le header `apikey:` pour les API Keys
// longue durée (différent du `Authorization: Bearer` des tokens OAuth2 courts).
return fetch(`${BASE}${path}`, {
...init,
headers: {
...init.headers,
apikey: key,
Accept: 'application/json',
},
});
}
export function hasMeteoFranceCredentials(): boolean {
return Boolean(process.env.METEOFRANCE_API_KEY);
}