Aller au contenu

Lot 1, séquence A5 — Foncier

1er octobre 2026. Mise en œuvre de la séquence A5 du plan du Lot 1. Décisions : EC-048, EC-049 (amendé), EC-050, EC-069 (appliqué de la même façon).

  • Un polygone invalide est conservé, signalé et jamais réparé : pas de ST_MakeValid. Il n’a ni surface ni périmètre ; sa correction est un nouveau relevé.
  • La surface mesurée vient de la base (ST_Area en géographie). Le domaine la recalcule pour comparaison : elle concorde à 0,1 %.
  • La tolérance de chevauchement n’est dans aucune table : c’est un paramètre de app.signaler_chevauchements(version, tolerance_m2). Sa valeur par défaut, 50 m², est arbitraire et destinée à devenir paramétrable (EC-049).
  • Aucune route REST en A5 : le contrat est gelé en A9, les écrans B3 demanderont leurs routes.
Objet Contenu
app.parcelle organisation_id et groupement_id, producteur, produit, code unique, type_surface (cultures, serres, prairies), surface déclarée, facteurs region, mode_culture, type_sol facultatifs
app.zone_cueillette Même mécanisme de polygone (EC-050)
app.parcelle_version Ajout seul. Une cible exactement (parcelle ou zone), numéro de version, geom Polygon 4326, geojson tenu par la base, valide, motif_invalidite, surface et périmètre (vides si invalide), méthode (dont import), précision médiane, appareil, trace brute, incertitude_m2 calculée
app.parcelle_version_en_vigueur Vue de la version la plus récente de chaque cible. security_invoker : elle applique la RLS de l’appelant
sync.controle Nouvelle colonne parcelle_version_id

Un producteur qui a des parcelles ne change pas de groupement : la parcelle porte groupement_id pour le téléphone, et la clé composée vers le producteur refuse le changement.

  • Validité : un déclencheur calcule ST_IsValid et sa raison, mesure si valide, remplit le GeoJSON, attribue le numéro de version et reprend le groupement de la cible (cible inconnue : erreur P0002 explicite). Un second déclencheur ouvre le contrôle polygone_invalide.
  • app.parcelle_version_a(parcelle, zone, date) : la version applicable à une date passée.
  • app.signaler_chevauchements(version, tolérance) : compare à la version en vigueur des autres cibles de même nature (parcelles entre elles, zones entre elles), ignore les polygones invalides, mesure l’aire de l’intersection, ouvre un contrôle chevauchement_parcelle au-delà de la tolérance. Un bord partagé ne compte pas. Idempotente : un seul contrôle ouvert par version.
  • app.parcelle_eligible_capacite(parcelle, zone) : vrai si la version en vigueur est valide et sans chevauchement non levé (AV1-01). Le producteur en contrôle se juge à part (producteur_en_controle, A4). La capacité (A8) appelle les deux ; A5 ne bloque rien elle-même.
  • importerPolygone (apps/api/src/foncier/polygones.service.ts) : valide la forme (GeoJSON Polygon, un anneau fermé), insère la version, appelle signaler_chevauchements avec la tolérance reçue ou celle de PARAMETRES_FONCIER, rend validité, surface, incertitude et contrôles ouverts. Sur une erreur de cible, la transaction est à annuler.
  • evaluerEcartDeLaParcelle : écart entre surface déclarée et mesurée, jugé par evaluerEcartSurface contre l’incertitude périmètre × précision (GPS-04). Un écart dans la marge n’est pas une anomalie.
  • evaluerEligibiliteDuGroupement (A4) lit maintenant les surfaces mesurées : un producteur dont une parcelle n’a pas de polygone valide, ou qui n’en a aucune, a un critère « surface » inconnu. On ne conclut pas sur des surfaces incomplètes.

Défaut du jeu de démonstration, trouvé au chargement

Section intitulée « Défaut du jeu de démonstration, trouvé au chargement »

Le générateur plaçait les 9 premières parcelles au même endroit (rayon nul pour l’anneau 0) : au chargement réel en base, 9 chevauchements s’ouvraient au lieu de 1. Corrigé dans generer.mjs (anneaux de 1/10 à 10/10 du rayon). Le jeu produit maintenant 1 polygone invalide et 1 chevauchement, et le chargement ne signale que les versions réellement insérées : le rejeu ne rouvre rien. Le commentaire « ~2 m de décalage » de la paire volontaire était aussi faux : 2 000 × 10⁻⁷ degré font environ 22 m.

Test Ce qu’il vérifie
db/tests/l1-a5.sql Parcelles et clés, version valide et sa surface, ajout seul, une cible exactement, nœud papillon accepté mais invalide et sans surface, aucune réparation, correction par nouvelle version, lecture à une date passée, chevauchement au-dessus et en dessous de la tolérance, bord partagé, tolérance en paramètre, zones, cible inconnue, isolation
apps/api/test/foncier.test.ts Surface PostGIS contre surfaceM2 à 0,1 % sur 5 polygones du jeu de démonstration, nœud papillon du jeu, correction, anneau non fermé, écart dans et hors incertitude, chevauchement avec deux tolérances, éligibilité sur surfaces mesurées, aucun appel à ST_MakeValid dans la migration
packages/schemas/src/foncier.test.ts Forme du GeoJSON et de la parcelle

Routes REST du foncier et import GeoJSON du back-office (écrans B3) ; valeurs de region d’un pack ; capacité (A8) ; règles PowerSync des nouvelles tables (A9) ; trous dans un polygone (un seul anneau au Lot 1).