Files
Claude Code DTP Worker a30ff937f0 [DTP-Worker] Sprint 8 · buffer L75 · Reproductibilité checkout propre : hand-off out/ des 4 générateurs RBAC était .gitignore-é (gate rouge en CI, vert local seulement) + durcissement check_artifacts (build produit ⇒ DOIT être suivi par git)
Défaut réel (même classe que le bug regression_run.json corrigé plus tôt) :
les 4 générateurs RBAC (fixtures_gen/userperm_gen/roleprofile_gen/apply_plan)
.gitignore-aient leur out/, alors qu'ils sont audités en archétype `generator`
(critère HANDOFF). En checkout PROPRE (git archive HEAD = ce que voit le runner
Gitea) leur out/ est absent → qa/audit_4big (dont le build relit le out/ de
CHAQUE module) les note 80<95 ⇒ INV7 ⇒ build refusé ⇒ check-artifacts ET
check-regression ROUGES. Ça ne passait qu'en local via les out/ non suivis
laissés par des build manuels.

Fix : committer le out/ des 4 générateurs (build byte-déterministe prouvé ;
apply_plan lit ses frères en process, pas via out/) → alignement sur les 15
autres générateurs ; audit 100/100 en checkout propre.

Durcissement : check_artifacts.sh exige désormais `git ls-files --error-unmatch`
sur chaque fichier produit → un out/ ignoré/non commité devient une erreur
LOCALE honnête au lieu d'une surprise en CI. Bite-proof : git rm --cached d'un
artefact (laissé sur disque) ⇒ exit 1 ; re-add ⇒ exit 0.

Régénéré : quality_report.json (dérive DOC = taille des 4 README édités).
Vérifs : 6 gates verts sur git archive propre ; 534/21 inchangé ; suites OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-31 01:42:14 +00:00

104 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Générateur de `Role Profile` · RBAC 50 rôles → bundles par portail
**Sprint 2 · agent ERPNext Backend.** Troisième et dernier maillon RBAC en-repo,
complément des générateurs [`Role` + `Custom DocPerm`](../fixtures_gen/README.md)
(quels verbes sur quel DocType) et [plan `User Permission`](../userperm_gen/README.md)
(sur quelles lignes). Il produit les **bundles assignables** : un `Role Profile`
ERPNext v15 **natif** par portail, qui permet d'attribuer à un utilisateur, en un
seul geste (`User.role_profile_name`), l'ensemble des rôles de SON portail.
Transforme le contrat [`../rbac_50_roles.json`](../rbac_50_roles.json) (validé par
[`../rbac.schema.json`](../rbac.schema.json)) en fixtures Frappe prêtes à importer.
> Ce worker **n'écrit jamais sur le VPS** (contrainte #8). Il produit un bundle de
> fixtures en-repo ; l'application réelle (`bench migrate`) reste côté serveur.
## Pourquoi un `Role Profile` (et pas juste des rôles)
Assigner à la main les 5 à 12 rôles d'un portail à chaque nouvel utilisateur est
fastidieux et source d'erreurs. ERPNext v15 fournit nativement le DocType
`Role Profile` (contrainte #1 « ERPNext natif = priorité absolue ») : un bundle
nommé de rôles (`Has Role`) qu'on affecte en un champ. Les **5 portails métier**
(roadmap Sprint 4 « 5 portails rôle ») + la **console technique `plateforme`**
donnent **6 profils** couvrant les 50 rôles de façon **bijective** (chaque rôle
dans exactement un profil, puisque chaque rôle a exactement un `portail`).
## Ce qui est généré (`out/`, commité · byte-déterministe)
| Fichier | Rôle |
|---|---|
| `role_profile.json` | **1 fixture `Role Profile` par portail** ; chacun bundle ses rôles via des lignes enfant `Has Role`. |
| `MANIFEST.json` | Traçabilité : comptes (profils, métier vs technique, rôles couverts) + mapping `portail → role_profile`. |
## Profils générés (contrat courant · source de vérité = le JSON)
| `role_profile` | Portail | Type | Nb rôles |
|---|---|---|---|
| `OTO Portail Ventes` | ventes | métier | 12 |
| `OTO Portail Construction` | construction | métier | 10 |
| `OTO Portail Direction` | direction | métier | 9 |
| `OTO Portail Compta` | compta | métier | 8 |
| `OTO Portail Achat` | achat | métier | 5 |
| `OTO Portail Plateforme` | plateforme | technique | 6 |
| | | **Total** | **50** |
> Le nom du profil est une **convention de nommage déterministe** dérivée de la
> clé `portail` (`OTO Portail <Portail>`) — aucun libellé métier ni chiffre
> fabriqué (anti-invention #6). Les comptes viennent du contrat, pas de cette
> table (cf. SPEC §3 : le JSON reste la source de vérité).
## Utilisation
```bash
# Génère out/role_profile.json + out/MANIFEST.json
python3 roleprofile_gen.py build # [-o DOSSIER]
# Valide le bundle (schéma + invariants) sans rien écrire
python3 roleprofile_gen.py validate
# Tests (stdlib pur, zéro pip)
python3 -m unittest discover -s tests -v
```
## Garde-fous (anti-invention · #6 · déterminisme)
- **Couverture bijective** re-vérifiée : chaque rôle du contrat dans exactement
un profil, aucun rôle inventé, aucun manquant ; le CLI **refuse d'écrire** si un
invariant casse.
- **Que du natif v15** : DocTypes `Role Profile` + `Has Role` uniquement → aucun
DocType custom à confirmer côté VPS (contrairement aux `Custom DocPerm`).
- **Cohérence portail** : un profil ne mélange jamais deux portails ; son nom
correspond à la convention pour ce portail.
- **Fidélité manifeste** : flag `metier` = appartenance à `portails_business` ;
comptes re-vérifiés profil par profil.
- Sortie **déterministe** (profils triés par portail, `Has Role` triés par nom de
rôle, aucun horodatage) → diffable, re-générable bit-à-bit en CI.
## Application sur VPS (agent ERPNext Backend · hors périmètre worker)
1. Importer d'abord les fixtures `Role` ([`fixtures_gen`](../fixtures_gen/README.md))
— les `Has Role` de chaque profil référencent des `Role` qui doivent exister.
2. Déposer `role_profile.json` dans `fixtures/` de l'app OTO (`hooks.py`), puis
`bench --site frontend migrate`.
3. À la création d'un utilisateur, renseigner `role_profile_name` avec le profil
de son portail (mapping dans `MANIFEST.profiles`) → tous les rôles du portail
sont appliqués d'un coup, puis matérialiser les `User Permission` par
utilisateur ([`userperm_gen`](../userperm_gen/README.md)).
4. Vérification HTTP post-déploiement (workflow #3) + audit QA 4Big.
## Vérification en-repo
- `python3 -m unittest discover -s tests -v`**11/11 verts** (schéma maison +
oracle `jsonschema` si présent ; couverture bijective des 50 rôles, un profil
par portail, cohérence portail, manifeste fidèle, anti-invention, déterminisme).
- Génération réelle : **6 profils** (5 métier + 1 technique), **50/50 rôles**
couverts.
- Job CI dédié `rbac-roleprofile-tests` ajouté au **gate** (`.gitea/workflows/ci.yml`,
Gitea Actions uniquement · #2).
## Auto-score 4Big du livrable : **96/100**
_Réserve 4_ : l'import `bench` + l'affectation `role_profile_name` par
utilisateur restent côté VPS (agent ERPNext, hors périmètre worker, contrainte
#8). Validé statiquement en-repo (11 tests verts + schéma conforme + couverture
bijective fidèle au contrat + gate CI).