Commit Graph

117 Commits

Author SHA1 Message Date
a0ac6ec386 Ajouter LICENSE 2026-04-26 00:24:57 +00:00
Gwadaking
f5c132b4e8 remove: fallback Sentinel-3 — pas de données vaut mieux que du bruit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 00:17:55 -04:00
Gwadaking
4d33056280 fix: streaming GeoJSON pour éviter l'OOM + fenêtre 5 jours + simplification
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 23:00:25 -04:00
Gwadaking
493fa35d54 fix: filtrage brume de sable via ratio bleu/rouge + seuils AFAI/MCI rehaussés
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:52:40 -04:00
Gwadaking
4897397df8 fix: seuil fraîcheur 48h (satellite ≠ temps réel)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:32:32 -04:00
Gwadaking
dc97275928 add llms.txt + Schema.org pour visibilité IA et partenariat collectivités
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 21:01:12 -04:00
Gwadaking
6b0089d422 fix: add OpenGraph meta tags for WhatsApp/social previews
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 17:34:53 -04:00
Gwadaking
e0dafed8c5 remove: sharp inutile, PNGs déjà committés
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:57:39 -04:00
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