# 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).