# Data Dictionary > Dictionnaire de donnees complet du domaine **CFA + Agence d'Acadenice**. > Source de verite pour le MCD, MLD et MPD. Mantra BYAN #33 : Data Dictionary First. > Scope B valide : entite PERSONNE pivot multi-roles (formateur, developpeur, admin). > **Etudiants** : non modelises ici, juste users Docmost. ## Conventions - Codes en `snake_case`, prefixes par mnemonique d'entite - **Source** : `S` saisi, `C` calcule (rollup/formula), `A` automatique (timestamp/sequence) - **Type abstrait** : independant de la techno (mapping Postgres + Baserow plus loin) - **Nullable** : `O` oui, `N` non ## Mapping types abstrait → Postgres → Baserow | Type abstrait | Postgres | Baserow | |---------------|----------|---------| | `INT` | `INTEGER` ou `BIGINT` (PK) | `Number` (sans decimal) | | `DECIMAL(p,s)` | `NUMERIC(p,s)` | `Number` (avec decimal) | | `VARCHAR(n)` | `VARCHAR(n)` | `Text` | | `TEXT` | `TEXT` | `Long text` | | `DATE` | `DATE` | `Date` | | `TIMESTAMPTZ` | `TIMESTAMP WITH TIME ZONE` | `Last modified time` / `Created time` | | `ENUM(...)` | `VARCHAR + CHECK` ou type ENUM | `Single select` | | `MULTI_ENUM(...)` | tableau VARCHAR ou table associative | `Multiple select` | | `EMAIL` | `VARCHAR(254) + CHECK regex` | `Email` | | `FK` | `INTEGER + REFERENCES` | `Link to table` | --- # Section 1 — Entite pivot ## Entite PERSONNE Centrale au modele. Une personne peut cumuler plusieurs roles. Sa capacite annuelle totale se split entre formation et agence. | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `personne_id` | Identifiant | INT | N | seq | A | PK | | `personne_nom` | Nom de famille | VARCHAR(100) | N | — | S | trim | | `personne_prenom` | Prenom | VARCHAR(100) | N | — | S | trim | | `personne_email` | Email pro | EMAIL | N | — | S | UNIQUE, format email | | `personne_telephone` | Telephone | VARCHAR(20) | O | NULL | S | format E.164 si rempli | | `personne_capacite_annuelle` | Capacite totale heures/an | DECIMAL(6,2) | N | 0 | S | `>= 0` | | `personne_split_formation_pct` | Part allouee formation | DECIMAL(4,1) | N | 50.0 | S | `0-100`, `+ split_agence_pct = 100` | | `personne_split_agence_pct` | Part allouee agence | DECIMAL(4,1) | N | 50.0 | S | `0-100` | | `personne_roles` | Roles cumules | MULTI_ENUM | N | — | S | `formateur \| developpeur \| admin \| direction \| support` | | `personne_heures_attribuees_formation` | Cumul heures formation attribuees | DECIMAL(6,2) | N | 0 | C | rollup `SUM(ATTRIBUTION.heures)` | | `personne_heures_attribuees_agence` | Cumul heures agence attribuees | DECIMAL(6,2) | N | 0 | C | rollup `SUM(INTERVENTION.heures)` | | `personne_heures_restantes_formation` | Capacite formation restante | DECIMAL(6,2) | N | 0 | C | formula | | `personne_heures_restantes_agence` | Capacite agence restante | DECIMAL(6,2) | N | 0 | C | formula | | `personne_heures_restantes_total` | Capacite totale restante | DECIMAL(6,2) | N | 0 | C | formula | | `personne_statut` | Statut | ENUM | N | `actif` | S | `actif \| inactif` | **Formules cles** : ``` personne_heures_restantes_formation = (capacite_annuelle * split_formation_pct / 100) - heures_attribuees_formation personne_heures_restantes_agence = (capacite_annuelle * split_agence_pct / 100) - heures_attribuees_agence personne_heures_restantes_total = capacite_annuelle - heures_attribuees_formation - heures_attribuees_agence ``` **Note** : un admin pur (pas formateur ni developpeur) peut avoir `capacite_annuelle = 0` et splits a 0. --- # Section 2 — Branche CFA ## Entite FORMATION | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `formation_id` | Identifiant | INT | N | seq | A | PK | | `formation_nom` | Nom | VARCHAR(200) | N | — | S | UNIQUE, trim | | `formation_description` | Description | TEXT | O | NULL | S | — | | `formation_filiere` | Filiere | ENUM | O | NULL | S | `dev \| graphisme \| marketing \| iot \| cybersec` | | `formation_heures_totales` | Heures totales | DECIMAL(6,2) | N | 0 | S | `>= 0` | | `formation_heures_attribuees` | Heures attribuees blocs | DECIMAL(6,2) | N | 0 | C | rollup | | `formation_heures_restantes` | Restantes | DECIMAL(6,2) | N | 0 | C | formula | | `formation_statut` | Statut | ENUM | N | `draft` | S | `draft \| actif \| termine \| archive` | | `formation_date_debut` | Date debut | DATE | O | NULL | S | — | | `formation_date_fin` | Date fin | DATE | O | NULL | S | `>= date_debut` | | `formation_created_at` | Cree le | TIMESTAMPTZ | N | NOW() | A | — | | `formation_updated_at` | Modifie le | TIMESTAMPTZ | N | NOW() | A | — | ## Entite BLOC | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `bloc_id` | Identifiant | INT | N | seq | A | PK | | `bloc_formation_id` | Formation parente | INT FK | N | — | S | FK → FORMATION, CASCADE | | `bloc_nom` | Nom | VARCHAR(200) | N | — | S | UNIQUE par formation | | `bloc_description` | Description | TEXT | O | NULL | S | — | | `bloc_heures_prevues` | Heures du bloc | DECIMAL(6,2) | N | 0 | S | `>= 0` | | `bloc_heures_attribuees` | Heures modules | DECIMAL(6,2) | N | 0 | C | rollup | | `bloc_heures_restantes` | Restantes | DECIMAL(6,2) | N | 0 | C | formula | | `bloc_ordre` | Ordre dans formation | INT | N | 0 | S | `>= 0` | ## Entite MODULE | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `module_id` | Identifiant | INT | N | seq | A | PK | | `module_bloc_id` | Bloc parent | INT FK | N | — | S | FK → BLOC, CASCADE | | `module_nom` | Nom | VARCHAR(200) | N | — | S | trim | | `module_description` | Description | TEXT | O | NULL | S | — | | `module_heures_prevues` | Heures prevues | DECIMAL(5,2) | N | 0 | S | `>= 0` | | `module_heures_attribuees` | Heures attribuees | DECIMAL(5,2) | N | 0 | C | rollup | | `module_heures_realisees` | Heures realisees | DECIMAL(5,2) | N | 0 | C | rollup | | `module_statut` | Cycle de vie | ENUM | N | `a_attribuer` | S | `a_attribuer \| attribue \| en_cours \| realise \| annule` | ## Entite ATTRIBUTION (Module ↔ Personne[formateur]) | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `attribution_id` | Identifiant | INT | N | seq | A | PK | | `attribution_module_id` | Module attribue | INT FK | N | — | S | FK → MODULE, CASCADE | | `attribution_personne_id` | Formateur (Personne) | INT FK | N | — | S | FK → PERSONNE, RESTRICT. Personne doit avoir role `formateur` | | `attribution_heures_attribuees` | Heures planifiees | DECIMAL(5,2) | N | 0 | S | `> 0` | | `attribution_heures_realisees` | Heures effectuees | DECIMAL(5,2) | N | 0 | S | `>= 0` | | `attribution_date_debut` | Debut periode | DATE | O | NULL | S | — | | `attribution_date_fin` | Fin periode | DATE | O | NULL | S | `>= date_debut` | | `attribution_statut` | Statut | ENUM | N | `planifie` | S | `planifie \| en_cours \| realise \| annule` | --- # Section 3 — Branche AGENCE ## Entite CLIENT | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `client_id` | Identifiant | INT | N | seq | A | PK | | `client_nom` | Nom client | VARCHAR(200) | N | — | S | UNIQUE | | `client_contact_principal` | Contact (Nom + role) | VARCHAR(200) | O | NULL | S | — | | `client_contact_email` | Email contact | EMAIL | O | NULL | S | format email | | `client_contact_telephone` | Telephone | VARCHAR(20) | O | NULL | S | — | | `client_secteur` | Secteur d'activite | VARCHAR(100) | O | NULL | S | — | | `client_notes` | Notes libres | TEXT | O | NULL | S | — | | `client_statut` | Statut | ENUM | N | `prospect` | S | `prospect \| actif \| inactif \| archive` | | `client_created_at` | Cree le | TIMESTAMPTZ | N | NOW() | A | — | ## Entite PROJET | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `projet_id` | Identifiant | INT | N | seq | A | PK | | `projet_client_id` | Client | INT FK | N | — | S | FK → CLIENT, RESTRICT | | `projet_nom` | Nom projet | VARCHAR(200) | N | — | S | UNIQUE par client | | `projet_description` | Description | TEXT | O | NULL | S | — | | `projet_type` | Type | ENUM | O | NULL | S | `site_web \| app_mobile \| api \| infra \| audit \| support \| autre` | | `projet_charge_heures` | Charge estimee | DECIMAL(7,2) | N | 0 | S | `>= 0` | | `projet_heures_attribuees` | Heures attribuees taches | DECIMAL(7,2) | N | 0 | C | rollup | | `projet_heures_realisees` | Heures realisees | DECIMAL(7,2) | N | 0 | C | rollup | | `projet_heures_restantes` | Restantes | DECIMAL(7,2) | N | 0 | C | formula | | `projet_date_debut` | Date debut | DATE | O | NULL | S | — | | `projet_date_fin_prevue` | Date fin prevue | DATE | O | NULL | S | `>= date_debut` | | `projet_date_livraison` | Date livraison effective | DATE | O | NULL | S | — | | `projet_statut` | Statut | ENUM | N | `devis` | S | `devis \| en_cours \| livre \| cloture \| abandonne` | | `projet_formation_id` | Formation pedagogique liee | INT FK | O | NULL | S | FK → FORMATION (lien optionnel pour projets pedagogiques) | | `projet_url` | URL livraison | VARCHAR(500) | O | NULL | S | format URL | | `projet_repository` | URL repo Git | VARCHAR(500) | O | NULL | S | format URL | ## Entite TACHE | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `tache_id` | Identifiant | INT | N | seq | A | PK | | `tache_projet_id` | Projet parent | INT FK | N | — | S | FK → PROJET, CASCADE | | `tache_titre` | Titre | VARCHAR(200) | N | — | S | trim | | `tache_description` | Description | TEXT | O | NULL | S | — | | `tache_charge_heures` | Charge estimee | DECIMAL(5,2) | N | 0 | S | `>= 0` | | `tache_heures_realisees` | Heures realisees | DECIMAL(5,2) | N | 0 | C | rollup | | `tache_priorite` | Priorite | ENUM | O | NULL | S | `faible \| normale \| haute \| critique` | | `tache_statut` | Statut | ENUM | N | `todo` | S | `todo \| in_progress \| review \| done \| abandoned` | | `tache_date_debut` | Debut prevu | DATE | O | NULL | S | — | | `tache_date_fin_prevue` | Fin prevue | DATE | O | NULL | S | `>= date_debut` | ## Entite INTERVENTION (Tache ↔ Personne[developpeur]) | Code | Designation | Type | Nullable | Default | Source | Contraintes | |------|-------------|------|----------|---------|--------|-------------| | `intervention_id` | Identifiant | INT | N | seq | A | PK | | `intervention_tache_id` | Tache | INT FK | N | — | S | FK → TACHE, CASCADE | | `intervention_personne_id` | Developpeur (Personne) | INT FK | N | — | S | FK → PERSONNE, RESTRICT. Personne doit avoir role `developpeur` | | `intervention_heures` | Heures effectuees | DECIMAL(5,2) | N | 0 | S | `> 0` | | `intervention_date` | Date intervention | DATE | N | TODAY | S | — | | `intervention_notes` | Notes / commit ref | TEXT | O | NULL | S | — | | `intervention_statut` | Statut | ENUM | N | `realise` | S | `planifie \| realise \| annule` | --- # Section 4 — Cardinalites synthetiques | Relation | Source | Cible | Cardinalite | |----------|--------|-------|-------------| | FORMATION → BLOC | (1,N) | (1,1) | une formation a au moins 1 bloc | | BLOC → MODULE | (1,N) | (1,1) | un bloc a au moins 1 module | | MODULE ↔ PERSONNE via ATTRIBUTION | (0,N) | (0,N) | n-n porteuse | | CLIENT → PROJET | (0,N) | (1,1) | un client peut avoir 0+ projets | | PROJET → TACHE | (0,N) | (1,1) | un projet peut etre vide ou avoir des taches | | TACHE ↔ PERSONNE via INTERVENTION | (0,N) | (0,N) | n-n porteuse | | PROJET ↔ FORMATION | (0,1) | (0,N) | lien optionnel projet pedagogique | # Section 5 — Volumetrie estimee (an 1 / an 5) | Entite | An 1 | An 5 | |--------|------|------| | PERSONNE | ~30 | ~80 | | FORMATION | ~10 | ~50 | | BLOC | ~50 | ~250 | | MODULE | ~500 | ~2500 | | ATTRIBUTION | ~600 | ~3000 | | CLIENT | ~10 | ~50 | | PROJET | ~20 | ~150 | | TACHE | ~200 | ~2000 | | INTERVENTION | ~2000 | ~20000 | Volumetrie negligeable cote performance — indexation standard sur les FK suffit.