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