Aller au contenu

app.capacite_version

Capacité d’une parcelle ou d’une zone pour une campagne : surface mesurée × rendement. En ajout seul, une version par modification. Ne s’applique qu’une fois validée par la direction et le RSCI (EC-012).

Name Type Default Nullable Extra Definition Children Parents Comment
id uuid app.uuid_v7() false app.validation app.solde_capacite Identifiant stable (UUID v7).
organisation_id uuid false app.validation app.solde_capacite app.organisation app.utilisateur app.campagne app.parcelle app.zone_cueillette app.parcelle_version Organisation propriétaire. Sert à l’isolation par RLS (EC-032).
groupement_id uuid false app.parcelle app.zone_cueillette Groupement de la cible, repris d’elle par la base. Le téléphone filtre dessus.
parcelle_id uuid true app.parcelle Parcelle cible. Exactement une cible entre parcelle et zone de cueillette.
zone_cueillette_id uuid true app.zone_cueillette Zone de cueillette cible (EC-050).
campagne_id uuid false app.campagne Campagne de la capacité. Deux campagnes la même année portent chacune la leur.
version integer false Numéro de version pour la cible et la campagne, attribué par la base.
parcelle_version_id uuid false app.parcelle_version Version de polygone sur laquelle la capacité est calculée, posée par la base. Si le polygone change, la capacité n’est plus applicable (EC-012).
surface_mesuree_m2 bigint false Surface mesurée de cette version de polygone, en m², posée par la base. La surface déclarée n’entre jamais dans le calcul (AV1-01).
rendement_g_ha bigint false Rendement de référence en vigueur lors de la saisie, en g/ha, posé par la base.
capacite_g bigint true GENERATED ALWAYS AS (((surface_mesuree_m2 * rendement_g_ha) + 5000) / 10000) STORED Capacité en grammes, calculée : surface mesurée × rendement / 10 000, arrondie au plus proche (RG-020). Seule formule du projet pour la capacité.
cree_par uuid false app.utilisateur Auteur de la proposition : il ne peut pas la valider (SB-11).
cree_le timestamp with time zone now() false Date de création de la version.
Name Type Definition
capacite_version_check CHECK CHECK (((parcelle_id IS NULL) <> (zone_cueillette_id IS NULL)))
capacite_version_rendement_g_ha_check CHECK CHECK ((rendement_g_ha > 0))
capacite_version_surface_mesuree_m2_check CHECK CHECK ((surface_mesuree_m2 > 0))
capacite_version_version_check CHECK CHECK ((version > 0))
capacite_version_organisation_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)
capacite_version_organisation_id_cree_par_fkey FOREIGN KEY FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)
capacite_version_organisation_id_campagne_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, campagne_id) REFERENCES app.campagne(organisation_id, id)
capacite_version_organisation_id_groupement_id_parcelle_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, groupement_id, parcelle_id) REFERENCES app.parcelle(organisation_id, groupement_id, id)
capacite_version_organisation_id_groupement_id_zone_cueill_fkey FOREIGN KEY FOREIGN KEY (organisation_id, groupement_id, zone_cueillette_id) REFERENCES app.zone_cueillette(organisation_id, groupement_id, id)
capacite_version_organisation_id_parcelle_version_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, parcelle_version_id) REFERENCES app.parcelle_version(organisation_id, id)
capacite_version_pkey PRIMARY KEY PRIMARY KEY (id)
capacite_version_organisation_id_id_key UNIQUE UNIQUE (organisation_id, id)
capacite_version_parcelle_id_campagne_id_version_key UNIQUE UNIQUE (parcelle_id, campagne_id, version)
capacite_version_zone_cueillette_id_campagne_id_version_key UNIQUE UNIQUE (zone_cueillette_id, campagne_id, version)
Name Definition
capacite_version_pkey CREATE UNIQUE INDEX capacite_version_pkey ON app.capacite_version USING btree (id)
capacite_version_organisation_id_id_key CREATE UNIQUE INDEX capacite_version_organisation_id_id_key ON app.capacite_version USING btree (organisation_id, id)
capacite_version_parcelle_id_campagne_id_version_key CREATE UNIQUE INDEX capacite_version_parcelle_id_campagne_id_version_key ON app.capacite_version USING btree (parcelle_id, campagne_id, version)
capacite_version_zone_cueillette_id_campagne_id_version_key CREATE UNIQUE INDEX capacite_version_zone_cueillette_id_campagne_id_version_key ON app.capacite_version USING btree (zone_cueillette_id, campagne_id, version)
Name Definition
journal CREATE TRIGGER journal AFTER INSERT OR DELETE OR UPDATE ON app.capacite_version FOR EACH ROW EXECUTE FUNCTION journal.tg_journaliser()
ajout_seul CREATE TRIGGER ajout_seul BEFORE DELETE OR UPDATE ON app.capacite_version FOR EACH ROW EXECUTE FUNCTION app.tg_ajout_seul()
garde CREATE TRIGGER garde BEFORE INSERT ON app.capacite_version FOR EACH ROW EXECUTE FUNCTION app.tg_capacite_version_garde()
erDiagram

"app.validation" }o--|| "app.capacite_version" : "FOREIGN KEY (organisation_id, capacite_version_id) REFERENCES app.capacite_version(organisation_id, id)"
"app.solde_capacite" }o--|| "app.capacite_version" : "FOREIGN KEY (organisation_id, capacite_version_id) REFERENCES app.capacite_version(organisation_id, id)"
"app.capacite_version" }o--|| "app.organisation" : "FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)"
"app.capacite_version" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)"
"app.capacite_version" }o--|| "app.campagne" : "FOREIGN KEY (organisation_id, campagne_id) REFERENCES app.campagne(organisation_id, id)"
"app.capacite_version" }o--|| "app.parcelle" : "FOREIGN KEY (organisation_id, groupement_id, parcelle_id) REFERENCES app.parcelle(organisation_id, groupement_id, id)"
"app.capacite_version" }o--|| "app.zone_cueillette" : "FOREIGN KEY (organisation_id, groupement_id, zone_cueillette_id) REFERENCES app.zone_cueillette(organisation_id, groupement_id, id)"
"app.capacite_version" }o--|| "app.parcelle_version" : "FOREIGN KEY (organisation_id, parcelle_version_id) REFERENCES app.parcelle_version(organisation_id, id)"

"app.capacite_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 par la base. 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 (EC-050)."
  uuid campagne_id FK "Campagne de la capacité. Deux campagnes la même année portent chacune la leur."
  integer version "Numéro de version pour la cible et la campagne, attribué par la base."
  uuid parcelle_version_id FK "Version de polygone sur laquelle la capacité est calculée, posée par la base. Si le polygone change, la capacité n'est plus applicable (EC-012)."
  bigint surface_mesuree_m2 "Surface mesurée de cette version de polygone, en m², posée par la base. La surface déclarée n'entre jamais dans le calcul (AV1-01)."
  bigint rendement_g_ha "Rendement de référence en vigueur lors de la saisie, en g/ha, posé par la base."
  bigint capacite_g "Capacité en grammes, calculée : surface mesurée × rendement / 10 000, arrondie au plus proche (RG-020). Seule formule du projet pour la capacité."
  uuid cree_par FK "Auteur de la proposition : il ne peut pas la valider (SB-11)."
  timestamp_with_time_zone cree_le "Date de création de la version."
}
"app.validation" {
  uuid id "Identifiant de la validation (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."
  text role_validation "Rôle sous lequel la validation est donnée."
  uuid validateur_id FK "Utilisateur qui valide. Différent de l'auteur de l'objet."
  uuid auteur_objet_id FK "Auteur de l'objet validé, renseigné par le déclencheur du lot, jamais par l'API."
  text decision "Décision : approuve ou refuse."
  text commentaire "Commentaire, obligatoire en cas de refus."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  uuid capacite_version_id FK "Capacité validée par cette ligne (de la même organisation). Une cible au plus ; une capacité se valide une fois par rôle, `direction` et `rsci`, par deux personnes différentes."
}
"app.solde_capacite" {
  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. Le téléphone filtre dessus."
  uuid parcelle_id FK "Parcelle du solde. Exactement une cible entre parcelle et zone de cueillette."
  uuid zone_cueillette_id FK "Zone de cueillette du solde."
  uuid campagne_id FK "Campagne du solde."
  uuid capacite_version_id FK "Version de capacité validée qui fonde le solde."
  bigint capacite_g "Capacité validée, en grammes."
  bigint consomme_g "Quantité déjà collectée, en grammes. Jamais écrasée par une nouvelle capacité."
  bigint reste_g "Capacité moins consommé, en grammes. Négatif en cas de dépassement : un dépassement n'est jamais masqué (RG-022)."
  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.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.campagne" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
  text code "Code de campagne inséré dans le numéro officiel. Unique par organisation, toutes années confondues (EC-031)."
  text nom "Nom de la campagne."
  date date_ouverture_prevue "Date d'ouverture prévue. Détermine « AA » tant que la campagne est en préparation."
  date date_cloture_prevue "Date de clôture prévue. Jamais avant la date d'ouverture prévue."
  date date_ouverture "Date d'ouverture réelle, renseignée à l'ouverture puis figée."
  date date_cloture "Date de clôture réelle, renseignée à la clôture."
  smallint annee "Année d'ouverture (réelle, sinon prévue), calculée. Ses deux derniers chiffres forment « AA » du numéro (EC-023)."
  uuid pack_version_id FK "Version du pack de la filière. Figée à l'ouverture, qui exige une version publiée."
  integer modele_numerotation_version FK "Version du modèle de numérotation de l'organisation. Obligatoire et figée à l'ouverture ; la clé vers le modèle est posée à la séquence A3."
  text statut "`preparation`, `ouverte` ou `cloturee`. Pas de retour en préparation."
  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.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