[ERP-74] Seed RBAC idempotent (rôles + matrice § 2.7 + demo users) + RG-1.04 + test matrice #40

Merged
malio merged 5 commits from feature/ERP-74-seed-rbac-command into develop 2026-06-01 21:06:34 +00:00
Owner

Objectif

Seeder le RBAC métier de façon rejouable et disponible en recette/prod (commande applicative, pas fixture require-dev), durcir RG-1.04, et écrire le test de matrice (rôles enfin existants).

A. RbacSeeder (Core) — source unique anti-drift

4 rôles (bureau/compta/commerciale/usine, isSystem=false), matrice § 2.7 (rôle → permissions) et comptes démo, définis en un seul endroit. Méthodes idempotentes ensureRoles / attachMatrix / ensureDemoUsers. commerciale référence BusinessRoles::COMMERCIALE (déjà consommé par RG-1.04).

B. Commande app:seed-rbac (présente en build prod, idempotente, non destructive)

  • Sans option : rôles + matrice § 2.7.
  • --with-demo-users + --password=<…> ou env RBAC_DEMO_PASSWORD : 1 compte démo/rôle. Aucun mot de passe en dur côté serveur.
  • Garde-fou : exit non-zéro + invite à lancer app:sync-permissions si les codes commercial.clients.* manquent.

C. Fixture dev/test RbacDemoFixtures (DRY)

Appelle le même seeder (ensureRoles + ensureDemoUsers). La matrice est attachée juste après par l'étape app:seed-rbac du makefile (la table permission est purgée au moment du fixtures:load, donc attachMatrix ne peut pas tourner pendant le load). make db-reset / test-db-setup reproduisent l'état de recette.

Déploiement (documenté README)

Après migration-migrate + app:sync-permissions : app:seed-rbac (prod) ; app:seed-rbac --with-demo-users --password=… (recette).

D. Durcissement RG-1.04

Pour une Commerciale, complétude de l'onglet Information exigée sur POST + tout PATCH (suppression de la condition d'intersection). Conséquence : POST Commerciale → 422 (le POST n'expose pas le groupe Information), Admin → 201. Spec § 7 amendée.

Compta ↔ onglet Comptabilité (§ 2.7)

Pour que compta PATCH accounting → 200 (exigé par la matrice), la security du Patch /clients/{id} est élargie à manage OU accounting.manage, et un nouveau guardManage (mode strict RG-1.28) interdit à un porteur non-manage de modifier les onglets principal/Information (→ 403). Approche validée : élargir la security + guard in-processor (pas de nouvel endpoint).

E. ClientRBACMatrixTest

Matrice § 2.7 complète via les comptes démo seedés (app:seed-rbac --with-demo-users) : bureau / compta / commerciale / usine (200/403 par verbe et par onglet) + RG-1.04 (POST Commerciale 422 / Admin 201).

Tests

make php-cs-fixer-allow-risky OK ; make test 429 tests verts. Idempotence vérifiée (rejeu de la commande : 0 rôle / 0 lien / 0 user). test-db-setup exécute la nouvelle étape app:seed-rbac sans erreur.

Cible : develop. Squash merge.

## Objectif Seeder le RBAC métier de façon **rejouable et disponible en recette/prod** (commande applicative, pas fixture `require-dev`), durcir RG-1.04, et écrire le test de matrice (rôles enfin existants). ## A. `RbacSeeder` (Core) — source unique anti-drift 4 rôles (`bureau`/`compta`/`commerciale`/`usine`, isSystem=false), matrice § 2.7 (rôle → permissions) et comptes démo, définis en **un seul endroit**. Méthodes idempotentes `ensureRoles` / `attachMatrix` / `ensureDemoUsers`. `commerciale` référence `BusinessRoles::COMMERCIALE` (déjà consommé par RG-1.04). ## B. Commande `app:seed-rbac` (présente en build prod, idempotente, non destructive) - Sans option : rôles + matrice § 2.7. - `--with-demo-users` + `--password=<…>` ou env `RBAC_DEMO_PASSWORD` : 1 compte démo/rôle. **Aucun mot de passe en dur** côté serveur. - Garde-fou : exit non-zéro + invite à lancer `app:sync-permissions` si les codes `commercial.clients.*` manquent. ## C. Fixture dev/test `RbacDemoFixtures` (DRY) Appelle le **même seeder** (`ensureRoles` + `ensureDemoUsers`). La matrice est attachée juste après par l'étape `app:seed-rbac` du makefile (la table `permission` est purgée au moment du `fixtures:load`, donc `attachMatrix` ne peut pas tourner pendant le load). `make db-reset` / `test-db-setup` reproduisent l'état de recette. ## Déploiement (documenté README) Après `migration-migrate` + `app:sync-permissions` : `app:seed-rbac` (prod) ; `app:seed-rbac --with-demo-users --password=…` (recette). ## D. Durcissement RG-1.04 Pour une Commerciale, complétude de l'onglet Information exigée sur **POST + tout PATCH** (suppression de la condition d'intersection). Conséquence : POST Commerciale → 422 (le POST n'expose pas le groupe Information), Admin → 201. Spec § 7 amendée. ## Compta ↔ onglet Comptabilité (§ 2.7) Pour que `compta PATCH accounting → 200` (exigé par la matrice), la security du `Patch /clients/{id}` est élargie à `manage` **OU** `accounting.manage`, et un nouveau **`guardManage`** (mode strict RG-1.28) interdit à un porteur non-`manage` de modifier les onglets principal/Information (→ 403). Approche validée : élargir la security + guard in-processor (pas de nouvel endpoint). ## E. `ClientRBACMatrixTest` Matrice § 2.7 complète via les comptes démo seedés (`app:seed-rbac --with-demo-users`) : bureau / compta / commerciale / usine (200/403 par verbe et par onglet) + RG-1.04 (POST Commerciale 422 / Admin 201). ## Tests `make php-cs-fixer-allow-risky` OK ; `make test` **429 tests verts**. Idempotence vérifiée (rejeu de la commande : 0 rôle / 0 lien / 0 user). `test-db-setup` exécute la nouvelle étape `app:seed-rbac` sans erreur. Cible : `develop`. Squash merge.
matthieu added 3 commits 2026-06-01 20:27:33 +00:00
- RbacSeeder : source unique des 4 roles metier (bureau/compta/commerciale/usine),
  de la matrice RBAC § 2.7 (role -> permissions) et des comptes demo. Operations
  idempotentes et non destructives (ensureRoles / attachMatrix / ensureDemoUsers).
- app:seed-rbac : commande applicative presente en build prod (contrairement aux
  fixtures require-dev). Sans option : roles + matrice. --with-demo-users +
  --password / RBAC_DEMO_PASSWORD : un compte demo par role. Garde-fou : exit
  non-zero + invite a lancer app:sync-permissions si les codes manquent.
- RbacDemoFixtures (dev/test) : appelle le meme seeder (DRY). La matrice est
  attachee post-sync par app:seed-rbac (la table permission est purgee au load).
- makefile : etape seed-rbac apres sync-permissions (db-reset + test-db-setup).
- Doc deploiement (README) + credentials des comptes demo (CLAUDE.md / README).
- RG-1.04 durcie : pour une Commerciale, la completude de l'onglet Information est
  exigee sur POST et sur tout PATCH, independamment des champs envoyes (suppression
  de la condition d'intersection dans validateInformationCompleteness).
- Onglet Comptabilite editable par Compta : security du Patch /clients/{id} elargie
  a `manage` OU `accounting.manage` ; nouveau guardManage (ClientProcessor, mode
  strict RG-1.28) qui refuse a un porteur non-`manage` de modifier les onglets
  principal / Information -> 403. Compta reste donc cantonne a la Comptabilite.
- Spec § 7 RG-1.04 amendee (+ consequence POST 422) + docblock du validator.
- Tests unitaires ClientProcessor : guardManage (Compta accounting-only -> 200,
  champ metier -> 403) + RG-1.04 durcie hors onglet Information.
test(commercial) : full RBAC matrix (M1)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m52s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m16s
49cf798fc9
ClientRBACMatrixTest : matrice § 2.7 par role metier via les comptes demo seedes
par la commande reelle app:seed-rbac --with-demo-users (idempotente). Valide
200/403 par verbe et par onglet pour bureau / compta / commerciale / usine :
- usine : 403 partout ;
- bureau : view + manage, sans accounting ni archive ;
- compta : view + edition accounting (200), POST/main/information/archive -> 403 ;
- commerciale : view + manage, sans accounting ni archive ;
- RG-1.04 : POST Commerciale incomplet -> 422, meme POST par Admin -> 201.
matthieu added 2 commits 2026-06-01 21:01:47 +00:00
perf(commercial) : memoize request payload decoding in ClientProcessor
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m48s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m16s
c1c7080788
matthieu added the backtype/feattype/test labels 2026-06-01 21:03:34 +00:00
malio merged commit 0e3299300f into develop 2026-06-01 21:06:34 +00:00
malio deleted branch feature/ERP-74-seed-rbac-command 2026-06-01 21:06:35 +00:00
malio added the M1-Client label 2026-06-01 21:17:10 +00:00
Sign in to join this conversation.