📚 Documentation CerOps
Ce dossier contient la documentation fonctionnelle et technique du projet CerOps.
Objectif
Centraliser la vision produit, les choix techniques et les règles métier afin de :
- faciliter le développement
- aligner l’équipe
- préparer les livrables (école / pitch / démo)
Structure
parcelles.md→ gestion des parcelles agricolesagriculteurs.md→ gestion des utilisateurs agriculteurspilotes-drone.md→ gestion des pilotes de dronemarketplace.md→ mise en relation agriculteurs ↔ pilotesimagerie-parcellaire.md→ traitement et exploitation des imagesplan-actions.md→ recommandations et suivi d’actionsmobile-map-offline.md→ fonctionnement mobile + offlineapi-contrats.md→ contrats entre frontend et backend
Règles
- 1 fichier = 1 domaine
- Utiliser le template commun
- Mettre à jour la doc en même temps que le code
🎯 Gestion des parcelles
Contexte
Le module de gestion des parcelles est au cœur de CerOps. Il permet de représenter, stocker et manipuler les surfaces agricoles exploitées par les agriculteurs.
Les données initiales proviennent du Registre Parcellaire Graphique (RPG), une source officielle contenant les géométries des parcelles agricoles en France.
Ces parcelles servent de base pour :
- la visualisation cartographique
- l’analyse agronomique (NDVI, imagerie)
- les actions terrain (photos, interventions)
- la planification des missions drone
Objectif
Permettre :
- d’importer et stocker des parcelles agricoles fiables
- de les associer à des agriculteurs
- de les afficher sur une carte mobile
- de les modifier/éditer depuis le mobile
- de servir de support à toutes les fonctionnalités métier (drone, imagerie, plan d’actions)
Utilisateurs concernés
- Agriculteur → consulte et gère ses parcelles
- Pilote de drone → intervient sur des parcelles
- Admin → supervise et corrige les données
Fonctionnalités (User Stories)
- En tant qu’agriculteur, je veux voir mes parcelles sur une carte afin de visualiser mon exploitation
- En tant qu’agriculteur, je veux modifier les limites d’une parcelle afin de corriger les données
- En tant qu’utilisateur, je veux importer des parcelles existantes (RPG) afin de ne pas tout recréer manuellement
- En tant que pilote de drone, je veux accéder aux parcelles afin de planifier mes missions
- En tant qu’utilisateur mobile, je veux consulter les parcelles hors ligne afin de travailler sur le terrain sans réseau
- En tant qu’utilisateur, je veux sélectionner une parcelle afin d’y associer des actions ou des photos
Données manipulées
Entités principales
Parcelle
- id
- nom (optionnel)
- géométrie (polygone)
- surface (calculée ou stockée)
- culture (optionnel)
- source (RPG / utilisateur)
- date de création
- date de modification
Agriculteur
- id
- nom
- relation avec parcelles
Stockage
- Base de données : PostgreSQL + PostGIS
- Type géométrique :
PolygonouMultiPolygon - Format API : GeoJSON
Relations
- 1 Agriculteur → N Parcelles
- 1 Parcelle → N Actions (futur)
- 1 Parcelle → N Images (drone / terrain)
API / Interfaces
Endpoints principaux
GET /parcelles
Retourne la liste des parcelles d’un utilisateur
GET /parcelles/:id
Retourne le détail d’une parcelle
POST /parcelles
Créer une parcelle (manuel ou import)
PUT /parcelles/:id
Modifier une parcelle (géométrie incluse)
DELETE /parcelles/:id
Supprimer une parcelle
Format de réponse (exemple)
{
"id": "parcelle_1",
"nom": "Champ Nord",
"geometry": {
"type": "Polygon",
"coordinates": ["..."]
},
"surface": 2.5,
"culture": "blé"
}
Écrans / UX
Mobile
Carte principale avec :
- fond OSM
- affichage des parcelles (polygones)
Interaction :
- sélection d’une parcelle
- affichage des infos
Mode édition :
- déplacer les points du polygone
- ajouter/supprimer des points
Actions :
- Bouton “Créer une parcelle”
- Bouton “Modifier”
Cas limites
Offline
- Les parcelles doivent être disponibles hors-ligne (cache local)
- Les modifications doivent être stockées localement puis synchronisées
Erreurs
- Géométrie invalide (polygone non fermé, intersections)
- Conflits de modification (multi-device)
Données manquantes
- Parcelle sans nom
- Parcelle sans culture
→ acceptable en MVP
Critères d’acceptation
- Les parcelles RPG peuvent être importées
- Les parcelles sont stockées en base PostGIS
- Une parcelle est associée à un agriculteur
- Les parcelles sont exposées via une API en GeoJSON
- Les parcelles s’affichent sur la carte mobile
- Une parcelle peut être sélectionnée
- Une parcelle peut être modifiée depuis le mobile
- Les parcelles sont accessibles hors-ligne
- Les modifications offline sont synchronisées
Dépendances
- Backend → API parcelles + PostGIS
- Mobile → affichage carte + édition géométrie
- Drone → utilisation des parcelles pour missions
- Imagerie → association images ↔ parcelles
- Plan d’actions → association actions ↔ parcelles
MVP vs Post-MVP
MVP
- Import RPG manuel
- Stockage PostGIS
- API parcelles simple
- Affichage carte (OSM + polygones)
- Sélection parcelle
- Édition basique (déplacement points)
- Cache offline simple
Post-MVP
- Import automatique RPG
- Détection intelligente des parcelles
- Historique des modifications
- Versioning des parcelles
- Validation géométrique avancée
- Collaboration multi-utilisateur
- Découpage/fusion de parcelles
- Analyse NDVI/NDRE par parcelle
🎯 [Nom du module]
Contexte
Décrire le rôle de ce module dans CerOps.
Objectif
Quel problème ce module résout ?
Utilisateurs concernés
- Agriculteur
- Pilote de drone
- Admin
- Autre ?
Fonctionnalités (User Stories)
- En tant que …, je veux …, afin de …
Données manipulées
- Entités
- Champs importants
- Relations
API / Interfaces
- Endpoints concernés
- Inputs / outputs
Écrans / UX
- Pages / composants liés
- Comportements attendus
Cas limites
- Offline ?
- Erreurs ?
- Données manquantes ?
Critères d’acceptation
- …
- …
Dépendances
- Backend
- Mobile
- Drone
- Autres modules
MVP vs Post-MVP
MVP
- …
Post-MVP
- …
🎯 [Nom du module]
Contexte
Décrire le rôle de ce module dans CerOps.
Objectif
Quel problème ce module résout ?
Utilisateurs concernés
- Agriculteur
- Pilote de drone
- Admin
- Autre ?
Fonctionnalités (User Stories)
- En tant que …, je veux …, afin de …
Données manipulées
- Entités
- Champs importants
- Relations
API / Interfaces
- Endpoints concernés
- Inputs / outputs
Écrans / UX
- Pages / composants liés
- Comportements attendus
Cas limites
- Offline ?
- Erreurs ?
- Données manquantes ?
Critères d’acceptation
- …
- …
Dépendances
- Backend
- Mobile
- Drone
- Autres modules
MVP vs Post-MVP
MVP
- …
Post-MVP
- …
🎯 Marketplace pilotes de drone
Contexte
Le module Marketplace permet de connecter les besoins des agriculteurs, exprimés dans CerOps, avec les pilotes de drone capables de réaliser les missions.
La marketplace est une application web séparée, accessible uniquement aux pilotes de drone.
Les agriculteurs n’y ont pas accès.
Les missions sont créées automatiquement dans la marketplace à partir des demandes de survol faites dans CerOps.
Le rôle de la marketplace est de :
- exposer ces missions aux pilotes
- permettre leur sélection et planification
- gérer l’exécution et la livraison des résultats
Stack technique retenue
- Frontend : Next.js + TailwindCSS + shadcn/ui
- Backend : Fastify + oRPC
- Base de données : PostgreSQL + Prisma
- Auth : Better-Auth
- Runtime : Bun
- Paiement : Stripe
- Cartographie : Map (OSM ou équivalent)
- Notifications : système backend (push/email)
Objectif
Permettre :
- aux agriculteurs (via CerOps) de faire des demandes de survol
- de transformer ces demandes en missions exploitables
- de les proposer aux pilotes adaptés à leur matériel
- de permettre aux pilotes de sélectionner, planifier et exécuter ces missions
- de centraliser la livraison des données collectées
Ce module résout le problème de mise en relation entre :
- un besoin agronomique
- et une capacité technique (drone + capteurs)
Utilisateurs concernés
- Pilote de drone (principal)
- Admin (gestion plateforme)
- Backend CerOps (source des missions)
Fonctionnalités (User Stories)
- En tant que pilote, je veux voir les missions disponibles autour de moi afin de choisir celles qui m’intéressent
- En tant que pilote, je veux filtrer les missions compatibles avec mon matériel afin de ne voir que celles que je peux réaliser
- En tant que pilote, je veux voir toutes les missions disponibles afin d’identifier des opportunités d’investissement matériel
- En tant que pilote, je veux accepter une mission afin de la réserver
- En tant que pilote, je veux planifier une mission dans une plage horaire flexible afin de m’adapter à la météo
- En tant que pilote, je veux uploader les résultats du survol afin de livrer la mission
- En tant que système, je veux matcher les missions avec les capacités des pilotes afin de proposer les missions pertinentes
- En tant que plateforme, je veux gérer le paiement de manière sécurisée afin de garantir la transaction
Données manipulées
Entités principales
Mission
- id
- exploitationId
- parcelleIds[]
- localisation (géométrie)
- surfaceTotale
- typeMission
- capteursRequis[]
- plageTemporelle
- prix
- statut
- piloteId (optionnel)
- createdAt
- updatedAt
Pilote
- id
- nom / société
- zoneIntervention
- drones[]
- capteurs[]
- certifications[]
- disponibilite
- scoreInterne
- historiqueMissions
Capteur
- id
- nom
- type (multispectral, thermique, RGB, etc.)
- capabilities[]
Livraison (Deliverable)
- id
- missionId
- fichiers[]
- commentaire
- createdAt
Paiement
- id
- missionId
- montant
- statut (pre_authorized, captured, refunded)
- stripePaymentId
Relations
- 1 Mission → N Parcelles
- 1 Mission → 1 Pilote
- 1 Pilote → N Missions
- 1 Mission → 1 Livraison
- 1 Mission → 1 Paiement
API / Interfaces
Endpoints principaux
Missions
GET /missionsGET /missions/:idPOST /missions/:id/acceptPOST /missions/:id/schedulePOST /missions/:id/uploadPOST /missions/:id/cancel
Pilotes
GET /pilotes/mePUT /pilotes/me
Matching
GET /missions?compatible=true
Paiement
POST /payments/createPOST /payments/capture
Inputs / outputs
Entrées
- mission créée depuis CerOps
- acceptation par pilote
- planning
- fichiers upload
Sorties
- liste des missions
- missions compatibles / non compatibles
- détails mission
- statut mission
- livrables
Écrans / UX
Dashboard pilote
- liste des missions disponibles
- filtre :
- missions compatibles
- toutes les missions
- indicateur de compatibilité (OK / non compatible + raison)
Vue carte
- affichage des missions comme des “points” (type Airbnb)
- localisation exacte
- possibilité de cliquer pour voir le détail
Détail mission
- parcelles concernées
- surface
- type de mission
- capteurs requis
- plage temporelle
- prix
- statut
- compatibilité avec le matériel
Acceptation mission
- bouton “Accepter”
- passage du statut à
reserved
Planification
- sélection d’un créneau dans la plage définie
- suggestion météo (visuelle uniquement)
Upload livrables
- upload fichiers libres (vidéo, images, etc.)
- ajout commentaire texte
- validation livraison
Cas limites
Offline
- la marketplace est une app web → pas de support offline prévu
Erreurs
- paiement échoué
- upload échoué
- mission déjà réservée
- conflit d’acceptation simultanée
Données manquantes
- mission sans capteur précis
- localisation incomplète → non autorisé en MVP
Concurrence
- plusieurs pilotes tentent d’accepter en même temps → le premier valide la mission
Annulation
- un pilote peut annuler
- impact sur score interne
- mission remise en
published
Critères d’acceptation
- Le fonctionnement marketplace est défini
- La séparation CerOps / marketplace est claire
- Les missions sont créées depuis CerOps
- Le matching capteur → mission est documenté
- Le système d’acceptation de mission est défini
- La planification avec plage horaire est décrite
- L’intégration Stripe est définie (pré-autorisation + capture)
- Les écrans principaux sont décrits
- Le système de visibilité missions compatibles / toutes missions est défini
- Les cas limites sont identifiés
- Les statuts de mission sont définis
Dépendances
- Backend CerOps → création des missions
- Mobile CerOps → création des demandes
- Backend marketplace → gestion missions
- Stripe → paiement
- Drone → exécution terrain
- Imagerie → analyse des données (hors marketplace)
MVP vs Post-MVP
MVP
- Création automatique de missions depuis CerOps
- Liste des missions
- Vue carte + liste
- Filtre missions compatibles
- Acceptation mission (first come, first served)
- Planification avec plage horaire
- Suggestion météo visuelle
- Upload fichiers + commentaire
- Paiement Stripe (pré-autorisation + capture)
- Score interne pilote
- Annulation + republication
Post-MVP
- Matching intelligent avancé (IA)
- Système de recommandation missions
- Optimisation des tournées pilotes
- Pricing dynamique avancé
- Historique détaillé des performances pilotes
- Système de réputation visible
- Notifications avancées temps réel
- Intégration météo intelligente (auto-planification)
- Analyse automatique des livrables
🎯 [Nom du module]
Contexte
Décrire le rôle de ce module dans CerOps.
Objectif
Quel problème ce module résout ?
Utilisateurs concernés
- Agriculteur
- Pilote de drone
- Admin
- Autre ?
Fonctionnalités (User Stories)
- En tant que …, je veux …, afin de …
Données manipulées
- Entités
- Champs importants
- Relations
API / Interfaces
- Endpoints concernés
- Inputs / outputs
Écrans / UX
- Pages / composants liés
- Comportements attendus
Cas limites
- Offline ?
- Erreurs ?
- Données manquantes ?
Critères d’acceptation
- …
- …
Dépendances
- Backend
- Mobile
- Drone
- Autres modules
MVP vs Post-MVP
MVP
- …
Post-MVP
- …
🎯 [Nom du module]
Contexte
Décrire le rôle de ce module dans CerOps.
Objectif
Quel problème ce module résout ?
Utilisateurs concernés
- Agriculteur
- Pilote de drone
- Admin
- Autre ?
Fonctionnalités (User Stories)
- En tant que …, je veux …, afin de …
Données manipulées
- Entités
- Champs importants
- Relations
API / Interfaces
- Endpoints concernés
- Inputs / outputs
Écrans / UX
- Pages / composants liés
- Comportements attendus
Cas limites
- Offline ?
- Erreurs ?
- Données manquantes ?
Critères d’acceptation
- …
- …
Dépendances
- Backend
- Mobile
- Drone
- Autres modules
MVP vs Post-MVP
MVP
- …
Post-MVP
- …
🎯 Mobile map & mode offline
Contexte
Ce module décrit le fonctionnement de l’application mobile CerOps autour de la carte, de la géolocalisation terrain et du mode hors-ligne.
L’objectif est de permettre à un agriculteur ou à un utilisateur terrain d’exploiter ses parcelles directement depuis son téléphone, même sans réseau, tout en conservant une expérience fluide et utile sur le terrain.
L’application repose sur :
flutter_mappour la carte- des fonds de carte OSM
- une base locale embarquée
- une synchronisation automatique avec le backend dès que le réseau revient
Le mode offline ne doit pas être global à toute la plateforme, mais centré sur l’exploitation agricole sélectionnée. Lorsqu’une exploitation est choisie, l’application prépare automatiquement une zone hors-ligne couvrant ses parcelles.
Stack technique retenue
- Framework mobile : Flutter
- Carte : flutter_map
- Fond cartographique : OpenStreetMap (OSM)
- Gestion d’état : Riverpod
- Base locale : Drift
- Stockage fichiers : stockage local appareil
- Synchronisation : queue locale + sync automatique au retour réseau
- Backend cible : Fastify + oRPC
Objectif
Permettre à l’utilisateur de :
- visualiser ses parcelles sur une carte mobile
- se géolocaliser sur le terrain
- consulter et modifier des données sans connexion
- prendre des photos et créer des actions hors-ligne
- synchroniser automatiquement ses changements lorsque le réseau revient
- gérer proprement les conflits de synchronisation
Ce module résout le problème principal d’un usage terrain en zone rurale, où la couverture réseau peut être instable ou absente.
Utilisateurs concernés
- Agriculteur
- Admin
- Utilisateur terrain
Fonctionnalités (User Stories)
- En tant qu’agriculteur, je veux sélectionner mon exploitation afin de charger automatiquement ma zone de travail hors-ligne
- En tant qu’agriculteur, je veux voir mes parcelles sur une carte afin de me repérer facilement sur le terrain
- En tant qu’agriculteur, je veux me géolocaliser afin de savoir où je me trouve par rapport à mes parcelles
- En tant qu’agriculteur, je veux consulter mes actions hors-ligne afin de continuer mon travail sans connexion
- En tant qu’agriculteur, je veux modifier une parcelle hors-ligne afin de corriger des informations directement sur le terrain
- En tant qu’agriculteur, je veux créer une action hors-ligne afin de noter une intervention ou un besoin observé
- En tant qu’agriculteur, je veux prendre des photos hors-ligne afin de documenter l’état d’une parcelle
- En tant qu’utilisateur, je veux que mes données se synchronisent automatiquement dès que le réseau revient afin d’éviter une action manuelle
- En tant qu’utilisateur, je veux être averti en cas de conflit de synchronisation afin de décider quelle version conserver
Données manipulées
Entités principales
Exploitation
- id
- nom
- parcelles associées
- zone offline calculée
Parcelle
- id
- exploitationId
- nom
- géométrie
- surface
- culture
- source
- updatedAt
- syncStatus
Action
Proposition de modèle minimum :
- id
- parcelleId
- exploitationId
- type
- titre
- description
- statut
- priorite
- datePrevue
- dateRealisation
- createdAt
- updatedAt
- createdBy
- syncStatus
- conflictVersionId (optionnel)
Valeurs possibles suggérées
-
type:- observation
- intervention
- traitement
- inspection
- irrigation
- autre
-
statut:- a_faire
- en_cours
- termine
- annule
-
priorite:- basse
- moyenne
- haute
-
syncStatus:- local_only
- pending_sync
- synced
- conflict
- sync_error
Photo
- id
- parcelleId
- actionId (optionnel)
- exploitationId
- localPath
- thumbnailPath
- mimeType
- latitude (optionnel)
- longitude (optionnel)
- takenAt
- createdAt
- updatedAt
- syncStatus
ZoneOffline
- id
- exploitationId
- boundingBox
- margeMetres
- downloadedAt
- tileVersion
- status
SyncQueue
- id
- entityType
- entityId
- operationType
- payload
- createdAt
- retryCount
- lastError
- status
Champs importants
syncStatussur les entités modifiablesupdatedAtpour comparaison local / distantlocalPathetthumbnailPathpour les photos offlineboundingBoxpour définir la zone de téléchargement cartographiqueretryCountetlastErrorpour suivre les échecs de synchronisation
Relations
- 1 Exploitation → N Parcelles
- 1 Exploitation → N Actions
- 1 Exploitation → N Photos
- 1 Parcelle → N Actions
- 1 Parcelle → N Photos
- 1 Action → N Photos
- 1 Exploitation → 1 ou plusieurs zones offline (post-MVP)
API / Interfaces
Endpoints concernés
Exploitations
GET /exploitationsGET /exploitations/:id
Parcelles
GET /parcelles?exploitationId=...GET /parcelles/:idPOST /parcellesPUT /parcelles/:id
Actions
GET /actions?exploitationId=...GET /actions/:idPOST /actionsPUT /actions/:id
Photos
POST /photosGET /photos?parcelleId=...GET /photos?actionId=...
Synchronisation
POST /sync/parcellesPOST /sync/actionsPOST /sync/photosGET /sync/conflictsPOST /sync/conflicts/:id/resolve
Inputs / outputs
Entrées côté mobile
- exploitation sélectionnée
- géolocalisation utilisateur
- modifications de parcelles
- nouvelles actions
- photos prises sur le terrain
Sorties affichées
- fond de carte OSM
- polygones des parcelles
- position GPS
- liste des actions
- galerie photo liée à une parcelle ou une action
- état de synchronisation
- conflits à résoudre
Écrans / UX
Sélection d’exploitation
- écran ou modal de sélection de l’exploitation
- déclenche automatiquement la préparation offline
- affiche l’état de téléchargement de la zone
Carte principale
- fond OSM
- affichage des parcelles sous forme de polygones
- centrage sur l’exploitation
- affichage de la position utilisateur
- sélection d’une parcelle
- affichage des informations principales de la parcelle
Vue détail parcelle
- informations de la parcelle
- liste des actions liées
- photos liées
- état de synchronisation
- bouton d’édition
Mode édition parcelle
- déplacement des points du polygone
- ajout de points
- suppression de points
- sauvegarde locale immédiate
- marquage en
pending_sync
Écran actions
- liste des actions par exploitation ou parcelle
- création d’action hors-ligne
- modification du statut
- affichage du statut de synchronisation
Écran photos
- prise de photo
- génération d’une miniature pour l’interface
- association à une parcelle ou une action
- stockage local du fichier avant envoi
Écran synchronisation
- état global de la sync
- nombre d’éléments en attente
- erreurs éventuelles
- liste des conflits à résoudre
- écran de comparaison en cas de conflit
Cas limites
Offline
- les parcelles doivent être disponibles hors-ligne
- les actions doivent être consultables et créables hors-ligne
- les photos doivent pouvoir être prises sans réseau
- les miniatures doivent être générées localement pour l’UI
- l’utilisateur peut ouvrir l’application hors-ligne s’il s’est déjà authentifié auparavant
Téléchargement de zone offline
- dès qu’une exploitation est sélectionnée, l’application calcule automatiquement une zone offline
- la zone est basée sur une bounding box contenant les parcelles de l’exploitation
- une marge de 250 mètres est ajoutée autour
- cette zone sert au téléchargement des tuiles cartographiques et des données métiers liées
Limites de la zone
- si les parcelles d’une exploitation sont très éloignées les unes des autres, la bounding box peut devenir trop grande
- dans ce cas, le volume de tuiles téléchargées peut être important
- pour le MVP, cette limite est acceptée
- en post-MVP, plusieurs zones offline distinctes pourront être gérées
Erreurs
- échec de téléchargement de tuiles
- géométrie de parcelle invalide
- photo corrompue ou trop volumineuse
- perte réseau pendant synchronisation
- backend indisponible
- file de synchronisation bloquée
Données manquantes
- parcelle sans nom
- action sans description détaillée
- photo sans géolocalisation
- certaines données non critiques sont acceptables en MVP
Conflits
- si une entité a été modifiée localement et à distance entre-temps, la synchronisation est bloquée pour cette entité
- l’utilisateur doit choisir la version à conserver ou fusionner manuellement selon le type d’objet
- un conflit ne doit pas écraser silencieusement les données
Authentification offline
- l’utilisateur peut rouvrir l’application hors ligne s’il a déjà une session valide stockée localement
- aucune nouvelle connexion ne peut être faite sans réseau
- certaines actions sensibles peuvent rester indisponibles si elles nécessitent une validation serveur
Critères d’acceptation
- Le fonctionnement de la carte mobile est documenté
- L’utilisation de
flutter_mapet OSM est précisée - La stratégie de sélection d’exploitation et de téléchargement automatique de zone offline est décrite
- La zone offline basée sur une bounding box avec marge de 250 m est définie
- Les parcelles sont disponibles hors-ligne
- Les actions sont disponibles et modifiables hors-ligne
- Les photos peuvent être prises hors-ligne
- Les miniatures photo sont générées localement pour l’interface
- La géolocalisation basique est décrite
- La synchronisation automatique au retour réseau est documentée
- La gestion des conflits est documentée
- L’authentification hors-ligne après première connexion est documentée
- Les limites du MVP sont identifiées
Dépendances
- Backend → endpoints exploitations, parcelles, actions, photos, sync
- Mobile → Flutter, flutter_map, gestion état, base locale, cache fichiers
- Cartographie → OSM + cache tuiles
- Stockage local → base locale pour parcelles/actions/queue + stockage fichiers pour photos
- Auth → persistance de session locale
- Drone → usage futur des parcelles et photos terrain
- Imagerie → association future avec traitement agronomique
- Plan d’actions → création et suivi des actions liées aux parcelles
MVP vs Post-MVP
MVP
- Utilisation de
flutter_mapavec fond OSM - Sélection d’une exploitation
- Téléchargement automatique d’une zone offline à partir des parcelles
- Calcul d’une bounding box avec marge de 250 m
- Téléchargement des tuiles nécessaires à cette zone
- Affichage offline des parcelles
- Géolocalisation basique
- Consultation et création d’actions hors-ligne
- Modification de parcelles hors-ligne
- Prise de photos hors-ligne
- Génération de miniatures locales
- Synchronisation automatique dès retour du réseau
- Détection de conflit et blocage de la sync concernée
- Résolution manuelle des conflits
- Réouverture hors-ligne après authentification initiale
Post-MVP
- Gestion de plusieurs zones offline par exploitation
- Téléchargement sélectif plus fin que la bounding box
- Prévisualisation de la taille de téléchargement
- Politique de purge intelligente du cache cartographique
- Fusion assistée des conflits
- Historique complet des modifications locales
- Compression ou optimisation automatique des photos avant sync
- Synchronisation plus avancée par événements ou file distribuée
- Notifications sur l’état de synchronisation
- Support d’usages drone plus poussés sur carte offline
🎯 [Nom du module]
Contexte
Décrire le rôle de ce module dans CerOps.
Objectif
Quel problème ce module résout ?
Utilisateurs concernés
- Agriculteur
- Pilote de drone
- Admin
- Autre ?
Fonctionnalités (User Stories)
- En tant que …, je veux …, afin de …
Données manipulées
- Entités
- Champs importants
- Relations
API / Interfaces
- Endpoints concernés
- Inputs / outputs
Écrans / UX
- Pages / composants liés
- Comportements attendus
Cas limites
- Offline ?
- Erreurs ?
- Données manquantes ?
Critères d’acceptation
- …
- …
Dépendances
- Backend
- Mobile
- Drone
- Autres modules
MVP vs Post-MVP
MVP
- …
Post-MVP
- …
⚙️ DevOps & Infrastructure
Monorepo
CerOps est organisé en monorepo géré par Turborepo et Bun. Toutes les applications et packages partagés cohabitent dans un seul dépôt Git, ce qui garantit la cohérence des types TypeScript entre le backend et les frontends, et simplifie les déploiements.
Bun est utilisé à la fois comme runtime JavaScript, package manager et outil de compilation (le serveur Fastify est compilé en binaire natif via bun build --compile). Les versions des dépendances partagées sont centralisées dans le workspace catalog pour éviter toute dérive entre packages.
Application mobile Flutter
L’application mobile agriculteurs est développée en Flutter dans un dépôt séparé. Elle n’est pas intégrée au monorepo pour deux raisons principales : l’écosystème Flutter (Dart, pub.dev) est incompatible avec la chaîne d’outils Bun/Node, et les cycles de release mobiles (App Store / Play Store) suivent un rythme indépendant du déploiement web.
L’app communique avec le même backend via les mêmes endpoints ORPC.
Intégration Continue (GitHub Actions)
Quatre workflows couvrent l’ensemble du cycle de qualité :
- CI (
ci.yaml) : build, tests unitaires et lint (Biome, knip, sherif) — déclenché sur chaque PR et push surmain - E2E (
e2e.yaml) : tests Playwright avec une base PostGIS éphémère — déclenché sur chaque PR - PR title (
pr-title.yaml) : validation Conventional Commits - Docs (
docs.yaml) : compilation mdBook — déclenché uniquement sidocs/**est modifié
Le cache Turborepo est restauré entre les runs pour ne reconstruire que les packages affectés par la PR.
Conteneurisation (Docker)
Chaque application a son propre Dockerfile multi-stage : le pruning Turborepo extrait uniquement les fichiers nécessaires à l’app ciblée, puis le build produit une image minimale. Le serveur est distribué comme binaire compilé, les frontends Next.js en mode standalone.
Déploiement : Coolify
Coolify est le PaaS self-hosted qui orchestre tous les services. Aujourd’hui, en phase de développement, Coolify effectue lui-même les builds directement depuis le dépôt Git à chaque push sur main.
À terme, cette responsabilité sera transférée à GitHub Actions : un workflow dédié se chargera de builder et publier une image Docker taguée (ex. v1.2.0) sur le registry, et Coolify n’aura plus qu’à déployer cette image prébuilt sur l’environnement cible (production, pré-production, etc.) sans refaire de build. Cette séparation garantit que le même artefact immuable traverse tous les environnements.
Services applicatifs
Les trois applications (server, web-agri, web-pilots) sont chacune un service Coolify distinct pointant sur leur Dockerfile respectif.
Base de données
La base de données est un service PostGIS (PostgreSQL + extension géospatiale) provisionné par Coolify. L’extension PostGIS est utilisée pour les calculs géographiques liés aux zones agricoles et aux missions terrain.
Services annexes
Coolify héberge également :
- OpenObserve — observabilité unifiée (logs, métriques, traces)
- RustFS — stockage objet compatible S3 (uploads, livrables de missions)
- pgAdmin — interface d’administration PostgreSQL
- mdBook — cette documentation
Architecture de déploiement (actuelle — full dev)
GitHub (push main)
│
▼ webhook + build
Coolify
├── server (API Fastify)
├── web-agri (frontend agriculteurs)
├── web-pilots (frontend pilotes)
├── postgis (base de données)
├── openobserve (observabilité)
├── rustfs (stockage objet)
├── pgadmin (admin BDD)
└── mdbook (documentation)
Architecture de déploiement (cible)
GitHub (tag vX.Y.Z)
│
▼ GitHub Actions (build + push image)
Container Registry
│
▼ deploy image
Coolify
├── prod → image :v1.2.0
├── preprod → image :v1.2.0-rc1
└── ...