Étape réalisée d’un ordre de transformation : statut, mesures, auteur (AM-12). Chaque mouvement de l’étape la référence. Validée, elle ne change plus.
| Name |
Type |
Default |
Nullable |
Children |
Parents |
Comment |
| id |
uuid |
app.uuid_v7() |
false |
app.mouvement app.sortie_etape |
|
Identifiant stable (UUID v7). |
| organisation_id |
uuid |
|
false |
app.mouvement app.sortie_etape |
app.organisation app.utilisateur app.noeud_activite app.ordre_transformation |
Organisation propriétaire (isolation par ligne). |
| ordre_id |
uuid |
|
false |
|
app.ordre_transformation |
Ordre de transformation concerné. |
| noeud_etape_id |
uuid |
|
true |
|
app.noeud_activite |
Étape du procédé (nœud enfant du procédé). Vide pour la saisie qui couvre tout le procédé en suivi global. |
| statut |
text |
‘a_faire’::text |
false |
|
|
a_faire, en_cours, realisee ou validee ; une seule marche à la fois. |
| mesures |
jsonb |
‘{}’::jsonb |
false |
|
|
Mesures saisies à l’étape (objet JSON) ; modifiables tant que l’étape n’est pas validée. |
| debut_le |
timestamp with time zone |
|
true |
|
|
Début de l’étape. |
| fin_le |
timestamp with time zone |
|
true |
|
|
Fin de l’étape ; jamais avant le début. |
| cree_par |
uuid |
|
false |
|
app.utilisateur |
Utilisateur qui a ouvert l’étape. |
| valide_par |
uuid |
|
true |
|
app.utilisateur |
Utilisateur qui a validé l’étape ; renseigné si et seulement si elle est validée. |
| valide_le |
timestamp with time zone |
|
true |
|
|
Date de validation de l’étape. |
| 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 dernière modification. |
| Name |
Type |
Definition |
| etape_realisee_check |
CHECK |
CHECK (((statut = ‘validee’::text) = ((valide_par IS NOT NULL) AND (valide_le IS NOT NULL)))) |
| etape_realisee_check1 |
CHECK |
CHECK (((fin_le IS NULL) OR (debut_le IS NULL) OR (fin_le >= debut_le))) |
| etape_realisee_mesures_check |
CHECK |
CHECK ((jsonb_typeof(mesures) = ‘object’::text)) |
| etape_realisee_statut_check |
CHECK |
CHECK ((statut = ANY (ARRAY[‘a_faire’::text, ‘en_cours’::text, ‘realisee’::text, ‘validee’::text]))) |
| etape_realisee_organisation_id_fkey |
FOREIGN KEY |
FOREIGN KEY (organisation_id) REFERENCES app.organisation(id) |
| etape_realisee_organisation_id_cree_par_fkey |
FOREIGN KEY |
FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id) |
| etape_realisee_organisation_id_valide_par_fkey |
FOREIGN KEY |
FOREIGN KEY (organisation_id, valide_par) REFERENCES app.utilisateur(organisation_id, id) |
| etape_realisee_organisation_id_noeud_etape_id_fkey |
FOREIGN KEY |
FOREIGN KEY (organisation_id, noeud_etape_id) REFERENCES app.noeud_activite(organisation_id, id) |
| etape_realisee_organisation_id_ordre_id_fkey |
FOREIGN KEY |
FOREIGN KEY (organisation_id, ordre_id) REFERENCES app.ordre_transformation(organisation_id, id) |
| etape_realisee_pkey |
PRIMARY KEY |
PRIMARY KEY (id) |
| etape_realisee_organisation_id_id_key |
UNIQUE |
UNIQUE (organisation_id, id) |
| Name |
Definition |
| etape_realisee_pkey |
CREATE UNIQUE INDEX etape_realisee_pkey ON app.etape_realisee USING btree (id) |
| etape_realisee_organisation_id_id_key |
CREATE UNIQUE INDEX etape_realisee_organisation_id_id_key ON app.etape_realisee USING btree (organisation_id, id) |
| etape_realisee_une_par_etape |
CREATE UNIQUE INDEX etape_realisee_une_par_etape ON app.etape_realisee USING btree (ordre_id, COALESCE(noeud_etape_id, ‘00000000-0000-0000-0000-000000000000’::uuid)) |
| Name |
Definition |
| journal |
CREATE TRIGGER journal AFTER INSERT OR DELETE OR UPDATE ON app.etape_realisee FOR EACH ROW EXECUTE FUNCTION journal.tg_journaliser() |
| modifie_le |
CREATE TRIGGER modifie_le BEFORE UPDATE ON app.etape_realisee FOR EACH ROW EXECUTE FUNCTION app.tg_modifie_le() |
| etape_realisee_controle |
CREATE TRIGGER etape_realisee_controle BEFORE INSERT OR UPDATE ON app.etape_realisee FOR EACH ROW EXECUTE FUNCTION app.tg_etape_realisee_controle() |
erDiagram
"app.mouvement" }o--|| "app.etape_realisee" : "FOREIGN KEY (organisation_id, etape_realisee_id) REFERENCES app.etape_realisee(organisation_id, id)"
"app.sortie_etape" }o--|| "app.etape_realisee" : "FOREIGN KEY (organisation_id, etape_realisee_id) REFERENCES app.etape_realisee(organisation_id, id)"
"app.etape_realisee" }o--|| "app.organisation" : "FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)"
"app.etape_realisee" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)"
"app.etape_realisee" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, valide_par) REFERENCES app.utilisateur(organisation_id, id)"
"app.etape_realisee" }o--|| "app.noeud_activite" : "FOREIGN KEY (organisation_id, noeud_etape_id) REFERENCES app.noeud_activite(organisation_id, id)"
"app.etape_realisee" }o--|| "app.ordre_transformation" : "FOREIGN KEY (organisation_id, ordre_id) REFERENCES app.ordre_transformation(organisation_id, id)"
"app.etape_realisee" {
uuid id "Identifiant stable (UUID v7)."
uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
uuid ordre_id FK "Ordre de transformation concerné."
uuid noeud_etape_id FK "Étape du procédé (nœud enfant du procédé). Vide pour la saisie qui couvre tout le procédé en suivi global."
text statut "a_faire, en_cours, realisee ou validee ; une seule marche à la fois."
jsonb mesures "Mesures saisies à l'étape (objet JSON) ; modifiables tant que l'étape n'est pas validée."
timestamp_with_time_zone debut_le "Début de l'étape."
timestamp_with_time_zone fin_le "Fin de l'étape ; jamais avant le début."
uuid cree_par FK "Utilisateur qui a ouvert l'étape."
uuid valide_par FK "Utilisateur qui a validé l'étape ; renseigné si et seulement si elle est validée."
timestamp_with_time_zone valide_le "Date de validation de l'étape."
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.mouvement" {
uuid id "Identifiant du mouvement (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 nature "Nature : reception, transfert, transformation, expedition, perte, inventaire ou contrepassation."
timestamp_with_time_zone date_operation "Date de l'opération sur le terrain ou à la balance."
uuid contrepasse_mouvement_id FK "Mouvement annulé par cette contre-passation. Un mouvement n'est contre-passé qu'une fois."
text motif "Motif, obligatoire pour une contre-passation."
uuid commande_id "Commande de synchronisation à l'origine du mouvement."
uuid cree_par FK "Utilisateur auteur du mouvement."
timestamp_with_time_zone cree_le "Date de création de la ligne."
uuid etape_realisee_id FK "Étape réalisée à laquelle se rattache un mouvement de transformation (AM-12) ; obligatoire pour ce type de mouvement, vide pour les autres."
}
"app.sortie_etape" {
uuid id "Identifiant stable (UUID v7)."
uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
uuid etape_realisee_id FK "Étape qui produit la sortie ; elle doit être en cours ou réalisée, pas encore validée."
text nature "produit_principal (au plus un par étape), coproduit, sous_produit, rebut ou perte."
uuid produit_id FK "Produit de la sortie."
bigint quantite_g "Quantité en grammes, strictement positive."
uuid lot_id FK "Lot créé par un mouvement de l'étape, pour la même quantité ; vide pour un rebut ou une perte, qui ne deviennent jamais un lot."
text destination "Destination du rebut (obligatoire pour un rebut)."
text motif "Motif de la perte déclarée (obligatoire pour une perte)."
uuid cree_par FK "Utilisateur qui a déclaré la sortie."
timestamp_with_time_zone cree_le "Date de la déclaration."
boolean reintegre_flux_bio "Vrai si l'opérateur déclare que ce rebut réintègre un flux biologique (EC-120) ; réservé à la nature rebut. Lu par la variable etape.rebut_reintegre_flux_bio des normes."
uuid mouvement_id FK "Mouvement de transformation qui a produit la sortie. Une sortie dont le mouvement est contre-passé (étape dévalidée) ne compte plus dans le bilan ; vide pour les sorties antérieures à L2-6 sans mouvement retrouvé."
}
"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.noeud_activite" {
uuid id "Identifiant stable (UUID v7)."
uuid organisation_id FK "Organisation propriétaire. Sert à l'isolation par RLS (EC-032)."
text chemin "Chemin pointé du nœud, un segment par niveau, trois niveaux au plus. Au premier niveau, il vaut le code de l'activité."
text activite_code FK "Type du nœud, pris dans le catalogue fermé app.activite ; sa profondeur est celle du nœud."
text libelle_fr "Libellé en français, défini par le pack."
text libelle_en "Libellé en anglais, défini par le pack."
boolean obligatoire "Vrai : le nœud ne se désactive pas tant que son parent est actif."
boolean critique "Vrai : étape critique (OSP-05), donc obligatoire."
boolean sous_traitable "Vrai : le nœud peut être confié à un sous-traitant."
smallint ordre "Rang parmi les nœuds frères."
uuid pack_version_id FK "Version du pack d'où le nœud a été copié."
timestamp_with_time_zone cree_le "Date de création de la ligne."
timestamp_with_time_zone modifie_le "Date de dernière modification de la ligne."
jsonb contrat "Contrat facultatif du nœud (AM-04, EC-118) : entrées et sorties typées (codes produit), mesures (code, libellé, unité, type) et clés de paramètres, tel que publié par le pack et validé par packs.validerArbre. Absent : le nœud accepte tout (pas de contrat défini). Les intrants cités par AM-04 restent en écart (EC-119)."
}
"app.ordre_transformation" {
uuid id "Identifiant stable (UUID v7)."
uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
uuid campagne_id FK "Campagne des lots produits par l'ordre."
uuid site_id FK "Site où le procédé est réalisé ; le procédé doit y être actif."
uuid noeud_id FK "Procédé : nœud de l'arbre d'activités de l'organisation, de profondeur 2 ou 3, sous une activité du regroupement transformation."
text niveau_suivi "Niveau de suivi retenu à la création (réglage de l'organisation, par procédé) : global (une saisie couvre le procédé) ou detaille (une saisie par étape)."
text statut "brouillon, en_cours (dès qu'une étape démarre), termine (toutes les étapes validées) ou annule (aucune étape validée)."
timestamp_with_time_zone date_operation "Date de l'opération, saisie par l'opérateur."
text motif_annulation "Motif de l'annulation ; renseigné si et seulement si l'ordre est annulé."
uuid cree_par FK "Utilisateur qui a créé l'ordre."
timestamp_with_time_zone cree_le "Date de création de la ligne."
timestamp_with_time_zone modifie_le "Date de dernière modification."
}
Generated by tbls