[DTP-Worker] Sprint 2 · Générateur fixtures ERPNext (RBAC 50 rôles → Role + Custom DocPerm)

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>
This commit is contained in:
Claude Code DTP Worker
2026-07-30 03:03:12 +00:00
parent 911f70b9ab
commit d815c7ab63
11 changed files with 869 additions and 7 deletions
@@ -0,0 +1,86 @@
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 6)
**Session** : `20260730_025643`
## Tâche exécutée
**Sprint 2 · Livrable ERPNext Backend « Générateur de fixtures RBAC → Frappe »**
(roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 2 « RBAC 50 rôles » ·
`RBAC_50_ROLES_SPEC.md` §7 qui l'annonce comme prochain incrément · suggéré par
les daily reports sessions 4-5).
## Contexte / analyse
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, `GAP_ANALYSIS_SPRINT1.md`,
daily reports sessions 4-5, `rbac_50_roles.json` + `rbac.schema.json` +
`RBAC_50_ROLES_SPEC.md`, validateur maison Publiciste, patrons générateur
Faisabilité + CI.
- État Sprint 2 côté repo : RBAC contrat (s4), Publiciste parser+gen (s3),
Faisabilité générateur 4 volets (s5) livrés. Frontend/CRM dépendent des
layouts LIVE (VPS · hors périmètre).
- **Priorité évidente et déjà annoncée** (SPEC §7, reports s4/s5) : le
**générateur de fixtures ERPNext** `rbac_50_roles.json → Role + Custom
DocPerm`. Sur le chemin critique de l'application RBAC (S4), 100 % autorable
en-repo (zéro API, zéro VPS, zéro pip), branché sur le même patron que le
Publiciste/Faisabilité.
## Réalisé — module `05_deliverables_mvp/rbac/fixtures_gen/`
- `fixturelib/frappe.py` — modèle **natif Frappe/ERPNext v15** : ordre des 15
flags DocPerm, mapping **1:1** des 12 verbes RBAC → flags, `if_owner` dérivé de
`scope_donnees == "own"`, constructeurs `role_fixture()` / `docperm_fixture()`.
Aucun chiffre métier (contrainte #1 : ERPNext natif, aucun modèle externe).
- `fixturelib/builder.py``build_bundle()` **déterministe** (tri stable rôles
par nom Frappe, DocPerms par (role, doctype, permlevel)), collecte des DocTypes
`custom` à confirmer, manifeste de traçabilité.
- `rbac_fixtures_gen.py` — CLI `build` (écrit `role.json` / `custom_docperm.json`
/ `MANIFEST.json`) et `validate`. La génération **refuse d'écrire** si un
invariant casse (schéma, 50 rôles, unicité, séparation des pouvoirs).
- `fixtures.schema.json` — contrat de sortie draft-07 (sous-ensemble supporté par
le **validateur maison Publiciste**, zéro pip).
- `tests/test_fixtures_gen.py`**11 tests `unittest` (stdlib pur)** : schéma
(maison + oracle `jsonschema` si présent), 50 rôles uniques, flags non pilotés
à 0, `if_owner`⇔scope, séparation des pouvoirs, **round-trip fidèle au
contrat** (aucune permission inventée ni perdue), déterminisme bit-à-bit.
- **CI** : job `rbac-fixtures-tests` ajouté au **gate** de `.gitea/workflows/ci.yml`
(Gitea Actions uniquement · #2).
- `README.md` + `.gitignore` (output `out/` non commité, re-généré à la demande).
- `RBAC_50_ROLES_SPEC.md §7` mis à jour (générateur livré).
## Anti-invention (#6) appliqué
- 100 % des données proviennent du contrat `rbac_50_roles.json` déjà validé ;
seuls ajouts = flags DocPerm natifs à **0** (défaut sûr) + méta de traçabilité.
- Verbes non pilotés (`select`/`amend`/`import`) forcés à 0 et testés.
- Verbe hors contrat → `ValueError` explicite (garde-fou anti-contrat corrompu).
- DocTypes DTP `custom` **jamais supposés existants** : listés dans le manifeste
« à créer + confirmer VPS » avant import (SPEC §6/§7).
- Séparation des pouvoirs : `set_user_permissions` réservé au RBAC Admin,
vérifié par test **et** par le CLI (échec si un autre rôle le porte).
## Vérifications effectuées (en-repo, sans toucher au VPS)
- **11/11 tests verts** (schéma maison + oracle `jsonschema` → concordance
draft-07 confirmée). Génération réelle : 50 rôles, **116 Custom DocPerm** sur
45 DocTypes, 4 DocTypes `custom` signalés.
- **Gate CI local vert (exit 0)** : `guard_constraints.sh`, `validate_json.sh`,
`check_docs.sh` (0 lien cassé), YAML `ci.yml` valide.
- **Régression** : 23/23 Publiciste + 10/10 RBAC + 16/16 Faisabilité toujours
verts (réutilisation du validateur sans effet de bord). **Total 60 tests.**
## Non fait (hors périmètre worker · VPS)
- Application des fixtures (`bench migrate` / `import-fixtures`) sur
`erpnext-backend-1` → agent ERPNext Backend.
- Création des DocTypes DTP `custom` + mapping `scope_donnees``User Permission`
par utilisateur → VPS.
- `permlevel > 0` (segmentation par niveau de champ) : non spécifié par le
contrat RBAC → non couvert (anti-invention #6).
## Prochaine tâche suggérée
- ERPNext S2 : générateur des fixtures `User Permission` **par entité** (WAF/WA
SRL/AC…) depuis `scope_donnees` (même patron, autorable en-repo partiellement).
- Ou Faisabilité S3 : `40_llm_outputs/` + rapports bancables FR/EN/ES.
- Ou Frontend/CRM S2 : dépend des layouts LIVE (VPS) → hors périmètre worker.
---
**Auto-score 4Big du livrable Générateur de fixtures RBAC : 96/100.** Réserve
4 : application `bench` + DocTypes `custom` + `User Permission` = côté VPS
(agent ERPNext, hors périmètre) ; `permlevel > 0` non couvert (anti-invention
#6). Validé statiquement en-repo (11 tests verts + round-trip fidèle au contrat
+ gate CI vert).