Commit graph

35 commits

Author SHA1 Message Date
Florian
0723ee10e3 feat(content): refonte conseils (kits par phénomène), à-propos, mentions, sitemap
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m28s
- /conseils : cards par phénomène (couleur d'impact + glyphe), bloc registre canicule mis en avant, numéros d'urgence
- /conseils/[slug] : nouvelle route SSR par phénomène — kit imprimable, share natif, cross-link, advice.ts réutilisé
- /conseils/registre-canicule : reskin nouveau design, contenu existant conservé + TL;DR coloré
- /a-propos : reskin + sections "engagement accessibilité" et "à venir"
- /mentions-legales : reskin en cards (contenu inchangé)
- Sitemap : custom serialize avec priority/changefreq par type d'URL, customPages pour les 102 départements + 7 kits (117 URLs au total). Suppression du custom sitemap-departements.xml redondant

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 19:02:38 +02:00
Florian
72b3785499 feat(design): refonte hi-fi (tokens, pills glyphes, dark mode, accueil)
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m30s
Adopte le design system livré par Claude Design (Info Canicule.html) :
palette --paper/--brand/--ink + ramp vigilance, Public Sans + Manrope,
header sticky blurred avec toggle clair/sombre, pills vigilance avec
glyphes ●▲◆■ (a11y daltonisme), home restructurée (hero, stat tiles,
map + sidebar avec recherche département, liste filtrable, CTA conseils).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 18:41:57 +02:00
Florian
a8830a4f34 fix(layout): contraindre la largeur des pages prose
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m32s
container-tight (max-w-5xl, @layer components) était écrasé par max-w-none
(@layer utilities) sur le même <section>, faisant déborder le contenu sur
toute la largeur. Sépare le wrapper container-tight de la zone prose.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 02:15:32 +02:00
Florian
6315793c90 feat(soutenir): barre d'objectif de don (nom de domaine dédié, 10 €)
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m29s
Affiche un goal concret en haut de /soutenir. Valeurs en dur dans le
frontmatter (goalRaised / goalTarget) à éditer à la main quand un don
arrive — pas de branchement Ko-fi.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 01:55:53 +02:00
Florian
95340c1228 ci: trigger deploy après fix VPS_KNOWN_HOSTS (port 22, host keys du VPS)
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m30s
2026-05-27 01:04:19 +02:00
Florian
2071281f6f ci: aligner runs-on sur ubuntu-latest (label exposé par le runner Forgejo)
Some checks failed
Deploy info-canicule / deploy (push) Failing after 3s
Le runner act-runner du VPS expose ubuntu-latest:docker://node:22 et
self-hosted, pas docker. Les ~20 derniers runs étaient en Canceled avec
'No matching online runner with label: docker'. L'image node:22 a déjà
openssh, git, rsync — plus besoin de l'étape Install tooling.
2026-05-27 01:01:14 +02:00
Florian
15635ed0e3 feat(home): onglets Aujourd'hui / Demain pour la carte Vigilance
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Permet au visiteur de basculer entre la carte du jour et celle de J+1
(toujours présente dans le bulletin MF, sauf entre minuit et la pub de
6h où l'onglet est désactivé avec explication). Réutilise les helpers
existants (currentEcheance, maxColorByDepartement) — pas de fetch
supplémentaire, J et J1 sont déjà dans le snapshot.

Bonus :
- dayLabel calculé depuis "maintenant Paris" plutôt qu'un sample
  d'alerte → fonctionne en jour calme tout-vert.
- CLAUDE.md : clarifie que MF officiel est canonique et Opendatasoft
  fallback (au lieu de la formulation "le jour où on bascule").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 00:47:56 +02:00
Florian
8638b260ff fix(map): fermer le tooltip au tap hors département (mobile)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Sur mobile, mouseout ne se déclenche pas après un touchstart : le tooltip
restait affiché jusqu'au prochain tap sur un département. Ajout d'un
listener pointerdown global qui ferme le tooltip dès qu'on tape ailleurs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:16:01 +02:00
Florian
fcfc858299 docs(vigilance): rectifier l'hypothèse load-balancer MF
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
L'observation initiale était à >20h UTC, hors fenêtres de publication MF
(04h/14h UTC). Diagnostic 60 fetches concurrents sans désynchro côté MF
→ l'origine est plus probablement notre cache / une requête transitoire.
On conserve la mitigation à 3 fetches concurrents pour rester safe, à
retirer si stabilité MF confirmée par observation suivie.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:05:34 +02:00
Florian
8a89dbbac1 chore(scripts): diagnostic load-balancer MF (DPVigilance update_time)
Script ad-hoc pour mesurer la désynchro WSO2 du gateway MF. Tabule les
update_time distincts sur N fetches séquentiels et conclut si la mitigation
MF_PARALLEL_FETCHES=3 reste justifiée. Constaté 2026-05-26 :
~60/40 split entre 2 update_time → à revérifier périodiquement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:58:10 +02:00
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
Florian
e72f25b33d fix(cache): Cache-Control must-revalidate sur home + dept
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Le navigateur cachait l ancienne version HTML → utilisateurs voyaient le
bulletin Vigilance précédent (carte du 25 mai 6h) malgré le bon HTML
servi par le serveur (carte du 25 mai 16h). max-age=60 + must-revalidate
force une revalidation conditionnelle à chaque visite > 1 min.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:46:20 +02:00
Florian
ac46637377 perf: skip previous-1950-2024 fetch si latest suffit (cold-fetch -90%)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Latest fichier (~50 KB compressé) couvre l'année courante et la précédente.
En mai 2026 il contient janvier 2025 → présent (~17 mois > 365j requis).
Previous (~4 MB compressé) n'est nécessaire que si latest a < 365j —
ce qui ne se produit qu'en début d'année (jan-mar 2025 par exemple).

Cold-fetch dept :
- Avant : ~17s (latest + previous + parsing 70 ans de data inutiles)
- Après : ~2-3s (latest seul, parse de quelques mois)

+ mem_limit 256m → 512m pour donner du headroom au cold-fetch concurrent
  (constaté : 5 workers warmup parallèles ont OOM le container).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:40:37 +02:00
Florian
b342ea7375 perf: fetches parallèles + /api/health expose vigilance freshness
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- /departement/[code] : Promise.allSettled sur les 3 fetches externes
  (vigilance MF, climato data.gouv, hourly SYNOP). Avant : ~15-20s
  sériel cold-fetch. Après : ~10s max (= temps du plus lent = climato).

- normales (3 ranges) : Promise.all aussi, économise ~30 ms.

- /api/health enrichi avec vigilance.productDatetime + ageSeconds
  pour permettre au cron freshness de checker sans /api/vigilance
  (qui a été supprimé en public).

Pré-requis pour le cron warmup côté infra repo (cf. scripts/cron-warmup-info-canicule.sh).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:32:49 +02:00
Florian
ecac3fbf8a polish(h2): titre 'Niveau par département' aussi dynamique
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:24:36 +02:00
Florian
0b418bd031 fix(vigilance): écheance dynamique selon l'heure courante
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Le bulletin MF est publié 2× par jour (~6h et ~16h Paris). Pendant la nuit
(de minuit au prochain bulletin ~6h), on est techniquement dans le J+1 du
bulletin courant, qui correspond pour l'utilisateur à "aujourd'hui réel".

Avant : on affichait toujours J → la nuit, la carte montrait les alertes
"d'hier" alors que l'utilisateur cherche "celles d'aujourd'hui réel".
Symptôme : Florian voit du orange sur vigilance.meteofrance.fr (qui prend
la bonne écheance) mais pas chez nous (qui restait collé sur J).

Fix :
- currentEcheance(snapshot) compare now au end_time du J : si dépassé, J1.
- index.astro + departement.astro utilisent cette écheance pour
  "aujourd'hui". Page dept : "demain" = J1 si on est sur J, vide sinon.
- Labels rendus dynamiques : "Niveau par département — mardi 26 mai" au
  lieu de "(aujourd'hui)" générique.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:22:19 +02:00
Florian
27441cdbb8 feat: retire API publique + dedupe load-balancing MF + maj pages
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
API publique retirée :
- /api/vigilance et /api/vigilance/dept/[code] supprimés
- Mentions retirées dans footer, /mentions-legales, /embed
- /api/health garde, sans CORS (usage interne UptimeRobot + cron HC.io)
- Tests E2E mis à jour (vérifient 404 sur les endpoints retirés)

Pages :
- /dependances : entièrement mise à jour (Sentry, sharp, Playwright,
  sitemap, typography ajoutés ; API MF officielle DPObs+DPVigilance,
  normales 1991-2020 listées ; section Services tiers ajoutée pour
  Opendatasoft en fallback ; section Infrastructure complétée avec
  GlitchTip + CrowdSec).
- /soutenir : "~7€/mois mutualisés" → "~30€/mois", suppression du
  détail VPS OVH (juste "infra"), suppression du bloc "Réutiliser
  les données via API".

Vigilance Météo France load-balancing :
- lib/vigilance.ts : fetch parallèle x3 et garde la réponse au
  update_time le plus récent. Constat 2026-05-26 : le gateway MF
  load-balance entre instances désynchronisées (~60% renvoyaient
  bulletin J-1, ~40% bulletin J). Cette mitigation atteint >95%
  de probabilité d'avoir le bulletin frais.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:16:04 +02:00
Florian
0a1f11aa00 tune(vigilance): cache TTL 15min → 5min pour capter bulletins complémentaires MF
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 02:01:29 +02:00
Florian
5f8b765d79 feat: Vigilance API officielle + tab 1 an + logo SVG + map à 5xl
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
1. lib/vigilance.ts : provider Météo France officielle via DPVigilance/v1
   /cartevigilance/encours. Map vers VigilanceAlert (1 par dept × phen × J/J1)
   en prenant phenomenon_max_color_id (pire de la journée). Filtre les domains
   non-dept (FRA national, sub-côtes XX10, etc).
   - Auto-pick : MF si key dispo, sinon opendatasoft. Override VIGILANCE_PROVIDER.
   - Fallback opendatasoft si MF échoue (cache key différent pour pas polluer).
   - Devrait fixer le lag de plusieurs heures observé sur Opendatasoft.

2. lib/climato.ts : fetch latest + previous (~4 MB compressé), garder 365j max
   en cache 24h. Permet l'onglet "1 an" sur la page dept.

3. TemperatureChartInteractive : onglet "1 an" (apparaît si > 30j dispos),
   série days365 + normales365 sérialisés au SSR.

4. Base.astro : logo header et footer utilisent <img src="/favicon.svg">
   au lieu d'un emoji 🌡️.

5. index.astro : wrapper map repassé à container-tight (max-w-5xl) — la version
   1400px était trop grande, on revient à la largeur du reste du site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 01:57:35 +02:00
Florian
cb8d111a12 feat: normales journalières + dedupe SYNOP + carte plus large
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
3 fixes en un :

1. lib/observations.ts : dedupe par validity_time sur le parse hourly.
   L API MF SYNOP retourne chaque obs en doublon exact sur les ranges
   multi-step (bug gateway WSO2). Constaté 7/8 paires identiques sur 24h.

2. Normales 1991-2020 passées de mensuelles à journalières (lissées 7j).
   - scripts/build-normales.mjs : agrégation par day-of-year (1..366)
     avec moving average ±3j pour stabiliser le bruit jour-à-jour.
   - src/data/normales.json : 2.28 MB (vs 78 KB), 96 × 366 entrées.
   - lib/normales.ts : normaleForDay/Date + normalesForRange, computeAnomaly
     compare maintenant chaque jour observé à SA normale (pas à la moyenne
     du mois) → bien plus précis sur les jours de transition mensuelle.
   - TemperatureChartInteractive : overlay normales en COURBE qui suit
     la saison (7j/30j) au lieu d une ligne horizontale unique.
     24h reste ligne horizontale (normale du jour courant).
   - Tooltip 7j/30j ajoute "↳ normale TX X°C (+Y)" pour montrer l écart
     par point.

3. Carte sur la home libérée du container-tight (max-w-5xl = 1024px) :
   wrapper dédié max-w-[1400px] → carte ~37% plus grande sur PC large.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 01:43:10 +02:00
Florian
84e8bd200f test: E2E onglet 24h + station PARIS-MONTSOURIS (sentinelle MF API live)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
27/27 tests passent en live, incl la nouvelle assertion que l API
Météo France répond bien avec le hourly + le mapping station résolu.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:43:29 +02:00
Florian
a007f340dc fix(stations): parse CSV en CRLF robust (le name était stripped \r → undefined)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Le CSV liste-stations-synop de Météo France arrive en CRLF, le split('\n')
laissait un \r en fin de chaque header → header.indexOf('name') = -1
→ stations[].name = undefined → 'station undefined' affiché côté front.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:37:09 +02:00
Florian
5fbbec4902 fix(mf): utiliser header apikey: au lieu de Bearer (API Key longue durée)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Le portail-api.meteofrance.fr utilise 2 mécanismes d auth différents :
- Token OAuth2 court (1h) → header Authorization: Bearer <token>
- API Key longue durée    → header apikey: <key>

On utilise la 2e, donc switch du header.

+ data-sources/Bulletin_Vigilance_swagger.json (gitignored mais utile en local
  pour préparer le switch Opendatasoft → Vigilance officielle Météo France).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:32:33 +02:00
Florian
a849977fcc refactor(mf): API Key longue durée au lieu d OAuth2 client_credentials
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Le portail Météo France ne propose pas le flow client_credentials gratuit
(seulement token OAuth2 court 1h, pas viable, ou API Key longue durée).
On simplifie : un seul env METEOFRANCE_API_KEY → Authorization: Bearer.

- lib/meteofrance-auth.ts : suppression du cache token + flow refresh
- .env.tmpl : ref unique vers vault Infra/Météo France API/api_key
- vault item recréé avec api_key (hidden) + created_at + expires_at
- CLAUDE.md projet : section rotation API key

L onglet 24 h n apparaît qu une fois api_key non vide dans le vault.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:25:54 +02:00
Florian
a78726076f fix(makefile): make env -f pour overwrite (pass-cli v2 ne force pas par défaut)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:18:10 +02:00
Florian
2c4d91ce2f 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>
2026-05-26 00:14:05 +02:00
Florian
9cfd4f8385 fix: anomalie fenêtres 3j+7j (worst-case) + carte plus large PC
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- normales.ts : computeAnomaly évalue 2 fenêtres (3j pour détecter un pic
  récent, 7j pour la tendance lissée), retient la pire catégorie. Évite
  de noyer un +15°C sur 3 jours dans 4 jours précédents normaux.
- FranceMap : max-w-3xl → max-w-5xl (1024px sur PC, plus lisible).

Mapping dept → station SYNOP (script build-stations-synop.mjs + json statique)
pour préparer l'intégration hourly via API Météo France officielle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:07:18 +02:00
Florian
c2b489f9b9 feat: normales saisonnières 1991-2020 + AnomalyBadge
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- scripts/build-normales.mjs : agrégation TN/TX mensuelles par dept sur
  la période WMO 1991-2020 depuis les fichiers Q_<DEPT>_previous-1950-2024.
  Output src/data/normales.json (78 KB, committé). Run annuel max.
- Corse : Météo France utilise le code historique "20" (avant split 2A/2B
  en 1976), donc 2A et 2B partagent la même normale issue de Q_20_*.
- src/lib/normales.ts : computeAnomaly() qui moyenne TX/TN des 7 derniers
  jours, compare à la normale du mois, calcule l'écart en °C et en σ,
  catégorise (normal / warm / cool / anomaly_warm / anomaly_cool /
  extreme_warm / extreme_cool / unknown).
- src/components/AnomalyBadge.astro : badge coloré (vert/jaune/orange/rouge)
  visible sur /departement/[code] juste au-dessus du graphe T°.
  Différencie "il fait chaud" de "il fait anormalement chaud pour ce mois".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:34:04 +02:00
Florian
dc01c46c76 fix(og): commit le PNG, ne pas regenerer dans le container Alpine
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
sharp dans node:22-alpine n'a pas librsvg → SVG mal rendu → PNG 4 KB
quasi-vide. Le PNG est generé localement (où WSL a librsvg complet),
commité, et servi tel quel. Script build:og garde dans package.json
pour regen manuel si le SVG bouge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:01:49 +02:00
Florian
87d173684c feat: OG png + sentry + dept api + drom notice + registre canicule
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Quick wins :
- public/og-image.png (1200x630, via sharp depuis le SVG, build via pnpm build)
  SVG ne fonctionne pas pour Open Graph (Slack/Discord/X/FB).
- @sentry/astro intégré conditionnellement (skip si SENTRY_DSN absent → no-op).
  GIT_COMMIT_SHA en var pour le release tag dans GlitchTip si voulu.
- /api/vigilance/dept/[code] : JSON enrichi (phenomenon label + color name)
  pour J et J1, CORS *, Cache-Control 5min. 404 si code unknown.
- JSON-LD enrichi : @graph WebSite + Service avec isBasedOn Dataset + license LOv2.
- Lien retour vigilance.meteofrance.fr visible sous la carte.

DROM (97x / 976) :
- 5 entrées ajoutées dans departements.ts (région "DROM").
- /departement/[code] DROM : bannière "Vigilance Outre-mer non couverte par
  cette source open data" + bouton vers vigilance.meteofrance.fr.
- Home : ligne sous la carte listant les 5 DROM + lien retour.
- L'API /api/vigilance/dept/<DROM> retourne quand même un JSON 200 (arrays vides).

Registre canicule :
- Page /conseils/registre-canicule : qui, quoi, comment s'inscrire au CCAS.
- Numéro vert 0 800 06 66 66.
- Bannière mise en avant en haut de /conseils.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:59:11 +02:00
Florian
89e48c18e4 feat: tooltip carte + tri/group alertes + safelist couleurs + legal Nocleus
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- FranceMap : tooltip riche au hover (HTML overlay), liste les phénomènes
  + niveaux du département. Touch-friendly (1er tap = preview, 2e = clic).
- index.astro : layout refactored, carte toujours visible full-width centrée,
  liste par région en details collapsible sous (plus de side-by-side cassé sur PC).
- Alertes actives groupées par département, triées par numéro asc (2A/2B après 19).
- Tailwind safelist vigilance-chip-{1..4} : les classes générées dynamiquement
  n'étaient pas captées par le scanner statique → CSS absent en prod.
- Mentions légales : distinction explicite entre Nocleus (micro-entreprise
  commerciale) et Info Canicule (projet perso non lucratif, hors cadre pro).
- Liens code source git.nocleus.com retirés partout (autres repos privés y sont
  visibles) → code "disponible sur demande" par mail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 20:23:02 +02:00
Florian
58053b72ed doc: roadmap updated post-MVP go-live
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 18:40:54 +02:00
Florian
f64394f69e fix(env): lire UMAMI_WEBSITE_ID via process.env (runtime, pas build)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
import.meta.env est résolu au build (par Vite), donc le snippet
Umami restait absent à l'exécution puisque .env est seulement disponible
au runtime côté container.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 18:37:38 +02:00
Florian
86352eb436 feat: pages contenu + SEO + Umami + sitemap
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- Pages /a-propos, /mentions-legales, /dependances, /soutenir (Ko-fi)
- Header/footer enrichis (lien Soutenir, mentions, API publique)
- @astrojs/sitemap + /sitemap-departements.xml.ts (96 dépts)
- robots.txt + og-image.svg + JSON-LD Schema.org
- Meta tags Open Graph + Twitter Card + canonical
- Umami snippet conditionnel (UMAMI_WEBSITE_ID env)
- Slot SENTRY_DSN dans .env.tmpl (GlitchTip — SDK à wire ultérieurement)
- @tailwindcss/typography pour les pages contenu

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 18:28:46 +02:00
Florian
e075d963bc init: info-canicule MVP (Vigilance + climato + conseils)
Astro 5 SSR + ioredis cache Valkey, déployable sur shared-net.
- Vigilance temps réel via Opendatasoft (no-auth, LOv2)
- Carte SVG des 96 départements (gregoiredavid/france-geojson)
- Climato T° 30j par dept (CSV.GZ Météo France, cache 24h)
- Conseils officiels par phénomène (7 types Vigilance)
- /api/health (UptimeRobot) + /api/vigilance (JSON public CORS *)
- Dockerfile multi-stage, CI Forgejo deploy.yml (pattern Reteno)

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