[ERP-59] Déclarer les permissions Commercial.clients + synchroniser RBAC (3 sources) #32

Closed
matthieu wants to merge 9 commits from feature/ERP-59-declarer-permissions-commercial-clients-rbac into develop
5 changed files with 59 additions and 0 deletions
Showing only changes of commit a84bde5bcc - Show all commits
+7
View File
@@ -103,6 +103,13 @@ return [
'label' => 'sidebar.commercial.section',
'icon' => 'mdi:account-arrow-left-outline',
'items' => [
[
'label' => 'sidebar.commercial.clients',
'to' => '/commercial/clients',
Outdated
Review

Incohérence de convention de route dans la section Commercial.

Contexte : le nouvel item pointe vers /commercial/clients (imbriqué), alors que l'item voisin suppliers pointe vers /suppliers (plat), et les items Administration vers /admin/*.

Cause : côté front, le module commercial n'expose aujourd'hui que pages/commercial.vue (→ /commercial). Tant qu'ERP-73 n'a pas créé la page, le lien /commercial/clients mènera à un 404 si on clique dessus (sans impact e2e : le test n'asserte que la présence des liens Administration, pas la navigation).

Recommandation : confirmer qu'ERP-73 implémentera bien la page à l'emplacement exact /commercial/clients (ex. pages/commercial/clients.vue), et trancher la convention du module Commercial (imbriqué /commercial/* vs plat /suppliers) pour rester cohérent. Mineur, à coordonner avec ERP-73.

**Incohérence de convention de route dans la section Commercial.** **Contexte** : le nouvel item pointe vers `/commercial/clients` (imbriqué), alors que l'item voisin `suppliers` pointe vers `/suppliers` (plat), et les items Administration vers `/admin/*`. **Cause** : côté front, le module `commercial` n'expose aujourd'hui que `pages/commercial.vue` (→ `/commercial`). Tant qu'ERP-73 n'a pas créé la page, le lien `/commercial/clients` mènera à un 404 si on clique dessus (sans impact e2e : le test n'asserte que la présence des liens Administration, pas la navigation). **Recommandation** : confirmer qu'ERP-73 implémentera bien la page à l'emplacement exact `/commercial/clients` (ex. `pages/commercial/clients.vue`), et trancher la convention du module Commercial (imbriqué `/commercial/*` vs plat `/suppliers`) pour rester cohérent. Mineur, à coordonner avec ERP-73.
'icon' => 'mdi:account-group-outline',
'module' => 'commercial',
'permission' => 'commercial.clients.view',
],
[
'label' => 'sidebar.commercial.suppliers',
'to' => '/suppliers',
+1
View File
@@ -23,6 +23,7 @@
},
"commercial": {
"section": "Commercial",
"clients": "Répertoire clients",
"suppliers": "Répertoire fournisseurs"
},
"core": {
+10
View File
@@ -65,6 +65,16 @@ export const personas: Record<PersonaKey, Persona> = {
'sites.bypass_scope',
'catalog.categories.view',
'catalog.categories.manage',
// Commercial — Repertoire clients (M1). Mappe ici sur le persona
// "tout" en attendant les vrais roles metier (bureau/compta/
// commerciale/usine) seedes par ERP-74. Pas de nouveau persona
// (regle ABSOLUE n°7). commercial.clients.view n'ajoute pas de lien
// dans la section Administration, donc expectedAdminLinks reste inchange.
'commercial.clients.view',
Outdated
Review

Mapping RBAC e2e volontairement grossier — gradations non couvertes jusqu'à ERP-74.

Contexte : les 5 permissions sont toutes accordées au seul persona e2e.user-full.

Cause : du coup aucun persona ne représente un utilisateur ayant commercial.clients.view/manage SANS accounting.manage ni archive. Or c'est précisément la différenciation que le ClientProcessor d'ERP-55 met en œuvre (gating 403 sur l'onglet Comptabilité, sur l'archivage, RG-1.28 strict). Ce comportement différentiel reste donc vérifié uniquement par les tests unitaires du Processor, pas de bout en bout.

Recommandation : acceptable et déjà documenté (les vrais rôles métier bureau/compta/commerciale/usine arrivent en ERP-74). Penser à ajouter à ce moment-là un persona « view sans accounting/archive » pour exercer le gating en e2e. Aucune action requise sur cette MR.

**Mapping RBAC e2e volontairement grossier — gradations non couvertes jusqu'à ERP-74.** **Contexte** : les 5 permissions sont toutes accordées au seul persona `e2e.user-full`. **Cause** : du coup aucun persona ne représente un utilisateur ayant `commercial.clients.view`/`manage` SANS `accounting.manage` ni `archive`. Or c'est précisément la différenciation que le ClientProcessor d'ERP-55 met en œuvre (gating 403 sur l'onglet Comptabilité, sur l'archivage, RG-1.28 strict). Ce comportement différentiel reste donc vérifié uniquement par les tests unitaires du Processor, pas de bout en bout. **Recommandation** : acceptable et déjà documenté (les vrais rôles métier bureau/compta/commerciale/usine arrivent en ERP-74). Penser à ajouter à ce moment-là un persona « view sans accounting/archive » pour exercer le gating en e2e. Aucune action requise sur cette MR.
'commercial.clients.manage',
'commercial.clients.accounting.view',
'commercial.clients.accounting.manage',
'commercial.clients.archive',
],
expectedAdminLinks: ['users', 'roles', 'sites', 'categories', 'audit-log'],
},
@@ -9,4 +9,36 @@ final class CommercialModule
public const string ID = 'commercial';
public const string LABEL = 'Commercial';
public const bool REQUIRED = false;
/**
* Liste declarative des permissions RBAC exposees par le module Commercial.
*
* Consommee par la commande `app:sync-permissions` (SyncPermissionsCommand)
* qui se charge d'upserter ces entrees dans la table `permission`, de
* reactiver les codes precedemment marques orphelins et de marquer comme
* orphelins ceux qui ont disparu du code source.
*
* La cle `module` est auto-injectee par le sync command a partir de
* `self::ID`, il est donc inutile de la repeter dans chaque entree.
*
* Convention de nommage des codes : `module.resource[.sub].action` en
* snake_case, le prefixe module devant correspondre exactement a
* `self::ID` (verifie par la commande de synchronisation).
*
* Granularite alignee sur Core/Catalog (view + manage), plus deux
* permissions dediees a l'onglet Comptabilite et a l'archivage
* (cf. spec-back M1 § 2.7).
*
* @return array<int, array{code: string, label: string}>
*/
public static function permissions(): array
{
return [
['code' => 'commercial.clients.view', 'label' => 'Voir les clients'],
['code' => 'commercial.clients.manage', 'label' => 'Créer / modifier les clients (hors onglet Comptabilité)'],
['code' => 'commercial.clients.accounting.view', 'label' => 'Voir l\'onglet Comptabilité d\'un client'],
['code' => 'commercial.clients.accounting.manage', 'label' => 'Modifier l\'onglet Comptabilité d\'un client'],
['code' => 'commercial.clients.archive', 'label' => 'Archiver / restaurer un client'],
];
}
}
@@ -186,6 +186,15 @@ final class SeedE2ECommand extends Command
'sites.bypass_scope',
'catalog.categories.view',
'catalog.categories.manage',
// Commercial — Repertoire clients (M1). Mappe ici sur le
// persona "tout" en attendant les vrais roles metier
// (bureau/compta/commerciale/usine) seedes par ERP-74.
// Miroir de frontend/tests/e2e/_fixtures/personas.ts.
'commercial.clients.view',
'commercial.clients.manage',
'commercial.clients.accounting.view',
'commercial.clients.accounting.manage',
'commercial.clients.archive',
],
],
[