From a84bde5bcc897d6993c6c48b099d33ba5e45fb90 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 1 Jun 2026 09:45:17 +0200 Subject: [PATCH] feat(commercial) : declare commercial.clients permissions + sync RBAC mirrors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute CommercialModule::permissions() (5 codes commercial.clients.* : view, manage, accounting.view, accounting.manage, archive) — alignes sur les is_granted deja references par ERP-55 (Client ApiResource, ClientProcessor, ClientReadGroupContextBuilder). Synchronise les 3 sources RBAC (regle ABSOLUE n8) : item sidebar "Repertoire clients" (commercial.clients.view), persona user-full dans personas.ts et SeedE2ECommand.php, cle i18n sidebar.commercial.clients. Les roles metier Bureau/Compta/Commerciale/Usine sont seedes par ERP-74 : les 5 permissions sont mappees ici sur le seul persona technique user-full en attendant, sans creer de nouveau persona (regle n7). --- config/sidebar.php | 7 ++++ frontend/i18n/locales/fr.json | 1 + frontend/tests/e2e/_fixtures/personas.ts | 10 ++++++ src/Module/Commercial/CommercialModule.php | 32 +++++++++++++++++++ .../Infrastructure/Console/SeedE2ECommand.php | 9 ++++++ 5 files changed, 59 insertions(+) diff --git a/config/sidebar.php b/config/sidebar.php index 2d019df..b4dbe2f 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -103,6 +103,13 @@ return [ 'label' => 'sidebar.commercial.section', 'icon' => 'mdi:account-arrow-left-outline', 'items' => [ + [ + 'label' => 'sidebar.commercial.clients', + 'to' => '/commercial/clients', + 'icon' => 'mdi:account-group-outline', + 'module' => 'commercial', + 'permission' => 'commercial.clients.view', + ], [ 'label' => 'sidebar.commercial.suppliers', 'to' => '/suppliers', diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index 77849a7..af8d223 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -23,6 +23,7 @@ }, "commercial": { "section": "Commercial", + "clients": "Répertoire clients", "suppliers": "Répertoire fournisseurs" }, "core": { diff --git a/frontend/tests/e2e/_fixtures/personas.ts b/frontend/tests/e2e/_fixtures/personas.ts index 43d4bba..c610608 100644 --- a/frontend/tests/e2e/_fixtures/personas.ts +++ b/frontend/tests/e2e/_fixtures/personas.ts @@ -65,6 +65,16 @@ export const personas: Record = { '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', + 'commercial.clients.manage', + 'commercial.clients.accounting.view', + 'commercial.clients.accounting.manage', + 'commercial.clients.archive', ], expectedAdminLinks: ['users', 'roles', 'sites', 'categories', 'audit-log'], }, diff --git a/src/Module/Commercial/CommercialModule.php b/src/Module/Commercial/CommercialModule.php index 0be29ca..f4fac9c 100644 --- a/src/Module/Commercial/CommercialModule.php +++ b/src/Module/Commercial/CommercialModule.php @@ -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 + */ + 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'], + ]; + } } diff --git a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php index 115f5d6..9a59237 100644 --- a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php +++ b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php @@ -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', ], ], [