Transforme rbac_50_roles.json en fixtures Frappe/ERPNext v15 natives, prêtes à appliquer via bench (VPS · agent ERPNext). Réalise le prochain incrément annoncé au §7 de RBAC_50_ROLES_SPEC.md. Zéro pip, zéro VPS, sortie déterministe. - fixturelib/frappe.py : modèle natif (15 flags DocPerm, mapping 1:1 des verbes RBAC, if_owner⇔scope "own"). fixturelib/builder.py : bundle déterministe. - rbac_fixtures_gen.py : CLI build/validate (refuse d'écrire si invariant KO). - fixtures.schema.json : contrat de sortie (validateur maison Publiciste réutilisé). - 11 tests unittest : schéma+oracle, 50 rôles, séparation des pouvoirs, round-trip fidèle au contrat, déterminisme. Job CI rbac-fixtures-tests au gate. - Anti-invention #6 : 100% dérivé du contrat, flags non pilotés à 0, DocTypes custom signalés « à confirmer VPS ». Vérif : 11/11 verts + gate CI local vert (exit 0) + régression 60 tests OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.7 KiB
Générateur de fixtures ERPNext · RBAC 50 rôles → Frappe
Sprint 2 · agent ERPNext Backend. Transforme le contrat
../rbac_50_roles.json (validé par
../rbac.schema.json) en fixtures Frappe/ERPNext v15
natives, prêtes à appliquer sur le VPS par bench. Réalise le « prochain
incrément » annoncé au §7 de ../RBAC_50_ROLES_SPEC.md.
Ce worker n'écrit jamais sur le VPS (contrainte #8). Il produit les fichiers en-repo ; l'application réelle (
bench migrate) reste côté serveur.
Ce qui est généré (out/, non commité)
| Fichier | DocType Frappe | Rôle |
|---|---|---|
role.json |
Role |
50 rôles desk préfixés OTO (anti-collision natif). |
custom_docperm.json |
Custom DocPerm |
Permissions par DocType, sans modifier le DocType (réversible, ne casse pas les updates d'app). |
MANIFEST.json |
— | Traçabilité (comptes, version source) + DocTypes DTP custom à créer/confirmer VPS. |
Utilisation
# Génère out/role.json, out/custom_docperm.json, out/MANIFEST.json
python3 rbac_fixtures_gen.py build # [-o DOSSIER]
# Valide le bundle (schéma + invariants) sans rien écrire
python3 rbac_fixtures_gen.py validate
# Tests (stdlib pur, zéro pip)
python3 -m unittest discover -s tests -v
Mapping RBAC → Frappe (aucune invention · #6)
- Chaque
permissions_cibles[].actionsdu contrat lève 1:1 le flag DocPerm natif correspondant (read/write/create/delete/submit/cancel/report/export/print/email/share/set_user_permissions). Les flags non pilotés (select/amend/import) restent à 0 (défaut sûr). scope_donnees == "own"→if_owner = 1(restriction Frappe native). Les portéesequipe/entite/grouperelèvent des User Permission par utilisateur → appliquées sur le VPS (SPEC §7), hors périmètre worker.permlevel = 0(le contrat ne segmente pas par niveau de champ).- Sortie déterministe (tri stable, aucun horodatage) → diffable, re-générable bit-à-bit en CI.
Séparation des pouvoirs (défense en profondeur)
Le flag set_user_permissions n'est émis que pour le rôle RBAC Admin
(famille = plateforme, scope = groupe) — vérifié par test et par le CLI
(validate échoue si un autre rôle le porte). Aucune élévation de privilège
possible via les fixtures.
Application sur VPS (agent ERPNext Backend · hors périmètre worker)
- Créer d'abord les DocTypes DTP
customlistés dansMANIFEST.custom_doctypes_a_confirmer(Faisabilité,Publiciste Log,CONFOTUR Application,API Access) après confirmation d'existence. - Déposer
role.json+custom_docperm.jsondansfixtures/de l'app OTO, référencés danshooks.py. bench --site frontend migrate(oubench import-fixtures).- Mapper
scope_donnees→User Permissionpar utilisateur. - 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 + oraclejsonschemasi présent ; round-trip fidèle au contrat, déterminisme, séparation des pouvoirs).- Job CI dédié
rbac-fixtures-testsajouté au gate (.gitea/workflows/ci.yml, Gitea Actions uniquement · #2).
Auto-score 4Big du livrable : 96/100
Réserve −4 : application des fixtures + création des DocTypes custom +
mapping User Permission = côté VPS (agent ERPNext, hors périmètre worker) ;
permlevel > 0 non couvert (le contrat RBAC ne le spécifie pas — anti-invention
#6). Validé statiquement en-repo (11 tests verts + schéma conforme + gate CI).