feat: graph T° interactif + widget iframe + MF auth + E2E Playwright
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run

Graph T° (TemperatureChartInteractive.astro) :
- Onglets 24 h / 7 j / 30 j (toggle JS, séries serialisées au SSR)
- Hover vertical line + tooltip valeurs
- Overlay normales mois en pointillé (TX orange, TN bleu)
- Onglet 24 h dispo seulement si l'API MF a répondu (best-effort)

Météo France OAuth2 (lib/meteofrance-auth.ts + observations.ts) :
- client_credentials avec refresh auto, cache token Valkey
- Fallback METEOFRANCE_STATIC_TOKEN pour debug
- /synop endpoint pour 24h horaires par station SYNOP du dept
- Mapping dept → station SYNOP la plus proche (src/data/stations-synop.json)
- En attente de creds : SDK skip silencieusement, l'onglet 24h n'apparaît pas

Widget iframe (/embed/dept/[code] + /embed doc) :
- Layout minimal sans header/footer global
- Réutilisable via iframe avec une ligne
- Page /embed avec snippet copier-coller + aperçu live

Tests E2E Playwright (tests/e2e/) :
- home (carte 96 paths, tooltip dept, navigation)
- api (health, vigilance, vigilance/dept)
- departement (tabs période, DROM notice, 404)
- static pages (a-propos, mentions, dependances, soutenir, conseils, embed)
- embed widget (rendu minimal, headers X-Frame OK)
- 20+ tests, run via pnpm test:e2e (live) ou test:e2e:local

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian 2026-05-26 00:14:05 +02:00
parent 9cfd4f8385
commit 2c4d91ce2f
20 changed files with 922 additions and 467 deletions

View file

@ -7,8 +7,9 @@ import { getDepartement, isDrom } from '../../lib/departements';
import { PHENOMENA, COLOR_LABEL } from '../../lib/phenomena';
import { ADVICE, EMERGENCY_NUMBERS } from '../../lib/advice';
import { getClimatoForDepartement } from '../../lib/climato';
import { computeAnomaly } from '../../lib/normales';
import ClimatoChart from '../../components/ClimatoChart.astro';
import { computeAnomaly, normaleForMonth } from '../../lib/normales';
import { getHourlyForDepartement } from '../../lib/observations';
import TemperatureChartInteractive from '../../components/TemperatureChartInteractive.astro';
import AnomalyBadge from '../../components/AnomalyBadge.astro';
export const prerender = false;
@ -34,17 +35,32 @@ if (!drom) {
let climato = null;
let anomaly = null;
let hourly = null;
let normale = null;
if (!drom) {
try {
climato = await getClimatoForDepartement(dept.code);
if (climato?.days?.length) {
anomaly = await computeAnomaly(dept.code, climato.days);
// Mois représentatif = mois du dernier jour climato dispo
const lastDate = climato.days[climato.days.length - 1].date;
normale = await normaleForMonth(dept.code, parseInt(lastDate.slice(5, 7), 10));
}
} catch (e) {
console.warn('climato fetch failed for', dept.code, (e as Error).message);
}
// Hourly est best-effort : si MF API down ou pas de creds, on n'affiche juste pas l'onglet 24h
try {
hourly = await getHourlyForDepartement(dept.code, 24);
} catch (e) {
console.warn('hourly fetch failed for', dept.code, (e as Error).message);
}
}
const last7 = climato?.days?.slice(-7) ?? [];
const last30 = climato?.days?.slice(-30) ?? [];
const stationLabel = hourly ? `${hourly.stationName} (${hourly.distKm} km)` : null;
const today = snapshot ? alertsForDepartement(snapshot, dept.code, 'J') : [];
const tomorrow = snapshot ? alertsForDepartement(snapshot, dept.code, 'J1') : [];
const highest = today[0];
@ -158,11 +174,17 @@ const adviceFor = highest && ADVICE[highest.phenomenonId];
<AnomalyBadge anomaly={anomaly} />
</div>
)}
<ClimatoChart days={climato.days} />
<TemperatureChartInteractive
hourly={hourly}
days7={last7}
days30={last30}
normale={normale}
stationLabel={stationLabel}
/>
<p class="mt-2 text-xs text-slate-500">
Source : Météo France — données climatologiques de base quotidiennes, agrégées par moyenne
sur toutes les stations du département. Donnée brute, contrôle qualité Météo France.
Normales calculées sur 1991-2020 (référence WMO).
Sources : Météo France — observations SYNOP horaires (onglet 24 h) et données
climatologiques de base quotidiennes (7 j / 30 j), agrégées par moyenne sur les
stations du département. Normales calculées sur 1991-2020 (référence WMO).
</p>
</div>
</section>