Wiki/docs/06-merise-mcd.md
Corentin JOGUET 668576cdc4 chore: initial commit — formation-hub conception phase
Conception complete (Phase 0) pour formation-hub Acadenice :

- 19 docs Merise Agile + UML + GitOps + plans (tests/deploy/ops/api)
  cf docs/00-readme.md pour l'index complet
- Stack Docker compose (Docmost + Baserow + Postgres + Redis + MinIO local FS)
  compose.yml + compose.staging.yml + compose.prod.yml
- CI/CD GitHub Actions skeleton (ci, deploy-staging, deploy-prod)
- Bridge service skeleton (Hono + TS + Biome + Vitest + zod + pino)
- Templates GitHub : PR + 3 issue types + CODEOWNERS + dependabot.yml
- Scripts ops : healthcheck, backup quotidien, smoke-test post-deploy
- LICENSE AGPL-3.0 + SECURITY.md + CONTRIBUTING.md + CHANGELOG.md
- Diagramme drawIO archi infra (XML importable dans diagrams.net)

Decisions structurelles enregistrees :
- Scope CFA + Agence avec entite PERSONNE pivot multi-roles (ADR-001)
- Stack composite Docmost AGPL + Baserow MIT + bridge custom (ADR-001)
- Path B : UX quasi-unified via Tiptap node-views custom (ADR-002)
- Monorepo trunk-based development (ADR-003)
- Postgres separe Docmost/Baserow (ADR-004)
- Bridge stack Node 22 + Hono (ADR-005)
- Repo neuf prefere a fork Docmost
- Prod-like des le jour 1 (pas MVP)
2026-05-07 12:16:19 +02:00

7.9 KiB

MCD — Modele Conceptuel de Donnees

Vue conceptuelle des entites et relations. Scope B (CFA + Agence via PERSONNE pivot). Dictionnaire de donnees complet : 05-data-dictionary.md.

1. Vue d'ensemble

8 entites organisees en 3 zones :

Zone Entites
Pivot PERSONNE
CFA FORMATION, BLOC, MODULE + ATTRIBUTION (assoc.)
Agence CLIENT, PROJET, TACHE + INTERVENTION (assoc.)

PERSONNE est le pivot entre les deux activites : la meme personne peut avoir le role formateur (lie a ATTRIBUTION) et developpeur (lie a INTERVENTION). Sa capacite annuelle est splittee entre formation et agence.

2. Diagrammes entites-relations

Le modele complet a 9 entites — afficher tous les attributs sur un seul ER produit du spaghetti. On decompose en 5 vues : globale simplifiee + 3 zones detaillees + lien pedagogique.

2.1 Vue globale (simplifiee — entites et relations seules)

erDiagram
    PERSONNE ||--o{ ATTRIBUTION : "formateur"
    PERSONNE ||--o{ INTERVENTION : "developpeur"
    FORMATION ||--o{ BLOC : ""
    BLOC ||--o{ MODULE : ""
    MODULE ||--o{ ATTRIBUTION : ""
    CLIENT ||--o{ PROJET : ""
    PROJET ||--o{ TACHE : ""
    TACHE ||--o{ INTERVENTION : ""
    PROJET }o--o| FORMATION : "pedagogique"

2.2 Zone CFA (formations + heures formateurs)

erDiagram
    FORMATION ||--o{ BLOC : "1,N contient"
    BLOC ||--o{ MODULE : "1,N comprend"
    MODULE ||--o{ ATTRIBUTION : "0,N attribuee"
    PERSONNE ||--o{ ATTRIBUTION : "0,N enseigne"

    FORMATION {
        int formation_id PK
        string formation_nom UK
        enum formation_filiere
        decimal formation_heures_totales
        enum formation_statut
        date formation_date_debut
        date formation_date_fin
    }
    BLOC {
        int bloc_id PK
        int bloc_formation_id FK
        string bloc_nom
        decimal bloc_heures_prevues
        int bloc_ordre
    }
    MODULE {
        int module_id PK
        int module_bloc_id FK
        string module_nom
        decimal module_heures_prevues
        enum module_statut
    }
    ATTRIBUTION {
        int attribution_id PK
        int attribution_module_id FK
        int attribution_personne_id FK
        decimal heures_attribuees
        decimal heures_realisees
        date date_debut
        enum statut
    }
    PERSONNE {
        int personne_id PK
        string nom_prenom
        decimal capacite_annuelle
    }

2.3 Zone Agence (projets clients + heures devs)

erDiagram
    CLIENT ||--o{ PROJET : "1,N a"
    PROJET ||--o{ TACHE : "0,N comporte"
    TACHE ||--o{ INTERVENTION : "0,N realisee"
    PERSONNE ||--o{ INTERVENTION : "0,N realise"

    CLIENT {
        int client_id PK
        string client_nom UK
        string contact_email
        enum statut
    }
    PROJET {
        int projet_id PK
        int projet_client_id FK
        string projet_nom
        enum type
        decimal charge_heures
        date date_debut
        enum statut
    }
    TACHE {
        int tache_id PK
        int tache_projet_id FK
        string titre
        decimal charge_heures
        enum priorite
        enum statut
    }
    INTERVENTION {
        int intervention_id PK
        int intervention_tache_id FK
        int intervention_personne_id FK
        decimal heures
        date intervention_date
        enum statut
    }
    PERSONNE {
        int personne_id PK
        string nom_prenom
        decimal capacite_annuelle
    }

2.4 Zone Personne pivot (capacite + roles)

erDiagram
    PERSONNE ||--o{ ATTRIBUTION : "role formateur"
    PERSONNE ||--o{ INTERVENTION : "role developpeur"

    PERSONNE {
        int personne_id PK
        string personne_nom
        string personne_prenom
        string personne_email UK
        decimal capacite_annuelle
        decimal split_formation_pct
        decimal split_agence_pct
        string roles "multi-select"
        decimal heures_attribuees_formation "rollup"
        decimal heures_attribuees_agence "rollup"
        decimal heures_restantes_total "formula"
        enum statut
    }
    ATTRIBUTION {
        int attribution_id PK
        int attribution_module_id FK
        int attribution_personne_id FK
        decimal heures_attribuees
    }
    INTERVENTION {
        int intervention_id PK
        int intervention_tache_id FK
        int intervention_personne_id FK
        decimal heures
    }

2.5 Lien projet pedagogique (cross CFA-Agence)

erDiagram
    PROJET }o--o| FORMATION : "0,1 projet pedagogique"

    PROJET {
        int projet_id PK
        int projet_formation_id FK "nullable"
        string projet_nom
    }
    FORMATION {
        int formation_id PK
        string formation_nom
    }

Notation : ce lien est optionnel cote PROJET (un projet peut etre purement client). Cote FORMATION, plusieurs projets peuvent etre lies a une formation pedagogique.

3. Cardinalites detaillees

Relation Source Cardinalite Cible Cardinalite Sens metier
CONTIENT (CFA) FORMATION (1,N) BLOC (1,1) une formation comprend des blocs RNCP
COMPREND (CFA) BLOC (1,N) MODULE (1,1) un bloc se decompose en modules
ATTRIBUTION (CFA) MODULE (0,N) PERSONNE (0,N) un module est dispense par 0-N formateurs
EMPLOIE (Agence) CLIENT (1,N) PROJET (1,1) un client peut avoir des projets
COMPORTE (Agence) PROJET (0,N) TACHE (1,1) un projet est decoupe en taches
INTERVENTION (Agence) TACHE (0,N) PERSONNE (0,N) un dev peut intervenir sur 0-N taches
PROJET_PEDAGOGIQUE PROJET (0,1) FORMATION (0,N) un projet client peut servir de support pedagogique a une formation

4. Calculs (rollups + formulas) cles

PERSONNE.heures_attribuees_formation = SUM(ATTRIBUTION.heures_attribuees)
                                       WHERE attribution_personne_id = personne_id
                                       AND attribution_statut != 'annule'

PERSONNE.heures_attribuees_agence    = SUM(INTERVENTION.heures)
                                       WHERE intervention_personne_id = personne_id
                                       AND intervention_statut != 'annule'

PERSONNE.heures_restantes_total      = capacite_annuelle
                                       - heures_attribuees_formation
                                       - heures_attribuees_agence

PROJET.heures_realisees              = SUM(TACHE.heures_realisees) WHERE tache_projet_id = projet_id
TACHE.heures_realisees               = SUM(INTERVENTION.heures)    WHERE intervention_tache_id = tache_id

(rollups CFA inchanges depuis version precedente — voir Data Dictionary)

5. Regles de gestion (extension)

  • RG-PERSONNE-01 : personne_split_formation_pct + personne_split_agence_pct = 100 (CHECK constraint)
  • RG-PERSONNE-02 : Une attribution ne peut etre creee que si la personne a formateur dans ses roles.
  • RG-PERSONNE-03 : Une intervention ne peut etre creee que si la personne a developpeur dans ses roles.
  • RG-PERSONNE-04 : heures_restantes_total >= 0 est un warning UI, pas un blocage (depassement possible avec justification).

(RG CFA conserves : voir version precedente du MCD pour RG-FORMATION, RG-BLOC, RG-MODULE)

6. Questions ouvertes (a valider metier)

  • Le split formation/agence est-il fixe par personne ou variable par periode (ex: trimestre 1 a 70/30, trimestre 2 a 50/50) ?
  • Faut-il modeliser une notion de session (un module enseigne plusieurs fois a des promotions differentes) ?
  • Faut-il une notion de promotion ou de classe dans le CFA ?
  • Pour les projets pedagogiques (lien PROJET ↔ FORMATION), comment tracer les etudiants impliques ? (Si on ne modelise pas l'etudiant, on ne peut pas formellement le lier au projet — a discuter.)
  • Workflow d'approbation des heures realisees (admin valide avant facturation ou paie) ?