Aller au contenu

sync.controle

File de contrôle unique : anomalies métier à examiner par un responsable. Modifiable jusqu’à sa levée.

Name Type Default Nullable Children Parents Comment
id uuid app.uuid_v7() false app.constat Identifiant du contrôle (UUID v7).
organisation_id uuid false app.utilisateur sync.commande app.producteur app.parcelle_version Organisation propriétaire de la ligne. Sert à l’isolation par RLS (EC-032) et au filtrage de la synchronisation.
commande_id uuid true sync.commande Commande à l’origine du contrôle.
motif text false Motif du contrôle, parmi le catalogue du protocole (§9). « module_inactif » (EC-096) : commande d’un module inactif, conservée sans écriture métier.
details jsonb ‘{}’::jsonb false Éléments de contexte, en JSON.
statut text ‘ouvert’::text false Statut : ouvert, en_cours ou leve.
decision text true Décision de levée. Renseignée si et seulement si le contrôle est levé.
motif_decision text true Motif de la décision.
decide_par uuid true app.utilisateur Utilisateur qui a levé le contrôle. Jamais l’auteur de la commande.
decide_le timestamp with time zone true Date de la levée.
cree_le timestamp with time zone now() false Date de création de la ligne.
modifie_le timestamp with time zone now() false Date de la dernière modification, tenue par un déclencheur.
producteur_id uuid true app.producteur Producteur concerné par le contrôle (de la même organisation), par exemple pour un doublon de pièce d’identité (AV1-02).
parcelle_version_id uuid true app.parcelle_version Version de polygone concernée par le contrôle (de la même organisation) : polygone invalide ou chevauchement.
Name Type Definition
controle_check CHECK CHECK (((statut = ‘leve’::text) = (decision IS NOT NULL)))
controle_check1 CHECK CHECK (((decision IS NULL) = ((decide_par IS NULL) AND (decide_le IS NULL) AND (motif_decision IS NULL))))
controle_decision_check CHECK CHECK ((decision = ANY (ARRAY[‘regularisation’::text, ‘declassement’::text, ‘non_conformite’::text, ‘fusion’::text, ‘correction’::text, ‘confirmation’::text, ‘ecart_manuel’::text, ‘reprise_manuelle’::text])))
controle_motif_check CHECK CHECK ((motif = ANY (ARRAY[‘capacite_depassee’::text, ‘doublon_identite’::text, ‘polygone_invalide’::text, ‘chevauchement_parcelle’::text, ‘modification_concurrente’::text, ‘ecart_calcul’::text, ‘apres_revocation’::text, ‘hors_ligne_depasse’::text, ‘droit_manquant’::text, ‘horloge_invraisemblable’::text, ‘reference_inconnue’::text, ‘reference_inactive’::text, ‘dependance_en_controle’::text, ‘donnees_illisibles’::text, ‘version_client_obsolete’::text, ‘empreinte_incoherente’::text, ‘piece_manquante’::text, ‘erreur_signalee_agent’::text, ‘intrant_non_autorise’::text, ‘conflit_interets’::text, ‘parametre_introuvable’::text, ‘module_inactif’::text])))
controle_statut_check CHECK CHECK ((statut = ANY (ARRAY[‘ouvert’::text, ‘en_cours’::text, ‘leve’::text])))
controle_organisation_id_decide_par_fkey FOREIGN KEY FOREIGN KEY (organisation_id, decide_par) REFERENCES app.utilisateur(organisation_id, id)
controle_organisation_id_commande_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, commande_id) REFERENCES sync.commande(organisation_id, id)
controle_pkey PRIMARY KEY PRIMARY KEY (id)
controle_organisation_id_producteur_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, producteur_id) REFERENCES app.producteur(organisation_id, id)
controle_organisation_id_parcelle_version_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, parcelle_version_id) REFERENCES app.parcelle_version(organisation_id, id)
Name Definition
controle_pkey CREATE UNIQUE INDEX controle_pkey ON sync.controle USING btree (id)
controle_ouvert_idx CREATE INDEX controle_ouvert_idx ON sync.controle USING btree (organisation_id, statut, cree_le) WHERE (statut <> ‘leve’::text)
controle_producteur_idx CREATE INDEX controle_producteur_idx ON sync.controle USING btree (organisation_id, producteur_id) WHERE (statut <> ‘leve’::text)
controle_parcelle_version_idx CREATE INDEX controle_parcelle_version_idx ON sync.controle USING btree (organisation_id, parcelle_version_id) WHERE (statut <> ‘leve’::text)
Name Definition
journal CREATE TRIGGER journal AFTER INSERT OR DELETE OR UPDATE ON sync.controle FOR EACH ROW EXECUTE FUNCTION journal.tg_journaliser()
modifie_le CREATE TRIGGER modifie_le BEFORE UPDATE ON sync.controle FOR EACH ROW EXECUTE FUNCTION app.tg_modifie_le()
controle_regles CREATE TRIGGER controle_regles BEFORE UPDATE ON sync.controle FOR EACH ROW EXECUTE FUNCTION sync.tg_controle_regles()
erDiagram

"app.constat" }o--o| "sync.controle" : "FOREIGN KEY (controle_id) REFERENCES sync.controle(id)"
"sync.controle" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, decide_par) REFERENCES app.utilisateur(organisation_id, id)"
"sync.controle" }o--|| "sync.commande" : "FOREIGN KEY (organisation_id, commande_id) REFERENCES sync.commande(organisation_id, id)"
"sync.controle" }o--|| "app.producteur" : "FOREIGN KEY (organisation_id, producteur_id) REFERENCES app.producteur(organisation_id, id)"
"sync.controle" }o--|| "app.parcelle_version" : "FOREIGN KEY (organisation_id, parcelle_version_id) REFERENCES app.parcelle_version(organisation_id, id)"

"sync.controle" {
  uuid id "Identifiant du contrôle (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  uuid commande_id FK "Commande à l'origine du contrôle."
  text motif "Motif du contrôle, parmi le catalogue du protocole (§9). « module_inactif » (EC-096) : commande d'un module inactif, conservée sans écriture métier."
  jsonb details "Éléments de contexte, en JSON."
  text statut "Statut : ouvert, en_cours ou leve."
  text decision "Décision de levée. Renseignée si et seulement si le contrôle est levé."
  text motif_decision "Motif de la décision."
  uuid decide_par FK "Utilisateur qui a levé le contrôle. Jamais l'auteur de la commande."
  timestamp_with_time_zone decide_le "Date de la levée."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de la dernière modification, tenue par un déclencheur."
  uuid producteur_id FK "Producteur concerné par le contrôle (de la même organisation), par exemple pour un doublon de pièce d'identité (AV1-02)."
  uuid parcelle_version_id FK "Version de polygone concernée par le contrôle (de la même organisation) : polygone invalide ou chevauchement."
}
"app.constat" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation concernée. Sert à l'isolation par RLS (EC-032)."
  uuid regle_decision_id FK "Ligne de décision évaluée."
  text regle_code "Code de la ligne, recopié pour la lecture (instantané, PC-08)."
  text version "Version du pack de la ligne, recopiée (instantané, PC-08)."
  text source "Source de la ligne, recopiée (instantané, PC-08)."
  text accroche "Point d'accroche de l'évaluation."
  text objet_type "Nature de l'objet concerné (reception, lot, collecte…)."
  uuid objet_id "Identifiant de l'objet concerné."
  text resultat "ecart (condition vraie) ou a_verifier (variable, paramètre ou date absents, erreur d'évaluation : jamais de valeur par défaut, PC-07)."
  text issue "Issue de la ligne pour un écart ; vide pour « à vérifier »."
  text motif "Raison d'un « à vérifier » ; vide pour un écart."
  jsonb valeurs "Valeurs lues par la ligne et paramètres utilisés, au moment de l'évaluation."
  bigint constatee "Valeur constatée, si la ligne déclare une mesure (entier, unité de la variable)."
  bigint attendue "Valeur attendue, si la ligne déclare une mesure."
  bigint ecart "Écart constatée − attendue, si la ligne déclare une mesure."
  uuid controle_id FK "Entrée de la file de contrôle liée, quand l'issue met une commande en contrôle (EC-091)."
  text statut "ouvert, justifie (note exigée), leve, clos (final)."
  text note "Justification écrite (RG-308), obligatoire pour « justifié »."
  uuid statut_par FK "Auteur du dernier changement de statut."
  timestamp_with_time_zone statut_le "Date du dernier changement de statut, posée par la base."
  uuid cree_par FK "Utilisateur à l'origine de l'évaluation ; vide pour une évaluation du serveur."
  timestamp_with_time_zone cree_le "Date du constat."
  timestamp_with_time_zone modifie_le "Date de la dernière modification, tenue par un déclencheur."
  text origine "Origine de la règle : pack (ligne d'une table de décision, regle_decision_id renseigné) ou processus (règle codée comme RG-014 ou RG-172, sans ligne de décision)."
}
"app.utilisateur" {
  uuid id "Identifiant de l'utilisateur (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  uuid keycloak_sub "Identifiant du compte Keycloak (revendication sub). Identique d'une organisation à l'autre pour un compte externe."
  text identifiant "Identifiant local de connexion, sans le code de l'organisation : 3 à 32 caractères parmi a-z, 0-9, _ et -. Unique dans l'organisation."
  text nom_affiche "Nom affiché dans l'application."
  text telephone "Numéro de téléphone. Attribut du compte, jamais son identifiant."
  text statut "Statut du compte : actif, suspendu ou desactive."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de la dernière modification, tenue par un déclencheur."
}
"sync.commande" {
  uuid id "Identifiant de la commande (UUID v7 généré sur l'appareil). Clé d'idempotence."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  uuid appareil_id FK "Appareil émetteur."
  uuid utilisateur_id FK "Agent auteur."
  bigint sequence "Séquence locale de l'appareil, à partir de 1. Unique par appareil."
  text type "Type de commande (ex. collecte.enregistrer)."
  integer version_schema "Version du JSON Schema de la charge utile."
  timestamp_with_time_zone cree_le_appareil "Heure du téléphone à la saisie."
  timestamp_with_time_zone date_operation "Date d'opération retenue par le serveur, jamais postérieure à la réception (protocole §6.4)."
  timestamp_with_time_zone recue_le "Heure de réception par le serveur."
  text reference_provisoire "Référence provisoire du document de terrain (EC-009)."
  text empreinte "Empreinte SHA-256 de la commande canonique."
  jsonb enveloppe "Commande complète en JSON, telle que reçue."
}
"app.producteur" {
  uuid id "Identifiant stable (UUID v7), clé d'échange avec le système de contrôle interne."
  uuid organisation_id FK "Organisation qui enrôle le producteur. Sert à l'isolation par RLS (EC-032)."
  uuid groupement_id FK "Groupement d'appartenance (de la même organisation). Le téléphone filtre sur ce groupement."
  text code "Code du producteur, unique par organisation et définitif (RG-010, EC-031)."
  text nom_complet "Nom complet du producteur."
  text telephone "Téléphone. Donnée personnelle : accès réservé aux rôles qui en ont l'usage (EX-063)."
  text village "Village."
  text canton "Canton."
  text zone_production "Zone de production."
  date date_inscription "Date d'inscription du producteur, transmise au système de contrôle interne."
  text type_piece_identite "Type de la pièce d'identité (carte nationale, passeport…). Vocabulaire non contrôlé pour l'instant. Renseigné avec le numéro, ou absent avec lui."
  text numero_piece_identite "Numéro de la pièce d'identité, tel que saisi. Le doublon ne bloque rien : il ouvre un contrôle (AV1-02)."
  text numero_piece_normalise "Numéro de pièce en majuscules, sans espace ni tiret, calculé. Sert à rapprocher deux saisies du même numéro."
  uuid photo_fichier_id FK "Photo du producteur (fichier de la même organisation)."
  uuid piece_fichier_id FK "Image de la pièce d'identité (fichier de la même organisation)."
  bigint chiffre_affaires_valeur "Chiffre d'affaires annuel, en unités mineures de sa devise (EC-028). Sert à l'éligibilité au groupe (EC-014)."
  text chiffre_affaires_devise "Devise ISO 4217 du chiffre d'affaires. Renseignée avec la valeur, ou absente avec elle."
  boolean actif "Faux quand le producteur est retiré des listes de saisie sans altérer l'historique (RG-011). Toujours faux pour une fiche fusionnée."
  text statut "`actif` ou `fusionnee`. Une fiche fusionnée renvoie à la fiche retenue et ne se réactive pas."
  uuid fusionnee_dans_id FK "Fiche retenue quand celle-ci a été absorbée par une fusion. Renseignée si et seulement si le statut est `fusionnee`."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de dernière modification."
}
"app.parcelle_version" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
  uuid groupement_id FK "Groupement de la cible, repris d'elle quand il n'est pas donné. Le téléphone filtre dessus."
  uuid parcelle_id FK "Parcelle cible. Exactement une cible entre parcelle et zone de cueillette."
  uuid zone_cueillette_id FK "Zone de cueillette cible. Exactement une cible entre parcelle et zone de cueillette."
  integer version "Numéro de version de la cible, à partir de 1, attribué par la base quand il n'est pas donné. La plus élevée est la version en vigueur."
  geometry_Polygon_4326_ geom "Polygone en WGS 84 (SRID 4326). Peut être invalide : il est alors signalé, jamais réparé."
  jsonb geojson "Le même polygone en GeoJSON, tenu par la base : c'est ce que le téléphone reçoit."
  boolean valide "Résultat de ST_IsValid sur le polygone, calculé par la base."
  text motif_invalidite "Raison donnée par ST_IsValidReason quand le polygone est invalide, sinon vide."
  bigint surface_mesuree_m2 "Surface mesurée en m² (ST_Area en géographie, arrondie). Vide si le polygone est invalide. Base de toute capacité (AV1-01)."
  bigint perimetre_m "Périmètre en mètres (ST_Perimeter en géographie, arrondi). Vide si le polygone est invalide."
  text methode "Méthode de relevé (GPS-03) : `sommets`, `marche`, `dessin` ou `import` (EC-048)."
  integer precision_mediane_cm "Précision médiane déclarée du relevé, en centimètres (GPS-03). Pour un import, la précision lue dans le fichier."
  text appareil "Appareil ou récepteur utilisé pour le relevé (GPS-03), en texte libre."
  uuid trace_fichier_id FK "Trace brute du relevé (fichier de la même organisation), conservée pour l'audit (GPS-03)."
  bigint incertitude_m2 "Incertitude de la surface mesurée (GPS-04) : périmètre × précision médiane, calculée. Un écart avec la surface déclarée plus petit n'est pas une anomalie."
  uuid cree_par FK "Utilisateur qui a importé ou relevé la version."
  timestamp_with_time_zone cree_le "Date de création de la version : début de sa période de vigueur."
}

Generated by tbls