Commit Graph

109 Commits

Author SHA1 Message Date
Gwadaking
65089f6cd4 fix: status 200 + bandeau avertissement données périmées
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:52:41 -04:00
Gwadaking
2a4c92dc03 fix: skipWaiting + clients.claim pour forcer le remplacement du SW
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:38:43 -04:00
Gwadaking
547e0e8437 fix: légende en popup mobile + manifest PWA sans screenshots
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:34:26 -04:00
Gwadaking
8114103117 fix: icônes PNG + fetch handler pour déclencher le prompt PWA
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:29:10 -04:00
Gwadaking
ad0dc92f89 add PWA installable + recalibrer scoring échelle Guadeloupe
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:12:20 -04:00
Gwadaking
5c860547f8 fix: corriger le masquage du bas de l'app par la barre Android
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:06:06 -04:00
Gwadaking
6a6f42e55b fix: verrouiller la carte sur l'archipel guadeloupéen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:33:10 -04:00
Gwadaking
2db067023f focus: recentrer l'app sur l'archipel guadeloupéen uniquement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:26:20 -04:00
Gwadaking
fd476f50c2 feat: système de signalement bug/idée + modal changelog avec limitations
- AppReport entity + migration (type, message, fingerprint SHA-256, created_at)
- POST /api/report avec rate-limit 5/heure par fingerprint IP
- ReportModal : formulaire type radio (bug/idée) + textarea 1 000 chars max
- ChangelogModal : fonctionnalités en prod, roadmap, 5 limitations honnêtes
- Deux boutons flottants bas-gauche (? info + ✉ signalement)
- Légende remontée pour éviter le chevauchement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:52:32 -04:00
Gwadaking
83690b94ab perf: spots/overview — 100+ requêtes individuelles → 1 requête cachée 30 min
Avant : SargassesMap faisait 1 appel /api/spots (API Platform) puis
N appels /api/spots/{id}/score (un par spot, ~100+ pour la Guadeloupe).

Après : un seul GET /api/spots/overview (LATERAL JOIN spots+scores)
avec Cache-Control: public, max-age=1800, stale-while-revalidate=300.

Les marqueurs colorés s'affichent immédiatement depuis la réponse unique ;
/api/spots/{id}/score n'est appelé qu'au clic sur un spot (SpotPanel).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:43:38 -04:00
Gwadaking
14d2acc39b feat: différencier visuellement Sentinel-2 (fiable) vs Sentinel-3 (bruit)
S3 OLCI n'a pas de bande SWIR : impossible de filtrer sun glint résiduel
et aérosols sahariens → faux positifs massifs à 300 m de résolution.

- Tuiles : ajout des propriétés source/confidence/coverage_km2
- Carte : styling data-driven par source
    S2 → orange vif (#f4720a), opacité 65 % — signal confirmé
    S3 → or pâle (#d4b830), opacité 20 % — signal incertain
- Légende : entrées distinctes S2 / S3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:33:11 -04:00
Gwadaking
08a4754b26 fix: désactiver la compression gzip de Tippecanoe (MapLibre v5)
Tippecanoe compresse les tiles .pbf par défaut. Caddy ne gzip pas
application/x-protobuf (pas dans sa liste par défaut), donc aucun
header Content-Encoding n'est émis. MapLibre v5 a supprimé la
détection auto des magic bytes gzip → erreur "Unable to parse tile".

--no-tile-compression génère des tiles protobuf bruts, lisibles
directement par MapLibre sans header supplémentaire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:09:02 -04:00
Gwadaking
79f834e1f0 fix: monter la carte une seule fois après chargement du style
Le style basculait de positron (URL) vers cartoonizeStyle() ~500 ms
après le premier rendu. Ce setStyle() déclenchait une réinscription
des sources/layers (react-map-gl v8 / maplibre-gl v5) qui échouait
silencieusement — les bancs de sargasses devenaient invisibles.

La carte est désormais montée UNE SEULE FOIS quand le style est prêt
(avec timeout 4 s → fallback positron). Plus de transition post-mount,
plus de race condition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 02:48:08 -04:00
Gwadaking
295548b04a fix: mkdir -p du répertoire parent avant appel Tippecanoe 2026-04-14 01:58:09 -04:00
Gwadaking
c134e14ec0 fix: tiles filtrées sur coverage_area > 0 au lieu de afai_mean > 0 2026-04-14 01:48:39 -04:00
Gwadaking
2c41832d02 fix: ingestion et service worker sont maintenant redémarré toutes les 6h 2026-04-14 01:42:43 -04:00
Gwadaking
9455fd8cb9 fix: ajouter dragonmantank/cron-expression (CronExpressionTrigger manquant) 2026-04-14 01:22:51 -04:00
Gwadaking
a6a9c80fa6 fix: DSN scheduler 'schedule://' au lieu de 'scheduler://' 2026-04-14 01:16:29 -04:00
Gwadaking
d3a17ff210 fix: ajouter symfony/redis-messenger (transport async Redis manquant) 2026-04-14 01:10:41 -04:00
Gwadaking
15575e7de3 fix: entrypoint sans redirection fichier (var/log inexistant au démarrage) 2026-04-14 00:52:32 -04:00
Gwadaking
96dc79a297 fix: workers supervisés + tiles régénérées après ingestion et au démarrage 2026-04-14 00:31:46 -04:00
Gwadaking
e0ed71535e fix: Tippecanoe compilé depuis source (multi-stage build, absent de bookworm)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 03:44:00 -04:00
Gwadaking
9712cb54db feat: phase A — backup B2, healthcheck /api/status, vector tiles Tippecanoe
- A1: scripts/backup-postgres.sh — pg_dump quotidien compressé → Backblaze B2 (rclone), rétention 30j
- A2: StatusController retourne HTTP 503 + healthy/alertReason si dernière observation > 6h
- A4: Dockerfile installe tippecanoe, GenerateTilesCommand génère 5 tilesets (obs + h6/12/24/48), Caddyfile sert /tiles/* sans fallback SPA, SargassesMap.jsx passe en sources vector tiles statiques
- chore: backend/public/assets/ ajouté au .gitignore (build artifacts)
- chore: setup vitest frontend + ImpactScoreServiceTest (session précédente)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 03:40:32 -04:00
Gwadaking
1d8771cdcb feat: script backup PostgreSQL → Backblaze B2 2026-04-10 03:37:18 -04:00
Gwadaking
eff47f14bc test: éliminer les PHPUnit Notices (createMock → createStub)
Remplace createMock() par createStub() pour tous les collaborateurs
sans expectations configurées. Les mocks avec expects() restent des
mocks locaux créés dans le test concerné. 0 notices sur 49 tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 01:05:48 -04:00
Gwadaking
cda9a7a8ff security: appliquer les findings de l'audit OWASP (H1→B3)
H1 — trusted_proxies RFC-1918 dans framework.yaml : rate limiting
     opérationnel derrière Traefik (IP client réelle, pas IP Traefik)

H2 — En-têtes HTTP dans Caddyfile : X-Frame-Options DENY,
     X-Content-Type-Options nosniff, Referrer-Policy, Permissions-Policy,
     suppression header Server

H3 — API Platform docs désactivés en when@prod (Swagger UI, ReDoc)

M1 — Rate limiter sur DELETE /api/push/subscribe (manquant)
M2 — Validation FILTER_VALIDATE_URL sur endpoint push avant stockage
M3 — APP_ENV=prod dans backend/.env (était dev — risque si .env.local absent)
M4 — Limite 4096 octets sur le body JSON (FeedbackController + PushController)
M5 — Service Worker : open redirect corrigé (targetUrl validé contre l'origine)

B1 — robots.txt créé (bloque /api/ et /bundles/)
B3 — --time-limit=3600 sur les workers Messenger (rotation + libération mémoire)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 00:49:15 -04:00
Gwadaking
0d9c85e71b feat: icône radar SVG (topbar + favicon) et titre Radar Sargasses Caraïbes
Remplace le logo PNG par un SVG radar inline (cercles concentriques +
bras rotatif + blip) en bleu #2563eb/#60a5fa sur fond #1a1a2e.
Même SVG utilisé pour favicon.svg et le picto dans la topbar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 00:39:00 -04:00
Gwadaking
a4d57d7961 fix: sélectionner l'observation la plus proche (pas la plus récente) pour patches et horizons
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>
2026-04-10 00:30:55 -04:00
Gwadaking
50a9e49468 fix: ordre géographique N→S (St-Martin, Guadeloupe, Dominique, Martinique, Ste-Lucie, Barbade) 2026-04-09 01:07:27 -04:00
Gwadaking
81cc9736d8 feat: Dominique et Sainte-Lucie dans les filtres navigation 2026-04-09 01:06:45 -04:00
Gwadaking
d0113de4c0 fix: import OSM en 1 seule requête Overpass (évite le 429 rate limit) 2026-04-09 01:04:44 -04:00
Gwadaking
fb00ec8fa2 fix: topbar 2 lignes sur mobile (boutons îles toujours visibles), logo 44px 2026-04-09 01:02:25 -04:00
Gwadaking
38e810bd79 fix: supprimer stat Distance sargasses (redondante avec la liste des bancs) 2026-04-09 01:00:25 -04:00
Gwadaking
9175f63e39 fix: distance sargasses = min(patches) live ST_Dump, plus fiable que la valeur stockée 2026-04-09 00:57:30 -04:00
Gwadaking
9143cf857d fix: bboxes précises par île (Basse-Terre, Grande-Terre, Désirade séparés), requête Overpass élargie 2026-04-09 00:46:09 -04:00
Gwadaking
ddfa6a3ecb fix: pagination désactivée sur /spots — retourne tous les spots OSM 2026-04-09 00:37:28 -04:00
Gwadaking
8823d33eb5 fix: clic carte ferme le panel, stopPropagation sur marker, max-height panel 2026-04-09 00:35:41 -04:00
Gwadaking
3a69283983 feat: import points côtiers depuis OpenStreetMap (Overpass API) 2026-04-09 00:31:40 -04:00
Gwadaking
3c2d174edb fix: fallback S3 sur toute erreur S2 (pas seulement cloud coverage) 2026-04-09 00:21:29 -04:00
Gwadaking
354ccef917 fix: colonne requested_at (pas created_at) dans StatusController 2026-04-09 00:18:11 -04:00
Gwadaking
544ba24af2 fix: alerte critique si 0 zones ingérées + lastIngestionJob dans /api/status 2026-04-09 00:14:34 -04:00
Gwadaking
e5e835298e feat: logo dans la topbar à la place de l'emoji+texte 2026-04-08 03:09:55 -04:00
Gwadaking
90bee1bfe9 fix: rebuild propre — 1 seul bundle, plugin clean-assets avant chaque build 2026-04-08 03:08:02 -04:00
Gwadaking
9f73639f25 clean: supprimer les artifacts Vite du repo, gitignore public/assets 2026-04-08 03:00:02 -04:00
Gwadaking
1b50bd4b87 fix: import logo via Vite asset pour résoudre la résolution d'URL dev/prod 2026-04-08 02:58:56 -04:00
Gwadaking
003de64fc4 fix: logo dans frontend/public/assets pour que Vite le serve en dev et le copie au build 2026-04-08 02:56:53 -04:00
Gwadaking
cc33c63d46 add: logo top-left sur la carte, compressé à 20ko (110px)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 02:51:11 -04:00
Gwadaking
d60951cae8 fix: score basé sur l'observation la plus proche du spot, pas la dernière globale
impact_score stocke source_observation_id — la lecture trie par distance(obs→spot)
ASC pour garantir que Barbade n'écrase jamais Guadeloupe. Suppression du garde
"closest wins" au write, remplacé par un ORDER BY déterministe au read.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 02:38:48 -04:00
Gwadaking
51ca910e11 fix: l'observation la plus proche gagne — évite l'écrasement par zone distante
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>
2026-04-08 02:33:31 -04:00
Gwadaking
a607fd3c99 fix: Veille/ambre uniquement si sargasses à <100km, "banc" au lieu de "patch"
- scoreLabel/etaLabel/SpotMarker conditionnent Veille à distance<100km
  pour éviter l'alerte ambre sur les spots sans sargasses proches
- "patch" → "banc de sargasses" dans le SpotPanel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 02:25:51 -04:00