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

234 lines
7.9 KiB
Markdown

# 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)
```mermaid
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)
```mermaid
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)
```mermaid
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)
```mermaid
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)
```mermaid
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) ?