Initial commit : docs (specs, data-model, architecture, roadmap)
This commit is contained in:
150
docs/architecture.md
Normal file
150
docs/architecture.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# ARCHITECTURE — Sargasse-Sentry
|
||||
|
||||
## Stack technique
|
||||
|
||||
| Couche | Technologie | Rôle |
|
||||
|---|---|---|
|
||||
| Backend | Symfony (PHP) | API JSON, crons, pipeline |
|
||||
| Frontend | React SPA | Interface utilisateur |
|
||||
| Maps | MapLibre GL JS + react-map-gl | Rendu cartographique |
|
||||
| Base de données | PostgreSQL + PostGIS | Données géospatiales |
|
||||
| Vector tiles | Tippecanoe (génération) | Tiles statiques pré-générées |
|
||||
| Cache | Redis | Scores, résultats API |
|
||||
| Reverse proxy | Traefik | Routage multi-tenant, SSL |
|
||||
| Runtime PHP | FrankenPHP | Remplace php-fpm + nginx |
|
||||
| Conteneurisation | Docker | Isolation, déploiement |
|
||||
|
||||
---
|
||||
|
||||
## Infrastructure
|
||||
|
||||
### Hébergement
|
||||
|
||||
VPS personnel, architecture **multi-tenant Docker + Traefik + FrankenPHP** (configuration existante partagée entre projets).
|
||||
|
||||
```
|
||||
Internet
|
||||
└── Traefik (reverse proxy, SSL Let's Encrypt)
|
||||
├── sargasse-sentry.tld → container Symfony/FrankenPHP
|
||||
├── [autres projets]
|
||||
└── ...
|
||||
|
||||
Containers Sargasse-Sentry :
|
||||
├── frankenphp (Symfony API + worker cron)
|
||||
├── postgres (PostgreSQL + PostGIS)
|
||||
└── redis (cache)
|
||||
```
|
||||
|
||||
### CDN (optionnel, sans coût)
|
||||
|
||||
**Cloudflare free tier** peut être activé devant Traefik pour mettre en cache les vector tiles statiques et les réponses HTTP publiques. Aucun coût.
|
||||
|
||||
---
|
||||
|
||||
## Architecture applicative
|
||||
|
||||
### Backend — Symfony API
|
||||
|
||||
Symfony n'expose que du JSON (pas de Twig). Deux responsabilités :
|
||||
|
||||
1. **API REST** — endpoints consommés par le frontend React
|
||||
2. **Pipeline** — crons + workers de traitement satellite
|
||||
|
||||
### Frontend — React SPA
|
||||
|
||||
Application React statique servie par FrankenPHP (ou Traefik directement). Consomme l'API Symfony et affiche les vector tiles via MapLibre GL JS.
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Spots & scores
|
||||
|
||||
```
|
||||
GET /api/spots Liste des CoastalPoints
|
||||
GET /api/spots/{id} Détail d'un CoastalPoint
|
||||
GET /api/spots/{id}/score ImpactScore courant + horizons
|
||||
GET /api/spots/{id}/score?at={datetime} Score à un instant donné
|
||||
```
|
||||
|
||||
### Observations & prédictions
|
||||
|
||||
```
|
||||
GET /api/observations?bbox={bbox}&date={date} Observations dans une zone
|
||||
GET /api/observations/{id} Détail observation
|
||||
GET /api/forecasts?observationId={id} Prédictions d'une observation
|
||||
GET /api/forecasts?bbox={bbox}&horizon={h} Prédictions par zone + horizon
|
||||
```
|
||||
|
||||
### Feedback
|
||||
|
||||
```
|
||||
POST /api/feedback Soumettre un UserFeedback anonyme
|
||||
```
|
||||
|
||||
### Tiles (statiques, hors API)
|
||||
|
||||
```
|
||||
GET /tiles/observations/{z}/{x}/{y}.pbf
|
||||
GET /tiles/forecasts/{horizon}/{z}/{x}/{y}.pbf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vector Tiles
|
||||
|
||||
### Stratégie : Tippecanoe + tiles statiques
|
||||
|
||||
- Les observations et prédictions sont converties en tiles `.pbf` après chaque ingestion (via Tippecanoe)
|
||||
- Les tiles sont stockées sur le filesystem du VPS et servies statiquement
|
||||
- Pas de rendu dynamique à la volée (Tegola écarté — complexité non justifiée au MVP)
|
||||
- Cloudflare free tier peut mettre ces tiles en cache si activé
|
||||
|
||||
### Interdits
|
||||
|
||||
- GeoJSON brut exposé en production sur des géométries complexes
|
||||
|
||||
---
|
||||
|
||||
## Caching
|
||||
|
||||
| Données | Stratégie | TTL suggéré |
|
||||
|---|---|---|
|
||||
| Scores par spot | Redis | 3h (durée du cycle d'ingestion) |
|
||||
| Résultats API observations | Redis | 3h |
|
||||
| Vector tiles statiques | HTTP Cache + Cloudflare | Long (invalidation à chaque ingestion) |
|
||||
| Endpoints publics | HTTP Cache | 15–30 min |
|
||||
|
||||
Règle : **1 requête = 1 zone + 1 timestamp**, pas de recalcul à la volée.
|
||||
|
||||
---
|
||||
|
||||
## Sécurité
|
||||
|
||||
- Rate limiting sur tous les endpoints publics (Symfony RateLimiter)
|
||||
- Aucune donnée personnelle collectée (UserFeedback = fingerprint anonyme)
|
||||
- Retry automatique pipeline avec backoff
|
||||
- Logs structurés sur chaque DataIngestionJob
|
||||
- Secrets (clés API Sentinel Hub, NOAA) via variables d'environnement Docker
|
||||
|
||||
---
|
||||
|
||||
## Schéma de flux de données
|
||||
|
||||
```
|
||||
Sentinel Hub API
|
||||
└── Cron Symfony (3h)
|
||||
└── DataIngestionJob
|
||||
├── Calcul AFAI → SargassumObservation
|
||||
│ └── Tippecanoe → tiles statiques /tiles/observations/
|
||||
└── Simulation dérive → SargassumForecast (×4 horizons)
|
||||
├── Calcul ImpactScore par CoastalPoint → Redis
|
||||
└── Tippecanoe → tiles statiques /tiles/forecasts/
|
||||
|
||||
NOAA GRIB API
|
||||
└── (consommé pendant la simulation de dérive)
|
||||
|
||||
React SPA
|
||||
├── MapLibre GL JS → /tiles/...pbf
|
||||
└── Symfony API → /api/spots/{id}/score
|
||||
```
|
||||
141
docs/data-model.md
Normal file
141
docs/data-model.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# DATA MODEL — Sargasse-Sentry
|
||||
|
||||
## Principe fondamental
|
||||
|
||||
Séparer strictement :
|
||||
- **Observation** — ce qui a été détecté (réel)
|
||||
- **Forecast** — ce qui est simulé (prédiction)
|
||||
- **Job** — traçabilité du pipeline
|
||||
- **Score** — agrégat calculé pour un point côtier
|
||||
- **Feedback** — retour terrain anonyme
|
||||
|
||||
---
|
||||
|
||||
## Entité : SargassumObservation
|
||||
|
||||
Représente une détection satellite réelle.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `geometry` | MULTIPOLYGON (SRID 4326) | Polygones détectés |
|
||||
| `bbox` | GEOMETRY BOX | Bounding box — requêtes spatiales légères |
|
||||
| `detectedAt` | datetime UTC | Immutable |
|
||||
| `source` | string | `Sentinel-2` / `Sentinel-3` |
|
||||
| `tileId` | string | Identifiant tuile Sentinel |
|
||||
| `cloudCoverage` | float 0–100 | % couverture nuageuse |
|
||||
| `confidence` | float 0–1 | Indice de confiance détection |
|
||||
| `afaiMean` | float | Valeur AFAI moyenne |
|
||||
| `afaiStd` | float | Écart-type AFAI |
|
||||
| `coverageArea` | float (km²) | Surface totale détectée |
|
||||
| `processingVersion` | string | Version de l'algorithme AFAI utilisé |
|
||||
| `createdAt` | datetime | |
|
||||
|
||||
**Index :**
|
||||
- `GIST (geometry)`
|
||||
- `GIST (bbox)`
|
||||
- `BTREE (detectedAt)`
|
||||
- `BTREE (source)`
|
||||
|
||||
---
|
||||
|
||||
## Entité : SargassumForecast
|
||||
|
||||
Projection issue du modèle de dérive.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `sourceObservation` | FK → SargassumObservation | |
|
||||
| `geometry` | MULTIPOLYGON (SRID 4326) | Polygone prédit |
|
||||
| `validAt` | datetime UTC | Moment auquel la prédiction est valide |
|
||||
| `computedAt` | datetime | Moment du calcul |
|
||||
| `modelVersion` | string | Version du modèle de dérive |
|
||||
| `timeHorizon` | int (heures) | `6 / 12 / 24 / 48` |
|
||||
| `confidence` | float 0–1 | |
|
||||
| `driftVectorAvg` | GEOMETRY(POINT, 4326) | Vecteur de dérive moyen (PostGIS natif) |
|
||||
| `createdAt` | datetime | |
|
||||
|
||||
**Index :**
|
||||
- `GIST (geometry)`
|
||||
- `BTREE (validAt)`
|
||||
- `BTREE (timeHorizon)`
|
||||
|
||||
---
|
||||
|
||||
## Entité : DataIngestionJob
|
||||
|
||||
Traçabilité du pipeline — robustesse obligatoire.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `source` | string | `Sentinel-2` / `Sentinel-3` |
|
||||
| `tileId` | string | |
|
||||
| `requestedAt` | datetime | |
|
||||
| `processedAt` | datetime (nullable) | |
|
||||
| `status` | enum | `pending / success / failed` |
|
||||
| `retryCount` | int | |
|
||||
| `errorMessage` | string (nullable) | |
|
||||
|
||||
---
|
||||
|
||||
## Entité : CoastalPoint
|
||||
|
||||
Points d'intérêt utilisateur.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `name` | string | |
|
||||
| `geometry` | POINT (SRID 4326) | |
|
||||
| `type` | enum | `beach / port / surf / fishing` |
|
||||
| `region` | string | |
|
||||
|
||||
---
|
||||
|
||||
## Entité : ImpactScore
|
||||
|
||||
Score calculé pour un point côtier à un instant donné.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `coastalPoint` | FK → CoastalPoint | |
|
||||
| `timestamp` | datetime | |
|
||||
| `score` | int 0–100 | |
|
||||
| `level` | enum | `low / medium / high` |
|
||||
| `distanceToNearestSargassum` | float (km) | |
|
||||
| `densityEstimate` | float | |
|
||||
| `trend` | enum | `increasing / stable / decreasing` |
|
||||
|
||||
---
|
||||
|
||||
## Entité : UserFeedback
|
||||
|
||||
Retour terrain anonyme — alimente la boucle d'apprentissage.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID | PK |
|
||||
| `location` | POINT (SRID 4326) | Localisation signalée |
|
||||
| `coastalPoint` | FK → CoastalPoint (nullable) | Si associé à un point connu |
|
||||
| `timestamp` | datetime | |
|
||||
| `hasSeaweed` | bool | Présence confirmée ou infirmée |
|
||||
| `density` | enum (nullable) | `low / medium / high` |
|
||||
| `source` | string | Fingerprint anonyme (IP hachée) — pas de compte |
|
||||
|
||||
---
|
||||
|
||||
## Schéma des relations
|
||||
|
||||
```
|
||||
SargassumObservation
|
||||
└── SargassumForecast (N)
|
||||
|
||||
CoastalPoint
|
||||
└── ImpactScore (N)
|
||||
└── UserFeedback (N, nullable)
|
||||
|
||||
DataIngestionJob (indépendant, audit trail)
|
||||
```
|
||||
136
docs/roadmap.md
Normal file
136
docs/roadmap.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# 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
|
||||
|
||||
- [ ] Initialisation dépôt Git
|
||||
- [ ] Configuration Docker (FrankenPHP + PostgreSQL/PostGIS + Redis)
|
||||
- [ ] Configuration Traefik (domaine, SSL)
|
||||
- [ ] Variables d'environnement (Sentinel Hub API key, NOAA, DB, Redis)
|
||||
- [ ] Initialisation projet Symfony
|
||||
- [ ] Installation API Platform (ou controllers JSON manuels)
|
||||
- [ ] Initialisation projet React
|
||||
- [ ] Configuration MapLibre GL JS + react-map-gl
|
||||
|
||||
### Base de données
|
||||
|
||||
- [ ] Extension PostGIS activée
|
||||
- [ ] Migration : `SargassumObservation`
|
||||
- [ ] Migration : `SargassumForecast`
|
||||
- [ ] Migration : `DataIngestionJob`
|
||||
- [ ] Migration : `CoastalPoint`
|
||||
- [ ] Migration : `ImpactScore`
|
||||
- [ ] Migration : `UserFeedback`
|
||||
- [ ] Index spatiaux (GIST) + index BTREE définis
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — MVP (Antilles, observations uniquement)
|
||||
|
||||
### Pipeline d'ingestion
|
||||
|
||||
- [ ] Cron Symfony toutes les 3h
|
||||
- [ ] Appel API Sentinel Hub (bandes B04, B08, B11)
|
||||
- [ ] Création `DataIngestionJob` (pending → success/failed)
|
||||
- [ ] Retry automatique + logging erreurs
|
||||
- [ ] Filtrage nuages (seuil configurable, défaut 60%)
|
||||
- [ ] Calcul AFAI (formule complète avec ratio longueurs d'onde)
|
||||
- [ ] Rasterisation → raster binaire sargasse/non
|
||||
- [ ] Vectorisation (raster → polygones, Douglas-Peucker, suppression bruit)
|
||||
- [ ] Persistance `SargassumObservation`
|
||||
- [ ] Génération vector tiles (Tippecanoe → `.pbf`)
|
||||
|
||||
### API Backend
|
||||
|
||||
- [ ] `GET /api/spots` — liste CoastalPoints
|
||||
- [ ] `GET /api/spots/{id}` — détail
|
||||
- [ ] `GET /api/observations?bbox=&date=` — observations par zone
|
||||
|
||||
### Frontend React
|
||||
|
||||
- [ ] Carte de base (MapLibre GL JS)
|
||||
- [ ] Affichage vector tiles observations
|
||||
- [ ] Sélection d'un CoastalPoint (Spot Mode)
|
||||
- [ ] Affichage polygones observés
|
||||
|
||||
### Données initiales
|
||||
|
||||
- [ ] Seed `CoastalPoint` zone Antilles (plages, ports, spots surf, zones pêche)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Dérive & Score
|
||||
|
||||
### Pipeline — simulation de dérive
|
||||
|
||||
- [ ] Accès NOAA GRIB (vent + courant)
|
||||
- [ ] Échantillonnage polygone (centroids + random sampling)
|
||||
- [ ] Application vecteur dérive par point
|
||||
- [ ] Reconstruction polygone (convex hull / alpha shape)
|
||||
- [ ] Génération horizons H+6, H+12, H+24, H+48
|
||||
- [ ] Persistance `SargassumForecast`
|
||||
- [ ] Génération vector tiles prédictions (Tippecanoe)
|
||||
|
||||
### Calcul ImpactScore
|
||||
|
||||
- [ ] Calcul score par `CoastalPoint` (distance, densité, vitesse d'approche, tendance)
|
||||
- [ ] Persistance `ImpactScore`
|
||||
- [ ] Mise en cache Redis (TTL 3h)
|
||||
|
||||
### API Backend
|
||||
|
||||
- [ ] `GET /api/spots/{id}/score` — score courant + horizons
|
||||
- [ ] `GET /api/spots/{id}/score?at={datetime}` — score à un instant
|
||||
- [ ] `GET /api/forecasts?observationId=` — prédictions par observation
|
||||
- [ ] `GET /api/forecasts?bbox=&horizon=` — prédictions par zone + horizon
|
||||
|
||||
### Frontend React
|
||||
|
||||
- [ ] Spot Mode complet (OK / Risque / Impact par horizon)
|
||||
- [ ] Slider temporel (Now → +6h → +12h → +24h → +48h)
|
||||
- [ ] Mise à jour dynamique polygones + score sur slider
|
||||
- [ ] Gradients radiaux densité
|
||||
- [ ] Animation légère sur polygones de prédiction
|
||||
- [ ] Vue mobile optimisée
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Feedback & Alertes
|
||||
|
||||
### Boucle d'apprentissage
|
||||
|
||||
- [ ] Bouton "Je confirme présence de sargasses"
|
||||
- [ ] `POST /api/feedback` — persistance `UserFeedback` anonyme
|
||||
- [ ] Intégration feedback dans calcul score (pondération)
|
||||
|
||||
### Alertes push
|
||||
|
||||
- [ ] Définir modalité d'inscription légère (push token navigateur ou email)
|
||||
- [ ] Système d'abonnement par `CoastalPoint`
|
||||
- [ ] Worker Symfony — envoi alertes si score dépasse seuil
|
||||
- [ ] Interface d'inscription (friction minimale)
|
||||
|
||||
---
|
||||
|
||||
## Transversal (continu)
|
||||
|
||||
- [ ] Rate limiting endpoints publics
|
||||
- [ ] Monitoring pipeline (alertes si ingestion échoue > N fois)
|
||||
- [ ] Logs structurés
|
||||
- [ ] Fallback Sentinel-2 → Sentinel-3
|
||||
- [ ] Configuration Cloudflare free tier (cache tiles statiques)
|
||||
- [ ] Tests fonctionnels pipeline (ingestion → score)
|
||||
170
docs/specs.md
Normal file
170
docs/specs.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# SPECS — Sargasse-Sentry
|
||||
|
||||
## Vision Produit
|
||||
|
||||
Sargasse-Sentry est une plateforme de renseignement maritime autonome transformant des données satellites brutes en information directement exploitable pour la prise de décision terrain.
|
||||
|
||||
Le produit ne doit pas être perçu comme une carte, mais comme un **outil d'aide à la décision en environnement incertain**, avec un focus sur :
|
||||
|
||||
- anticipation
|
||||
- lisibilité immédiate
|
||||
- confiance dans la donnée
|
||||
|
||||
### Utilisateurs cibles
|
||||
|
||||
| Profil | Usage |
|
||||
|---|---|
|
||||
| Marins-pêcheurs | Décision de sortie |
|
||||
| Surfeurs | Qualité du spot |
|
||||
| Baigneurs | Sécurité / nuisance |
|
||||
|
||||
### Contraintes produit
|
||||
|
||||
- Gratuit
|
||||
- Sans inscription obligatoire (sauf alertes push, voir Roadmap V3)
|
||||
- Mobile-first
|
||||
- Compréhensible en moins de 3 secondes
|
||||
|
||||
---
|
||||
|
||||
## UX — Logique Produit
|
||||
|
||||
### Mode principal : Spot Mode
|
||||
|
||||
L'utilisateur sélectionne un point côtier → affichage :
|
||||
|
||||
| Horizon | Indicateur |
|
||||
|---|---|
|
||||
| Aujourd'hui | OK / Risque / Impact |
|
||||
| +24h | OK / Risque / Impact |
|
||||
| +48h | OK / Risque / Impact |
|
||||
|
||||
### Timeline interactive
|
||||
|
||||
Slider temporel : `Now → +6h → +12h → +24h → +48h`
|
||||
|
||||
Met à jour en temps réel :
|
||||
- les polygones sur la carte
|
||||
- le score d'impact
|
||||
|
||||
### Impact Score
|
||||
|
||||
Calcul basé sur :
|
||||
|
||||
```
|
||||
score = f(distance côte, densité, vitesse d'approche, évolution tendancielle)
|
||||
```
|
||||
|
||||
| Score | Niveau |
|
||||
|---|---|
|
||||
| 0–30 | OK |
|
||||
| 30–70 | Risque |
|
||||
| 70–100 | Impact |
|
||||
|
||||
### Visualisation
|
||||
|
||||
- Gradients radiaux pour la densité
|
||||
- Contour épais pour la lisibilité
|
||||
- Animation légère **uniquement** sur les prédictions (pas les observations)
|
||||
|
||||
### Boucle d'apprentissage (différenciateur)
|
||||
|
||||
Bouton : **"Je confirme présence de sargasses"**
|
||||
|
||||
Stocke un `UserFeedback` anonyme (localisation, timestamp, confirmation, densité estimée).
|
||||
|
||||
---
|
||||
|
||||
## Pipeline de Données
|
||||
|
||||
### Étape 1 — Ingestion
|
||||
- Cron Symfony toutes les 3h
|
||||
- Appel API Sentinel Hub
|
||||
- Récupération bandes B04 (RED), B08 (NIR), B11 (SWIR1)
|
||||
- Création d'un `DataIngestionJob`
|
||||
|
||||
### Étape 2 — Pré-traitement
|
||||
- Filtrage nuages : rejet si `cloudCoverage > seuil`
|
||||
- Seuil configurable par région (défaut 60% — peut être ajusté pour zones tropicales à forte nébulosité)
|
||||
|
||||
### Étape 3 — Calcul AFAI
|
||||
|
||||
Formule complète :
|
||||
|
||||
```
|
||||
AFAI = R_NIR - R_RED - (R_SWIR1 - R_RED) × (λ_NIR - λ_RED) / (λ_SWIR1 - λ_RED)
|
||||
```
|
||||
|
||||
- `R_*` : réflectance de surface des bandes Sentinel
|
||||
- `λ_*` : longueurs d'onde centrales (constantes fixes par capteur)
|
||||
|
||||
Résultat : raster binaire (sargasse / non-sargasse)
|
||||
|
||||
### Étape 4 — Vectorisation
|
||||
- Raster → polygones
|
||||
- Simplification Douglas-Peucker
|
||||
- Suppression du bruit (polygones < seuil surface minimal)
|
||||
|
||||
### Étape 5 — Simulation de dérive (CRITIQUE)
|
||||
|
||||
Ne pas appliquer de translation globale.
|
||||
|
||||
Algorithme :
|
||||
1. **Échantillonnage** du polygone : génération de points internes (centroids + random sampling)
|
||||
2. **Pour chaque point** : récupération vent + courant (GRIB NOAA) → application du vecteur de dérive
|
||||
3. **Reconstruction** du polygone : convex hull ou alpha shape
|
||||
4. **Génération des horizons** : H+6, H+12, H+24, H+48
|
||||
|
||||
### Sources de données
|
||||
|
||||
| Source | Usage | Notes |
|
||||
|---|---|---|
|
||||
| Sentinel-2 | Observations haute résolution | Faible fréquence |
|
||||
| Sentinel-3 | Fallback | Fréquence élevée |
|
||||
| NOAA GRIB | Vent + courant | Gratuit, accès HTTP direct |
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
### Caching
|
||||
|
||||
- **Redis** : résultats API, scores d'impact
|
||||
- **HTTP Cache** : endpoints publics, tiles statiques
|
||||
- **Cloudflare free tier** (optionnel, sans coût) : CDN pour les vector tiles statiques
|
||||
|
||||
### Stratégie
|
||||
|
||||
- 1 requête = 1 zone + 1 timestamp
|
||||
- Pas de recalcul à la volée
|
||||
- Scores pré-calculés à chaque ingestion
|
||||
|
||||
---
|
||||
|
||||
## Sécurité & Résilience
|
||||
|
||||
- Retry automatique sur ingestion échouée
|
||||
- Fallback Sentinel-2 → Sentinel-3 si indisponible
|
||||
- Logs détaillés sur chaque `DataIngestionJob`
|
||||
- Monitoring des erreurs pipeline
|
||||
- Rate limiting sur les endpoints publics
|
||||
|
||||
---
|
||||
|
||||
## Roadmap
|
||||
|
||||
### MVP
|
||||
- Ingestion Sentinel-2
|
||||
- Calcul AFAI + vectorisation
|
||||
- Affichage polygones (observations uniquement)
|
||||
- Zone géographique : Antilles
|
||||
|
||||
### V2
|
||||
- Dérive H+6 / H+12 / H+24 / H+48
|
||||
- Score d'impact par `CoastalPoint`
|
||||
- Interface Spot Mode complète
|
||||
|
||||
### V3
|
||||
- Alertes push (nécessite inscription légère : push token ou email — à concevoir en minimisant la friction)
|
||||
- Boucle feedback utilisateur (`UserFeedback`)
|
||||
- Amélioration du modèle de dérive via données terrain
|
||||
Reference in New Issue
Block a user