# Spec RBAC · 50 rôles · OTO Enterprise OS DTP

> **Livrable Sprint 2 · ERPNext Backend** (roadmap
> [`../../04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md`](../../04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md)
> §Sprint 2 l.38 : _« ERPNext Backend : RBAC 50 rôles configuration »_ ·
> [`../GAP_ANALYSIS_SPRINT1.md`](../GAP_ANALYSIS_SPRINT1.md) §3.4 gap ERPNext).
>
> **Date** : 2026-07-30 · **Auteur** : Claude Code DTP Worker · **Version** : 1.0.0

---

## 1. Objet

Design **machine-lisible** des **50 rôles RBAC** (contrainte CLAUDE.md « RBAC 50 rôles »)
à créer nativement dans Frappe/ERPNext v15. Le contrat de données est
[`rbac.schema.json`](rbac.schema.json) ; les données sont
[`rbac_50_roles.json`](rbac_50_roles.json). Ce document ne touche **jamais la
production** : il définit la **cible** que l'agent ERPNext Backend appliquera sur
le VPS via `bench` / fixtures (voir §7).

**Priorité ERPNext natif** (contrainte #1) : chaque rôle est un DocType `Role`
Frappe standard — **aucun** RBAC externe.
**CRM = ERPNext natif** (jamais EspoCRM ni HubSpot — contrainte #3).

## 2. Modèle RBAC

Le RBAC Frappe combine trois niveaux, tous couverts par le schéma :

| Niveau Frappe | Champ du schéma | Rôle |
|---|---|---|
| **Role** (DocType) | `erpnext_role_name` | Un DocType `Role` par ligne, préfixe `OTO ` (anti-collision natif). |
| **Permissions par DocType** | `permissions_cibles[]` | Verbes Frappe (`read`/`write`/`create`/`submit`/`cancel`/`report`/…) par DocType. |
| **Row-level** (User Permission) | `scope_donnees` | `own` · `equipe` · `entite` (Company) · `groupe` (consolidé). |

**Défense en profondeur** : le pouvoir `set_user_permissions` (gestion des
habilitations) est **réservé** au seul rôle `OTO Plateforme RBAC Admin`
(`scope_donnees = groupe`, `famille = plateforme`) — séparation des pouvoirs
vérifiée par test automatisé.

## 3. Cartographie portails ↔ familles

Les **5 portails métier** (roadmap Sprint 4 « 5 portails rôle ») + **1 console
technique transversale** (`plateforme`, hors du compte de 5) :

| Portail | Familles rattachées | Nb rôles |
|---|---|---|
| **direction** | direction, finance (CFO), faisabilite (analyste), legal | 9 |
| **ventes** | ventes, marketing | 12 |
| **construction** | construction, faisabilite (rendu/IFC/économiste) | 10 |
| **achat** | achat | 5 |
| **compta** | finance | 8 |
| **plateforme** _(technique)_ | plateforme | 6 |
| | **Total** | **50** |

> Répartition indicative issue de `rbac_50_roles.json` ; la source de vérité reste
> le JSON (le test impose exactement 50 rôles et la couverture des 5 portails).

## 4. Cartographie rôles ↔ entités (CLAUDE.md §Entités)

Chaque rôle porte une `entite_principale`. « Groupe » = périmètre consolidé
transversal (direction, contrôle de gestion, audit UAF, BI).

| Entité | Exemples de rôles |
|---|---|
| **WAF** (holding) | Président, Directeur Juridique, Agent ONAPI |
| **WA SRL** | Contrats de vente, Achats, Comptable général, Fiscaliste e-CF, Analyste faisabilité |
| **AC Arias Cuevas** | Directeur/Chef de projet Construction, Ingénieur, Économiste, Magasinier |
| **Consortium ECR DR** (paymaster RH) | Gestionnaire Paie |
| **Helios RD** (marque publique) | Directeur des Ventes, Conseiller, Marketing, Comptable clients AR |
| **Ploutos** (patrimoine/monétaire) | Trésorier |
| **9060 QC** (World Activities Cdn.) | DevOps, RBAC Admin, QA, OTOIA, Mobile |
| **Groupe** (consolidé) | DG, CFO, COO, CCO, Conseil, Contrôle de gestion, Audit UAF, BI |

## 5. Les 50 rôles (résumé)

> Détail complet (permissions par DocType, modules, scope) dans
> [`rbac_50_roles.json`](rbac_50_roles.json).

**Direction / Gouvernance (6)** — Président WAF · Directeur Général · CFO · COO ·
CCO · Conseil d'Administration (lecture).

**Ventes (8)** — Directeur des Ventes · Chef d'Équipe · Conseiller · Courtier
externe · Coordinateur Réservations · Gestionnaire Contrats · Coordinateur
CONFOTUR · Support Après-Vente.

**Marketing (4)** — Directeur Marketing · Publiciste (agent) · SEO · Social.

**Construction (7)** — Directeur · Chef de Projet · Ingénieur · Architecte ·
QA/QC · Coordinateur BIM · Superviseur Sous-traitants.

**Achat (5)** — Directeur · Acheteur · Gestionnaire Fournisseurs · Magasinier ·
Contrôleur Réception.

**Finance / Compta (8)** — Contrôleur de Gestion · Comptable Général · AP · AR ·
Trésorier (Ploutos) · Paie (Consortium ECR DR) · Fiscaliste e-CF · Audit UAF.

**Faisabilité / AEC (4)** — Analyste Faisabilité · Rendu 3D · IFC/Speckle ·
Économiste de la Construction.

**Legal (2)** — Directeur Juridique · Agent ONAPI.

**Plateforme technique (6)** — DevOps · RBAC Admin · QA · OTOIA (système) ·
Mobile · BI.

_(6+8+4+7+5+8+4+2+6 = 50.)_

## 6. Conformité aux contraintes CLAUDE.md

| # | Contrainte | Application ici |
|---|---|---|
| 1 | ERPNext natif prioritaire | 100 % DocType `Role` Frappe, aucun RBAC externe. |
| 3 | CRM = ERPNext natif | Rôles ventes → `Lead`/`Opportunity`/`Quotation`/`Customer` natifs. |
| 6 | Zéro invention | Aucun chiffre/plafond monétaire inventé ; seuls rôles, entités et DocTypes natifs (+ DocTypes DTP marqués `custom` à confirmer VPS). |
| 8 | VPS pour tous projets | Application des fixtures = VPS (§7), jamais local. |
| — | Séparation des pouvoirs | `set_user_permissions` réservé au RBAC Admin (test). |

**DocTypes `custom: true`** (`Faisabilité`, `Publiciste Log`, `CONFOTUR
Application`, `API Access`) = DocTypes DTP **à créer** — existence **à confirmer
VPS** par l'agent ERPNext avant application (cohérent avec l'interdit « documenter
du code sans vérifier l'existence courante »).

## 7. Application sur VPS (hors périmètre worker)

Ce worker n'écrit **jamais** sur le VPS. L'agent ERPNext Backend appliquera la
cible côté serveur (`erpnext-backend-1`) dans l'ordre ci-dessous. Ce run-book
est **consolidé et vérifié** en-repo par l'agrégateur
[`apply_plan/`](apply_plan/README.md) (`python3 rbac_apply_plan.py build` →
`apply_plan.json` + `MANIFEST.json` agrégé : comptes des 3 volets, confirmations
VPS fusionnées, graphe de dépendances, recoupement bijectif des 50 rôles) :

1. Générer les fixtures `Role` + `Custom DocPerm` depuis `rbac_50_roles.json`
   — **livré** : [`fixtures_gen/`](fixtures_gen/README.md) (`python3 rbac_fixtures_gen.py build`).
2. Créer les DocTypes DTP `custom` manquants (§6) **après** confirmation
   (listés dans `MANIFEST.custom_doctypes_a_confirmer`).
3. Déposer `role.json` + `custom_docperm.json` dans `fixtures/` de l'app OTO
   (`hooks.py`), puis `bench --site frontend migrate`.
4. Mapper les `scope_donnees` en `User Permission` par utilisateur — **plan
   livré** : [`userperm_gen/`](userperm_gen/README.md)
   (`python3 userperm_gen.py build`). Matérialiser le `user_permission_template`
   par utilisateur assigné (champ `user` = sentinelle) après confirmation des
   Companies (`MANIFEST.companies_a_confirmer`) et décision du mécanisme des
   rôles `equipe` (`MANIFEST.roles_scope_equipe_a_confirmer`).
5. Générer les **`Role Profile`** (bundles de rôles par portail) — **livré** :
   [`roleprofile_gen/`](roleprofile_gen/README.md) (`python3 roleprofile_gen.py
   build`). Importer `role_profile.json` **après** les fixtures `Role` (étape 3),
   puis affecter `User.role_profile_name` selon `MANIFEST.profiles` → tous les
   rôles d'un portail appliqués en un geste.
6. Vérification HTTP post-déploiement (workflow #3) + audit QA 4Big.

> ✅ Le **générateur de fixtures** `rbac_50_roles.json → fixtures/` est **livré**
> en-repo ([`fixtures_gen/`](fixtures_gen/README.md), même patron que le
> Publiciste, zéro pip / zéro VPS). Sortie déterministe validée par 11 tests +
> job CI `rbac-fixtures-tests`. L'application `bench` reste côté serveur.
>
> ✅ Le **plan `User Permission` row-level** `scope_donnees → mécanisme Frappe`
> est **livré** en-repo ([`userperm_gen/`](userperm_gen/README.md)) : 28
> templates `Company` (portée `entite`), portées `own`/`groupe` sans restriction
> fabriquée, portée `equipe` signalée (pas de dimension native → aucune
> invention #6). 12 tests + job CI `rbac-userperm-tests`.
>
> ✅ Les **`Role Profile`** (bundles de rôles par portail) sont **livrés** en-repo
> ([`roleprofile_gen/`](roleprofile_gen/README.md)) : **6 profils** (5 portails
> métier + console technique `plateforme`) couvrant les **50 rôles de façon
> bijective**, 100 % DocTypes natifs v15 (`Role Profile` + `Has Role`), aucun
> DocType custom à confirmer. 11 tests + job CI `rbac-roleprofile-tests`.
>
> ✅ Le **run-book d'application unifié** (agrégat des 3 volets ci-dessus) est
> **livré** en-repo ([`apply_plan/`](apply_plan/README.md)) : les 6 étapes de ce
> §7 sous forme d'un plan ordonné + un manifeste agrégé (comptes consolidés,
> confirmations VPS fusionnées, cohérence inter-volets). Zéro chiffre recalculé
> (tout vient d'un manifeste source, #6), graphe de dépendances validé (Role
> avant Role Profile). 16 tests + job CI `rbac-applyplan-tests`.

## 8. Vérification (en-repo, sans toucher au VPS)

- `python3 -m unittest discover -s tests -v` → **10/10 verts** (schéma maison +
  oracle `jsonschema`, 50 rôles, unicité, couverture 5 portails, séparation des
  pouvoirs).
- `rbac_50_roles.json` : JSON strict valide (couvert par `ci/validate_json.sh`).
- Job CI dédié `rbac-tests` ajouté au **gate** (`.gitea/workflows/ci.yml`,
  Gitea Actions uniquement · #2).

## 9. Auto-score 4Big du livrable : **95/100**

_Réserve −5_ : application des fixtures + création des DocTypes `custom` +
mapping `User Permission` = côté VPS (agent ERPNext, hors périmètre worker) ;
plafonds d'approbation monétaires par rôle volontairement **non chiffrés** ici
(anti-invention #6 — à définir avec la Direction sur pièces). Validé statiquement
en-repo (10 tests verts + schéma conforme + gate CI).
