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>
This commit is contained in:
Florian 2026-05-25 18:17:56 +02:00
commit e075d963bc
37 changed files with 6730 additions and 0 deletions

67
src/layouts/Base.astro Normal file
View file

@ -0,0 +1,67 @@
---
import '../styles/global.css';
interface Props {
title?: string;
description?: string;
}
const {
title = 'Info Canicule — Vigilance météo en temps réel',
description = 'Suivi en temps réel des alertes Vigilance Météo France et conseils officiels en cas de canicule, orages, tempêtes.',
} = Astro.props;
---
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content={description} />
<meta name="robots" content="index, follow" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta name="theme-color" content="#ea580c" />
</head>
<body class="min-h-screen flex flex-col">
<header class="border-b border-slate-200 bg-white">
<div class="container-tight flex items-center justify-between py-4">
<a href="/" class="flex items-center gap-2 no-underline">
<span class="text-2xl">🌡️</span>
<span class="text-lg font-bold text-canicule-700">Info Canicule</span>
</a>
<nav class="flex items-center gap-6 text-sm font-medium text-slate-600">
<a href="/">Carte Vigilance</a>
<a href="/conseils">Conseils</a>
</nav>
</div>
</header>
<main class="flex-1">
<slot />
</main>
<footer class="border-t border-slate-200 bg-white">
<div class="container-tight py-6 text-sm text-slate-500">
<p>
Données :
<a href="https://meteo.data.gouv.fr/" class="text-canicule-700" rel="noopener">Météo France</a>
via
<a href="https://public.opendatasoft.com/" class="text-canicule-700" rel="noopener">Opendatasoft</a>
— Licence Ouverte 2.0.
</p>
<p class="mt-1">
Service d'information publique sans valeur officielle. En cas de doute, suivre les consignes de
la Préfecture (
<a href="tel:112" class="text-canicule-700">112</a>
en urgence).
</p>
<p class="mt-2 text-xs text-slate-400">
Un projet
<a href="https://nocleus.com" class="text-canicule-700" rel="noopener">Nocleus</a>.
</p>
</div>
</footer>
</body>
</html>