Files
radarsargasses/docs/roadmap.md
Gwadaking 2cef3725e9 feat: Phase 3 complete — push alerts, feedback scoring, S3 fallback, SPA routing, mobile CSS
- ImpactScoreService: implement getFeedbackBonus() (ST_Distance query on UserFeedback within 20km/6h)
- ImpactScoreService: trigger PushNotificationService when score >= 70
- PushNotificationService: send VAPID WebPush to spot subscribers, clean expired subs
- PushController: GET vapid-public-key, POST/DELETE subscribe with rate limiting
- SentinelHubClient: add optional $collection param, add Sentinel-3 OLCI FAI evalscript (MCI)
- IngestionService: add $collection param + HighCloudCoverageException for fallback logic
- IngestionService: add ingestWithFallback() — tries S2, falls back to S3 on high cloud
- IngestSentinelCommand: --source=auto (default) triggers ingestWithFallback
- FeedbackController: rate limiting via apiFeedbackLimiter
- Migration: push_subscription table
- rate_limiter.yaml: api_read(120/min), api_feedback(10/min), api_push(5/min)
- sw.js: service worker handling push events + notificationclick
- usePushSubscription hook: subscribe/unsubscribe lifecycle with VAPID
- SpotPanel: PushButton component integrated
- SpotPanel.css + TimelineSlider.css: mobile responsive (bottom-sheet on small screens)
- Caddyfile: SPA served at / with try_files fallback, sw.js served from root scope
- vite.config.js: build outDir → backend/public (not /spa)
- deploy/post-receive.sh: full deploy script (composer, npm build, migrations, cache, docker up)
- docs/roadmap.md: all Phase 3 + transversal items marked done

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 03:43:56 -04:00

150 lines
5.6 KiB
Markdown

# 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)