# ROADMAP — Sargasse-Sentry > Checklist permanente d'avancement projet. > Mettre à jour au fil des implémentations. --- ## Légende - [ ] À faire - [~] En cours - [x] Terminé --- ## Phase 0 — Fondations ### Infrastructure & environnement - [x] Initialisation dépôt Git (bare repo VPS + hook post-receive) - [x] Configuration Docker (FrankenPHP + PostgreSQL/PostGIS + Redis) - [x] Configuration Traefik (domaine radarsargasses971.com, SSL Let's Encrypt) - [x] Variables d'environnement (.env + clés VAPID documentées) - [x] Initialisation projet Symfony (`symfony new backend`) - [x] Installation API Platform - [x] Initialisation projet React (`npm create vite@latest frontend`) - [x] Configuration MapLibre GL JS + react-map-gl ### Base de données - [x] Extension PostGIS activée (dans la migration) - [x] Migration : `SargassumObservation` - [x] Migration : `SargassumForecast` - [x] Migration : `DataIngestionJob` - [x] Migration : `CoastalPoint` - [x] Migration : `ImpactScore` - [x] Migration : `UserFeedback` - [x] Migration : `PushSubscription` - [x] Index spatiaux (GIST) + index BTREE définis --- ## Phase 1 — MVP (Antilles, observations uniquement) ### Pipeline d'ingestion - [x] Cron VPS (`docker exec` toutes les 3h) → `app:ingest-sentinel` - [x] Appel API Sentinel Hub (bandes B04, B08, B11 via evalscript) - [x] Création `DataIngestionJob` (pending → success/failed) - [x] Retry automatique + logging erreurs - [x] Filtrage nuages via Catalog API (seuil 60%, configurable) - [x] Calcul AFAI dans evalscript Sentinel Hub (formule complète) - [x] Rasterisation → raster UINT8 binaire (evalscript cloud-side) - [x] Vectorisation GDAL (`gdal_polygonize.py`) + simplification PostGIS - [x] Persistance `SargassumObservation` - [ ] Génération vector tiles (Tippecanoe → `.pbf`) — différé Phase 2 ### API Backend - [x] `GET /api/spots` — liste CoastalPoints (API Platform) - [x] `GET /api/spots/{id}` — détail (API Platform) - [x] `GET /api/spots/{id}/score` — score + niveau + trend - [x] `GET /api/observations?bbox=&date=&source=` — PostGIS ST_Intersects - [x] `GET /api/observations/{id}` — détail avec geometry GeoJSON - [x] `GET /api/forecasts` — API Platform - [x] `POST /api/feedback` — feedback anonyme (IP hachée) ### Frontend React - [x] Carte de base (MapLibre GL JS + fond CARTO dark) - [x] Affichage observations GeoJSON (bbox dynamique au mouvement) - [x] Marqueurs CoastalPoints avec sélection - [x] SpotPanel : Spot Mode complet (score, niveau, distance, trend) - [x] Bouton feedback terrain (confirmation/infirmation anonyme) - [x] Build Vite → backend/public/ (SPA servie depuis la racine par Caddy) ### Données initiales - [x] Seed `CoastalPoint` zone Antilles — 29 points (plages, ports, surf, pêche) --- ## Phase 2 — Dérive & Score ### Pipeline — simulation de dérive - [x] Vent horaire via Open-Meteo (gratuit, sans clé, JSON) - [x] Échantillonnage PostGIS ST_GeneratePoints (30 points internes) - [x] Déplacement horaire itératif (modèle Stokes 3% vent) - [x] Reconstruction ST_ConcaveHull (PostGIS 3.4) - [x] Génération horizons H+6, H+12, H+24, H+48 avec confiance décroissante - [x] Persistance `SargassumForecast` - [ ] Génération vector tiles prédictions (Tippecanoe) — différé ### Calcul ImpactScore - [x] Score par `CoastalPoint` : distance(40) + densité(30) + vitesse(20) + tendance(10) - [x] Persistance `ImpactScore` - [x] Mise en cache Redis (TTL 3h) via ImpactScoreService ### API Backend - [x] `GET /api/spots/{id}/score` — score courant + horizons H+6/12/24/48 - [x] `GET /api/spots/{id}/score?at={datetime}` — score à un instant - [x] `GET /api/forecasts?bbox=&horizon=` — prédictions par zone + horizon (API Platform) ### Frontend React - [x] Slider temporel (Now → +6h → +12h → +24h → +48h) - [x] Spot Mode complet par horizon (OK / Risque / Impact + confiance) - [x] Mise à jour dynamique polygones + score sur slider - [x] Couche forecasts (violet pointillé) vs observations (orange plein) - [ ] Gradients radiaux densité — différé --- ## Phase 3 — Feedback & Alertes ### Boucle d'apprentissage - [x] Bouton "Je confirme présence de sargasses" - [x] `POST /api/feedback` — persistance `UserFeedback` anonyme - [x] Intégration feedback dans calcul score (bonus +8 pts si présence confirmée < 6h dans rayon 20 km) ### Alertes push - [x] Commande `app:generate-vapid-keys` (génération clés VAPID) - [x] `GET /api/push/vapid-public-key` — clé publique VAPID - [x] `POST /api/push/subscribe` — enregistrement abonnement push - [x] `DELETE /api/push/subscribe` — désinscription - [x] `PushNotificationService` — envoi WebPush VAPID, nettoyage abonnements expirés - [x] Déclenchement alertes si score ≥ 70 (HIGH_SCORE_THRESHOLD) - [x] Service worker (`sw.js`) — réception push + ouverture app au clic - [x] `usePushSubscription` hook React — subscribe/unsubscribe lifecycle - [x] Bouton "Activer les alertes" dans SpotPanel --- ## Transversal (continu) - [x] Rate limiting endpoints publics (api_read 120/min, api_feedback 10/min, api_push 5/min) - [x] Fallback Sentinel-2 → Sentinel-3 OLCI (mode `auto` dans IngestSentinelCommand) - [x] Routing SPA corrigé (Caddyfile `try_files` + build vers `backend/public/`) - [x] Vue mobile (SpotPanel bottom-sheet + TimelineSlider compact) - [x] Post-receive hook complet (composer + npm build + migrations + cache + docker up) - [ ] Monitoring pipeline (alertes si ingestion échoue > N fois) - [ ] Logs structurés (Monolog JSON handler) - [ ] Configuration Cloudflare free tier (cache tiles statiques) - [ ] Tests fonctionnels pipeline (ingestion → score)