75a3b0a471
Clôt le volet RBAC en-repo : recoud fixtures Role+DocPerm, plan User Permission et Role Profile en un run-book ordonné + manifeste agrégé. Zéro chiffre recalculé (tout vient d'un manifeste source, #6), graphe de dépendances validé (Role avant Role Profile), cohérence inter-volets + couverture bijective 50/50. 16 tests + job CI rbac-applyplan-tests · 99 tests de régression au total. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
5.1 KiB
Markdown
96 lines
5.1 KiB
Markdown
# Agrégateur RBAC · run-book d'application VPS unifié
|
||
|
||
**Sprint 2 · agent ERPNext Backend.** Quatrième et dernier maillon RBAC en-repo :
|
||
la **vue d'ensemble**. Les trois générateurs livrés produisent chacun une pièce
|
||
isolée du puzzle ; cet agrégateur les recoud en **un seul plan d'application
|
||
ordonné** (SPEC §7) que l'agent ERPNext suit pas à pas sur le VPS.
|
||
|
||
| Générateur | Répond à | Produit |
|
||
|---|---|---|
|
||
| [`fixtures_gen`](../fixtures_gen/README.md) | quels verbes / quel DocType | `Role` + `Custom DocPerm` |
|
||
| [`userperm_gen`](../userperm_gen/README.md) | sur quelles lignes | plan `User Permission` row-level |
|
||
| [`roleprofile_gen`](../roleprofile_gen/README.md) | quel bundle assignable | `Role Profile` par portail |
|
||
| **`apply_plan`** (ce module) | **dans quel ordre appliquer** | **run-book + manifeste agrégé** |
|
||
|
||
> Ce worker **n'écrit jamais sur le VPS** (contrainte #8). Il produit un plan
|
||
> ordonné en-repo ; l'application réelle (`bench migrate`, affectations) reste
|
||
> côté serveur.
|
||
|
||
## Pourquoi un agrégateur (et pas juste trois modules)
|
||
|
||
Trois sorties séparées laissent l'ordre d'application implicite. Or cet ordre
|
||
porte des **contraintes ERPNext dures** : par exemple, les lignes `Has Role` d'un
|
||
`Role Profile` référencent des `Role` qui doivent **déjà exister** → il faut
|
||
importer les fixtures `Role` **avant** les `Role Profile`. Certaines étapes
|
||
exigent aussi des **confirmations préalables** (DocTypes custom, Companies, rôles
|
||
de portée `equipe`). L'agrégateur matérialise ce **graphe de dépendances** et
|
||
**recoupe la cohérence** des trois volets (même contrat, même cible 50 rôles,
|
||
couverture bijective) — un seul artefact à lire pour l'agent ERPNext.
|
||
|
||
## Ce qui est généré (`out/`, non commité)
|
||
|
||
| Fichier | Rôle |
|
||
|---|---|
|
||
| `apply_plan.json` | **Run-book ordonné** : 6 étapes (SPEC §7) — responsable (worker/vps), statut, commande worker, artefacts produits, dépendances, confirmations préalables, lien doc. |
|
||
| `MANIFEST.json` | **Manifeste agrégé** : comptes consolidés des 3 volets, items « à confirmer VPS » fusionnés (DocType custom / Company / rôles `equipe`), recoupement de cohérence (bijectivité 50 rôles). |
|
||
|
||
## Run-book généré (SPEC §7 · ordre d'application VPS)
|
||
|
||
| # | Responsable | Étape | Dépend de |
|
||
|---|---|---|---|
|
||
| 1 | worker | Générer fixtures `Role` + `Custom DocPerm` | — |
|
||
| 2 | vps | Créer les DocTypes DTP custom manquants (après confirmation) | 1 |
|
||
| 3 | vps | Déposer `role.json` + `custom_docperm.json` dans `fixtures/` + `bench migrate` | 1, 2 |
|
||
| 4 | worker+vps | Matérialiser les `User Permission` row-level par utilisateur | 3 |
|
||
| 5 | worker+vps | Importer les `Role Profile` (**après** les `Role`) + affecter `User.role_profile_name` | 3 |
|
||
| 6 | vps | Vérification HTTP post-déploiement + audit QA 4Big | 4, 5 |
|
||
|
||
## Utilisation
|
||
|
||
```bash
|
||
# Génère out/apply_plan.json + out/MANIFEST.json
|
||
python3 rbac_apply_plan.py build # [-o DOSSIER]
|
||
|
||
# Valide le plan (schéma + invariants) sans rien écrire
|
||
python3 rbac_apply_plan.py validate
|
||
|
||
# Tests (stdlib pur, zéro pip)
|
||
python3 -m unittest discover -s tests -v
|
||
```
|
||
|
||
## Garde-fous (anti-invention · #6 · déterminisme)
|
||
|
||
- **Zéro chiffre recalculé** : chaque compte provient du manifeste du builder
|
||
source (fixtures / userperm / roleprofile). Chaque item « à confirmer VPS » est
|
||
repris tel quel. Le CLI **refuse d'écrire** si un invariant casse.
|
||
- **Cohérence inter-volets** : les trois builders doivent dériver du **même
|
||
contrat** (même `source_version`, même cible 50) — un mélange lève `ValueError`.
|
||
- **Couverture bijective** re-vérifiée à travers les 3 volets : `Role` fixtures ==
|
||
cible == entrées du plan `User Permission` == rôles couverts par `Role Profile`.
|
||
- **Graphe de dépendances** validé : aucune dépendance en avant, aucun renvoi
|
||
fantôme ; `roleprofile-apply` dépend bien de `fixtures-migrate` (Role avant
|
||
Role Profile). Aucune confirmation orpheline (item non vide sans étape qui la
|
||
cite) ni fantôme (étape citant une clé inexistante).
|
||
- Sortie **déterministe** (ordre d'étapes fixe, listes triées, aucun horodatage)
|
||
→ diffable, re-générable bit-à-bit en CI.
|
||
|
||
## Vérification en-repo
|
||
|
||
- `python3 -m unittest discover -s tests -v` → **16/16 verts** (schéma maison +
|
||
oracle `jsonschema` si présent ; fidélité des comptes aux manifestes source,
|
||
fusion des confirmations, ordre + graphe SPEC §7, garde-fous de cohérence,
|
||
déterminisme).
|
||
- Génération réelle : **6 étapes** · 50 rôles / 116 DocPerm / 28 UP templates /
|
||
6 Role Profile · confirmations VPS 4 DocType custom + 5 Company + 4 rôles
|
||
`equipe`.
|
||
- Job CI dédié `rbac-applyplan-tests` ajouté au **gate** (`.gitea/workflows/ci.yml`,
|
||
Gitea Actions uniquement · #2).
|
||
|
||
## Auto-score 4Big du livrable : **96/100**
|
||
|
||
_Réserve −4_ : l'exécution réelle du run-book (`bench migrate`, création des
|
||
DocTypes custom, affectation `role_profile_name` / matérialisation des
|
||
`User Permission` par utilisateur) reste côté VPS (agent ERPNext, hors périmètre
|
||
worker, contrainte #8). Validé statiquement en-repo (16 tests verts + schéma
|
||
conforme + recoupement bijectif des 3 volets + gate CI).
|