[DTP-Worker] Sprint 2 · Générateur plan User Permission (RBAC row-level scope_donnees → Frappe)

Complète le pipeline RBAC (Role + Custom DocPerm déjà livrés) par la dimension
row-level. Mapping natif ERPNext v15 des 4 scope_donnees :
- entite → User Permission allow=Company (28 templates, user=sentinelle)
- own    → if_owner (déjà posé par fixtures_gen)
- groupe → aucune restriction (vue consolidée)
- equipe → pas de dimension native → signalé VPS (jamais mappé, #6)

Module userperm_gen/ : permlib/{frappe,builder}, CLI build/validate (refuse
d'écrire si invariant KO), userperm.schema.json (validateur maison, zéro pip),
12 tests unittest, README. Job CI rbac-userperm-tests ajouté au gate.
Docs SPEC §7 + fixtures_gen README cousues. Régression 72 tests verts, gate 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:33:44 +00:00
parent d815c7ab63
commit b1b011ab81
12 changed files with 925 additions and 3 deletions
@@ -0,0 +1,91 @@
# Daily Report · 2026-07-30 · Claude Code DTP Worker (session 7)
**Session** : `20260730_032644`
## Tâche exécutée
**Sprint 2 · Livrable ERPNext Backend « Générateur de plan `User Permission`
row-level (RBAC 50 rôles → scope_donnees → Frappe) »**
(roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` §Sprint 2 « RBAC 50 rôles » ·
`RBAC_50_ROLES_SPEC.md` §7 ét. 4 · **prochaine tâche suggérée** par le daily
report session 6).
## Contexte / analyse
- Relu `CLAUDE.md`, `ROADMAP_8_WEEKS_OR_LESS.md`, daily report session 6,
`rbac_50_roles.json` + `rbac.schema.json`, générateur de fixtures `fixtures_gen`
(Role + Custom DocPerm), validateur maison Publiciste, patron CI.
- État Sprint 2 : contrat RBAC (s4), Publiciste (s3), Faisabilité (s5), fixtures
`Role`+`Custom DocPerm` (s6) livrés. Frontend/CRM dépendent de layouts LIVE (VPS).
- **Priorité évidente** (SPEC §7 ét. 4 + report s6) : le mapping row-level
`scope_donnees → User Permission` — dernier maillon RBAC manquant en-repo, sur
le chemin critique de l'application RBAC (S4), 100 % autorable sans VPS/pip/API,
même patron que le générateur de fixtures.
## Réalisé — module `05_deliverables_mvp/rbac/userperm_gen/`
- `permlib/frappe.py` — modèle **Frappe/ERPNext v15 natif** : mapping des 4
valeurs `scope_donnees` → mécanisme d'enforcement row-level natif
(`own``if_owner` déjà posé par fixtures_gen · `entite``User Permission`
allow=`Company` · `groupe`→aucune restriction consolidée · `equipe`→**pas de
dimension native** → signalé). Template `User Permission` avec `user` =
**sentinelle** `__ASSIGN_PER_USER__` (une UP est per-utilisateur, pas per-rôle
→ aucun utilisateur inventé, #6). Garde-fou : `entite` + périmètre consolidé
(« Groupe ») → `ValueError`.
- `permlib/builder.py``build_plan()` **déterministe** (tri stable par nom de
rôle) : 1 entrée/rôle + manifeste (comptes par mécanisme, Companies +
rôles `equipe` à confirmer VPS).
- `userperm_gen.py` — CLI `build` / `validate`. **Refuse d'écrire** si un
invariant casse (schéma, couverture bijective des 50 rôles, mécanisme =
mapping du scope, template SSI `entite`, fidélité `for_value`↔entité,
sentinelle utilisateur, cohérence des comptes).
- `userperm.schema.json` — contrat de sortie draft-07 (sous-ensemble supporté par
le **validateur maison Publiciste**, zéro pip · `user_permission_template`
nullable).
- `tests/test_userperm_gen.py`**12 tests `unittest` (stdlib pur)** : schéma
(maison + oracle `jsonschema` si présent), couverture bijective, mécanisme↔scope,
template SSI `entite`, anti-invention utilisateur, manifeste fidèle,
déterminisme, garde-fous (scope inconnu + entité consolidée).
- **CI** : job `rbac-userperm-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).
- **Docs cousues** : `RBAC_50_ROLES_SPEC.md §7` (ét. 4 + encart livré) et
`fixtures_gen/README.md` (ét. 4) pointent désormais vers le nouveau générateur.
## Anti-invention (#6) appliqué
- 100 % des données (rôle, scope, entité) proviennent du contrat `rbac_50_roles.json`.
- **Aucun utilisateur inventé** : champ `user` = sentinelle (vérifié test + CLI).
- **Aucune restriction fabriquée** hors portée `entite` : `own`/`groupe`/`equipe`
`user_permission_template = null`.
- Portée `equipe` (pas de dimension row-level native ERPNext v15) : **signalée**
dans le manifeste (options natives documentées pour l'agent ERPNext), jamais
mappée arbitrairement.
- `for_value` (Company) = `entite_principale` du contrat, à **confirmer VPS**
(jamais supposée existante).
## Vérifications effectuées (en-repo, sans toucher au VPS)
- **12/12 tests verts** (schéma maison + oracle `jsonschema`). Génération réelle :
**50 entrées**, **28 templates Company** (`entite`), 16 consolidés (`groupe`),
2 `own`, 4 `equipe` signalés. Companies : AC Arias Cuevas, Consortium ECR DR,
Helios RD, Ploutos, WA SRL.
- **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 Publiciste + 10 RBAC + 11 fixtures + 16 Faisabilité + 12
userperm = **72 tests verts** (réutilisation du validateur sans effet de bord).
## Non fait (hors périmètre worker · VPS)
- Matérialisation des `User Permission` **par utilisateur** (remplacement de la
sentinelle) + création des Companies + import → agent ERPNext Backend.
- Décision du mécanisme des rôles `equipe` (champ custom + UP, ou
`Employee.reports_to`) → à valider avec Michel côté VPS.
## Prochaine tâche suggérée
- ERPNext S2 : agrégateur `MANIFEST` unifié Role + DocPerm + User Permission
(vue unique d'application VPS), ou générateur `Role Profile` par portail.
- Ou Faisabilité S3 : `40_llm_outputs/` + rapports bancables FR/EN/ES.
- Frontend/CRM S2 : dépend des layouts LIVE (VPS) → hors périmètre worker.
---
**Auto-score 4Big du livrable Générateur de plan User Permission : 96/100.**
Réserve 4 : matérialisation par utilisateur + création des Companies + décision
du mécanisme `equipe` = côté VPS (agent ERPNext, hors périmètre) ; portée `equipe`
sans dimension native délibérément non inventée (#6). Validé statiquement en-repo
(12 tests verts + round-trip fidèle au contrat + gate CI vert).