Commit Graph

67 Commits

Author SHA1 Message Date
Gwadaking
6cbd190ba0 fix: disable transaction on initial migration (CONCURRENTLY indexes) 2026-04-01 21:07:12 -04:00
Gwadaking
c02b58c3ce fix: remove unused frontend/dist volume, commit built assets 2026-04-01 20:57:28 -04:00
Gwadaking
77be044e3f fix: commit Symfony .env defaults, fix gitignore, rename to CLAUDE.md 2026-04-01 20:48:40 -04:00
Gwadaking
dc2f5af0fd fix: use shared db-network/redis_global, set container_name rs971_app 2026-04-01 20:41:53 -04:00
Gwadaking
8b7b2cf64f fix: add missing tls=true label for Traefik cert 2026-04-01 20:07:07 -04:00
Gwadaking
1474b14e35 fix: use traefik-public network name 2026-04-01 19:56:44 -04:00
Gwadaking
813b26ec1d fix: use traefik-public network name 2026-04-01 17:55:38 -04:00
Gwadaking
7ecb71599d fix: move cache:warmup to runtime entrypoint, fix POSTGRES_PASSWORD default
cache:warmup at build time fails because .env.local is not available in the
image (gitignored). Moved to entrypoint.sh which runs after volume mounts.
Also added default value for POSTGRES_PASSWORD in docker-compose.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 17:44:05 -04:00
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
Gwadaking
94bb6f5e8c Phase 2 : dérive, ImpactScore, slider temporel
Backend :
- OpenMeteoClient : vent horaire 72h (gratuit, sans clé)
- DriftSimulationService : échantillonnage ST_GeneratePoints,
  déplacement itératif Stokes 3%, reconstruction ST_ConcaveHull,
  4 horizons H+6/12/24/48, confiance décroissante
- ImpactScoreService : score 4 composantes (distance/densité/
  vitesse/tendance), cache Redis TTL 3h, invalidation à chaque calcul
- ComputeForecastsCommand : traite les observations sans forecast
- SpotScoreController : score courant + horizons depuis forecasts

Frontend :
- TimelineSlider : navigation Now/+6h/+12h/+24h/+48h
- SargassesMap : couche observations (orange) vs forecasts (violet)
  rechargée à chaque changement d'étape
- SpotPanel : affichage score par horizon actif + indicateur confiance
- Build → backend/public/spa/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 03:23:21 -04:00
Gwadaking
0c1deb93cb Phase 1 : seed CoastalPoints + frontend React complet
Backend :
- SeedCoastalPointsCommand : 29 points Antilles (idempotent)
  Martinique, Guadeloupe, Sainte-Lucie, Barbade, Saint-Martin

Frontend :
- api/client.js : wrapper fetch pour spots, observations, feedback
- SargassesMap : MapLibre GL JS, marqueurs spots, couche observations
  GeoJSON avec rechargement bbox dynamique à chaque mouvement carte
- SpotPanel : Spot Mode (score/niveau/distance/trend), bouton feedback
  terrain anonyme, gestion état loading/error/null
- App.jsx : composition map + panel, état selectedSpot
- vite.config.js : proxy /api → Symfony dev, build → backend/public/spa

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 03:17:43 -04:00
Gwadaking
4af5e62465 Phase 1 : endpoints API complets
- CoastalPoint → shortName Spot → /api/spots (API Platform)
- SargassumForecast → shortName Forecast → /api/forecasts
- ObservationController : GET /api/observations avec filtres
  bbox (PostGIS ST_Intersects), date, source + geometry ST_AsGeoJSON
- SpotScoreController : GET /api/spots/{id}/score avec ?at= optionnel
- FeedbackController : POST /api/feedback, anonyme, fingerprint SHA256
- CORS : autorisation radarsargasses971.com + localhost dev

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:50:06 -04:00
Gwadaking
bf64340525 Phase 1 : pipeline d'ingestion Sentinel-2
- SentinelHubClient : auth OAuth2, Catalog API (cloud coverage),
  Process API avec evalscript AFAI binaire (UINT8, cloud-side)
- IngestionService : orchestration complète — job tracking,
  rejet nuages, téléchargement GeoTIFF, polygonize GDAL,
  simplification PostGIS, persistance SargassumObservation
- IngestSentinelCommand : 5 zones Antilles configurées,
  options --date et --zone, appelable via cron docker exec
- Dockerfile : ajout gdal-bin + python3-gdal
- Correction entity : paramètre immutable retiré de #[ORM\Column]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:45:12 -04:00
Gwadaking
e5e729c487 Phase 0 : entités, migrations, API Platform, PostGIS
- API Platform + Doctrine ORM + jsor/doctrine-postgis installés
- 6 entités Symfony (SargassumObservation, SargassumForecast,
  DataIngestionJob, CoastalPoint, ImpactScore, UserFeedback)
- Migration initiale manuelle avec CREATE EXTENSION postgis,
  toutes les tables, index GIST et BTREE
- doctrine.yaml configuré pour PostgreSQL 16 + types PostGIS
- Roadmap Phase 0 complète

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:37:27 -04:00
Gwadaking
34e9675350 Fix : backend intégré en monorepo (suppression git imbriqué)
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>
2026-04-01 02:23:26 -04:00
Gwadaking
f685c96ed6 Phase 0 : scaffolding complet
- Structure monorepo (backend Symfony, frontend React/Vite)
- Docker : FrankenPHP + PostgreSQL/PostGIS + Redis + Traefik labels
- Caddyfile, Dockerfile, .env.example, .gitignore
- MapLibre GL JS + react-map-gl installés
- Roadmap mise à jour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:23:10 -04:00
Gwadaking
e44916d444 Initial commit : docs (specs, data-model, architecture, roadmap) 2026-03-31 23:24:51 -04:00