Aller au contenu

app.certificat_portee

Portée d’un certificat (AM-07) : ce que l’organisme certifie, une ligne par activité, produit, site ou unité, incluse ou exclue. En ajout seul. Un certificat sans aucune ligne a une portée non renseignée : aucun écart n’est alors calculé. L’écart de portée est jugé par le domaine, pas par la base.

Name Type Default Nullable Children Parents Comment
id uuid app.uuid_v7() false Identifiant stable (UUID v7).
organisation_id uuid false app.organisation app.utilisateur app.site app.produit app.producteur app.parcelle app.zone_cueillette app.certificat Organisation propriétaire. Sert à l’isolation par RLS (EC-032).
certificat_id uuid false app.certificat Certificat dont la ligne précise la portée (de la même organisation).
dimension text false activite, produit, site ou unite. Détermine la seule colonne d’élément renseignée.
activite_code text true app.activite Activité du catalogue fermé (dimension activite).
produit_id uuid true app.produit Produit du catalogue de l’organisation (dimension produit). Les produits sont listés un à un : le catalogue n’a pas de catégorie (EC-102).
site_id uuid true app.site Site de l’organisation (dimension site).
producteur_id uuid true app.producteur Unité producteur (dimension unite). Exactement une unité entre producteur, parcelle et zone de cueillette.
parcelle_id uuid true app.parcelle Unité parcelle (dimension unite).
zone_cueillette_id uuid true app.zone_cueillette Unité zone de cueillette (dimension unite).
inclus boolean false Vrai : l’élément est couvert par le certificat. Faux : il est exclu expressément, et l’exclusion l’emporte sur une inclusion plus large.
cree_par uuid false app.utilisateur Utilisateur qui a déclaré la ligne.
cree_le timestamp with time zone clock_timestamp() false Date de création de la ligne.
Name Type Definition
certificat_portee_check CHECK CHECK ((((dimension = ‘activite’::text) AND (activite_code IS NOT NULL) AND (num_nonnulls(produit_id, site_id, producteur_id, parcelle_id, zone_cueillette_id) = 0)) OR ((dimension = ‘produit’::text) AND (produit_id IS NOT NULL) AND (num_nonnulls(activite_code, site_id, producteur_id, parcelle_id, zone_cueillette_id) = 0)) OR ((dimension = ‘site’::text) AND (site_id IS NOT NULL) AND (num_nonnulls(activite_code, produit_id, producteur_id, parcelle_id, zone_cueillette_id) = 0)) OR ((dimension = ‘unite’::text) AND (num_nonnulls(producteur_id, parcelle_id, zone_cueillette_id) = 1) AND (num_nonnulls(activite_code, produit_id, site_id) = 0))))
certificat_portee_dimension_check CHECK CHECK ((dimension = ANY (ARRAY[‘activite’::text, ‘produit’::text, ‘site’::text, ‘unite’::text])))
certificat_portee_organisation_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)
certificat_portee_organisation_id_cree_par_fkey FOREIGN KEY FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)
certificat_portee_organisation_id_site_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, site_id) REFERENCES app.site(organisation_id, id)
certificat_portee_organisation_id_produit_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, produit_id) REFERENCES app.produit(organisation_id, id)
certificat_portee_organisation_id_producteur_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, producteur_id) REFERENCES app.producteur(organisation_id, id)
certificat_portee_organisation_id_parcelle_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, parcelle_id) REFERENCES app.parcelle(organisation_id, id)
certificat_portee_organisation_id_zone_cueillette_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, zone_cueillette_id) REFERENCES app.zone_cueillette(organisation_id, id)
certificat_portee_organisation_id_certificat_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, certificat_id) REFERENCES app.certificat(organisation_id, id)
certificat_portee_activite_code_fkey FOREIGN KEY FOREIGN KEY (activite_code) REFERENCES app.activite(code)
certificat_portee_pkey PRIMARY KEY PRIMARY KEY (id)
certificat_portee_organisation_id_id_key UNIQUE UNIQUE (organisation_id, id)
Name Definition
certificat_portee_pkey CREATE UNIQUE INDEX certificat_portee_pkey ON app.certificat_portee USING btree (id)
certificat_portee_organisation_id_id_key CREATE UNIQUE INDEX certificat_portee_organisation_id_id_key ON app.certificat_portee USING btree (organisation_id, id)
certificat_portee_element_idx CREATE UNIQUE INDEX certificat_portee_element_idx ON app.certificat_portee USING btree (organisation_id, certificat_id, dimension, COALESCE(activite_code, (produit_id)::text, (site_id)::text, (producteur_id)::text, (parcelle_id)::text, (zone_cueillette_id)::text))
Name Definition
journal CREATE TRIGGER journal AFTER INSERT OR DELETE OR UPDATE ON app.certificat_portee FOR EACH ROW EXECUTE FUNCTION journal.tg_journaliser()
ajout_seul CREATE TRIGGER ajout_seul BEFORE DELETE OR UPDATE ON app.certificat_portee FOR EACH ROW EXECUTE FUNCTION app.tg_ajout_seul()
erDiagram

"app.certificat_portee" }o--|| "app.organisation" : "FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)"
"app.certificat_portee" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)"
"app.certificat_portee" }o--|| "app.site" : "FOREIGN KEY (organisation_id, site_id) REFERENCES app.site(organisation_id, id)"
"app.certificat_portee" }o--|| "app.produit" : "FOREIGN KEY (organisation_id, produit_id) REFERENCES app.produit(organisation_id, id)"
"app.certificat_portee" }o--|| "app.producteur" : "FOREIGN KEY (organisation_id, producteur_id) REFERENCES app.producteur(organisation_id, id)"
"app.certificat_portee" }o--|| "app.parcelle" : "FOREIGN KEY (organisation_id, parcelle_id) REFERENCES app.parcelle(organisation_id, id)"
"app.certificat_portee" }o--|| "app.zone_cueillette" : "FOREIGN KEY (organisation_id, zone_cueillette_id) REFERENCES app.zone_cueillette(organisation_id, id)"
"app.certificat_portee" }o--|| "app.certificat" : "FOREIGN KEY (organisation_id, certificat_id) REFERENCES app.certificat(organisation_id, id)"
"app.certificat_portee" }o--o| "app.activite" : "FOREIGN KEY (activite_code) REFERENCES app.activite(code)"

"app.certificat_portee" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
  uuid certificat_id FK "Certificat dont la ligne précise la portée (de la même organisation)."
  text dimension "`activite`, `produit`, `site` ou `unite`. Détermine la seule colonne d'élément renseignée."
  text activite_code FK "Activité du catalogue fermé (dimension `activite`)."
  uuid produit_id FK "Produit du catalogue de l'organisation (dimension `produit`). Les produits sont listés un à un : le catalogue n'a pas de catégorie (EC-102)."
  uuid site_id FK "Site de l'organisation (dimension `site`)."
  uuid producteur_id FK "Unité producteur (dimension `unite`). Exactement une unité entre producteur, parcelle et zone de cueillette."
  uuid parcelle_id FK "Unité parcelle (dimension `unite`)."
  uuid zone_cueillette_id FK "Unité zone de cueillette (dimension `unite`)."
  boolean inclus "Vrai : l'élément est couvert par le certificat. Faux : il est exclu expressément, et l'exclusion l'emporte sur une inclusion plus large."
  uuid cree_par FK "Utilisateur qui a déclaré la ligne."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
}
"app.organisation" {
  uuid id "Identifiant de l'organisation (UUID v7)."
  text code "Code court en majuscules. Immuable : il figure dans les identifiants Keycloak (coopa.agent01). « EXT » est réservé."
  text nom "Nom de l'organisation."
  text pays "Pays, code ISO 3166-1 alpha-2."
  text langue "Langue de l'organisation : fr ou en."
  text fuseau_horaire "Fuseau horaire IANA utilisé pour l'affichage des dates."
  text devise_defaut "Devise par défaut des montants, code ISO 4217."
  text keycloak_organisation_id "Identifiant de l'organisation dans Keycloak."
  text organisme_certificateur "Organisme de certification de l'organisation. Aucun contrôle de format (EC-027)."
  text code_operateur "Code d'opérateur attribué par l'organisme certificateur."
  uuid logo_fichier_id FK "Fichier du logo (EC-029)."
  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."
  text source_conformite "Source des décisions de conformité : `interne` (contrôle interne de BioTrace) ou `externe` (outil tiers). Une seule source active à la fois ; app.statut_conformite.source doit lui être égale."
  text statut "État du compte client : `active` ou `suspendue`. Une organisation suspendue est refusée par la garde d'authentification (`organisation_suspendue`) ; ses données et ses comptes sont conservés. Décidé par l'équipe de l'éditeur (EC-126)."
  timestamp_with_time_zone suspendue_le "Date de la suspension en cours ; nulle tant que l'organisation est active."
}
"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."
}
"app.site" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
  text code "Code du site, unique par organisation."
  text nom "Nom du site."
  boolean actif "Faux quand le site n'est plus utilisé. Un site n'est jamais supprimé."
  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.produit" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
  text code "Code du produit, inséré dans le numéro officiel (segment « produit »). Unique par organisation (EC-063)."
  text nom_fr "Nom en français."
  text nom_en "Nom en anglais."
  text unite_code FK "Unité de saisie et d'affichage."
  boolean est_matiere_premiere "Vrai pour une matière première, faux pour un produit fini."
  uuid matiere_premiere_liee_id FK "Matière première dont le produit fini est issu. Réservé aux produits finis, de la même organisation."
  text code_modele "Code du modèle de produit du pack qui a servi à créer la ligne. Nul pour un produit créé à la main."
  uuid pack_version_id FK "Version de pack d'origine. Nulle pour un produit créé à la main ; nulle exactement quand code_modele l'est."
  boolean actif "Faux quand le produit n'est plus utilisé. Un produit n'est jamais supprimé."
  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.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" {
  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 parcelle, identique à celui de son producteur (clé composée) : un producteur qui a des parcelles ne change pas de groupement."
  uuid producteur_id FK "Producteur propriétaire de la parcelle (de la même organisation)."
  uuid produit_id FK "Produit cultivé (de la même organisation)."
  text code "Code de la parcelle, unique par organisation."
  text type_surface "`cultures`, `serres` ou `prairies` : sert aux seuils d'éligibilité au groupe (RG-024)."
  bigint surface_declaree_m2 "Surface déclarée par le producteur, en m² (EC-030). Jamais la base d'une capacité : c'est la surface mesurée (AV1-01)."
  text region_facteur FK "Constante `region` : nom du facteur de la clé étrangère composée vers facteur_valeur."
  text region FK "Région (valeur du facteur `region`), facultative."
  text mode_culture_facteur FK "Constante `mode_culture` : nom du facteur de la clé étrangère composée vers facteur_valeur."
  text mode_culture FK "Mode de culture (`pluvial` ou `irrigue`), facultatif."
  text type_sol_facteur FK "Constante `type_sol` : nom du facteur de la clé étrangère composée vers facteur_valeur."
  text type_sol FK "Type de sol (valeur du facteur `type_sol`), facultatif."
  boolean actif "Faux quand la parcelle n'est plus utilisée. Une parcelle n'est jamais supprimée."
  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.zone_cueillette" {
  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 qui exploite la zone (de la même organisation)."
  uuid produit_id FK "Produit cueilli (de la même organisation)."
  text code "Code de la zone, unique par organisation."
  text nom "Nom de la zone."
  boolean actif "Faux quand la zone n'est plus utilisée. Une zone n'est jamais supprimée."
  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.certificat" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation qui enregistre le certificat. Sert à l'isolation par RLS (EC-032)."
  uuid referentiel_id FK "Référentiel coché par l'organisation (app.organisation_referentiel) que le certificat atteste (EC-101)."
  uuid operateur_id FK "Titulaire opérateur : l'organisation elle-même. Exactement un titulaire entre opérateur, groupement et fournisseur (EC-025)."
  uuid groupement_id FK "Titulaire groupement (de la même organisation). Un certificat de groupe couvre ses membres."
  uuid fournisseur_id FK "Titulaire fournisseur (de la même organisation). Un fournisseur ne se crée pas sans son certificat (EC-053)."
  text organisme_nom "Nom de l'organisme certificateur."
  text organisme_code "Code de l'organisme certificateur, sans contrôle de format (EC-027)."
  text numero "Numéro du certificat, sans contrôle de format."
  date date_debut "Premier jour de validité, inclus."
  date date_fin "Dernier jour de validité, inclus. Jamais avant date_debut. L'expiration se calcule depuis cette date."
  text statut "`valide`, `suspendu` ou `retire`. Pas de valeur « expiré » : il se calcule. La date d'une suspension ou d'un retrait n'est pas stockée (EC-072) ; le journal d'audit en garde la trace."
  uuid fichier_id FK "PDF du certificat (fichier de la même organisation). Obligatoire pour un fournisseur (EC-053)."
  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.activite" {
  uuid id "Identifiant stable (UUID v7)."
  text code "Code stable du type, cité par les packs, les grilles et les modules."
  smallint niveau "Niveau dans l'arbre : 1 activité, 2 sous-activité, 3 étape. Trois niveaux au plus."
  text parent_code FK "Type parent indicatif du catalogue (affichage) ; non vérifié contre l'arbre réel d'une organisation (app.noeud_activite), où seul le niveau du type doit correspondre à la profondeur du chemin."
  text regroupement "Regroupement affiché à l'écran : les cinq activités élémentaires du cahier v1.2, §2.2."
  text libelle_fr "Libellé en français."
  text libelle_en "Libellé en anglais."
  smallint ordre "Ordre d'affichage parmi les types du même parent."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de dernière modification (par migration seulement)."
  boolean provisoire "Vrai pour un type de niveau 2 ou 3 posé avant la validation du catalogue avec l'organisme de certification (Q1, EC-108). Le code reste stable ; le libellé et le rangement peuvent changer."
}

Generated by tbls