Les subqueries de loadHorizonScores() et loadPatches() triaient par
detected_at DESC, ce qui provoquait une contamination inter-zones :
une ingestion récente de Guadeloupe avec des patches à ~189km de la Barbade
écrasait les données locales pourtant plus proches.
Aligner sur la logique de loadLatestScore() (ImpactScoreService) qui
trie déjà par ST_Distance ASC — les 3 sources (score now, patches,
horizons) utilisent maintenant la même observation de référence.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ImpactScoreService : ne pas écraser le score si la nouvelle observation est plus
loin que le score actuel (sauf après 6h de stale). Empêche Barbade d'écraser
la Guadeloupe avec 367km quand des sargasses sont à 8km.
SpotScoreController : horizons et bancs filtrés par proximité (<300km) du spot,
plus la dernière observation globale quelle que soit sa zone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ST_Dump sur la dernière observation → 5 patches les plus proches dans 200km, exposés
dans /spots/{id}/score. SpotPanel affiche le nombre de patches et la distance+surface
de chacun sous forme de barres (échelle 0–100km).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expose breakdown {distance, density, velocity, trend} dans l'API /spots/{id}/score
(pour le score courant reconstruit depuis les champs stockés, et pour chaque horizon
avec confidence appliquée). Affiche les barres avec valeur/max dans le SpotPanel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Symfony Scheduler (MainSchedule) : cron 0,6,12,18h UTC
- IngestionScheduleMessage + IngestionScheduleHandler : pipeline complet
ingestion → forecasts → impact scores pour toutes les zones Antilles
- messenger.yaml : transport scheduler_main + async Redis (rs971_async)
- entrypoint.sh : 2 workers en background (scheduler_main + async)
- GET /api/status : date/heure de la dernière observation
- SargassesMap : badge "Données du JJ/MM à HH:MM" en bas à gauche
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avant : horizons = (1 - dist/50km) × 100 × confidence — échelle incomparable
avec le score now qui utilise distance(40) + densité(30) + vitesse(20) + tendance(10).
Après : même décomposition pour les 4 horizons, en passant currentDistanceKm
pour calculer la vitesse d'approche réelle par rapport à la position courante.
La confiance s'applique sur le score total (incertitude du modèle).
Résultat : si la sargasse s'éloigne à H+6, le score baisse. Si elle approche,
le score monte — mais atténué par la confiance du modèle (0.85 à H+6).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sans pondération, H+6 pouvait afficher 67 quand "now" était 34 car les
deux formules n'ont pas la même échelle. Multiplier par confidence (0.85
à H+6, 0.45 à H+48) rend les scores cohérents entre horizons : un risque
ne peut pas paraître croître si c'est juste l'incertitude qui augmente.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
symfony new crée son propre .git — supprimé pour intégrer
backend/ comme dossier ordinaire dans le monorepo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>