From 2be9cd05d42e86684aab44b94bace0ea78dec468 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 15 Jun 2026 18:11:15 +0200 Subject: [PATCH] feat(transport) : permissions carriers + sidebar (ERP-153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Socle RBAC du module Transport (M4 § 5) : - TransportModule::permissions() declare transport.carriers.{view,manage,archive} - RbacSeeder::MATRIX (§ 5.2) : Bureau (view+manage), Commerciale (view) ; Compta/Usine aucun acces ; archive admin seul - config/sidebar.php : section Transport + item /carriers (gate transport.carriers.view) - i18n sidebar.transport.{section,carriers} - 3 miroirs RBAC alignes : sidebar.php, personas.ts (user-full), SeedE2ECommand.php - TransportModuleTest : garde-fou sur le jeu de permissions --- config/sidebar.php | 17 ++++++ frontend/i18n/locales/fr.json | 4 ++ frontend/tests/e2e/_fixtures/personas.ts | 7 +++ .../Core/Application/Rbac/RbacSeeder.php | 12 +++- .../Infrastructure/Console/SeedE2ECommand.php | 5 ++ src/Module/Transport/TransportModule.php | 17 ++++-- .../Module/Transport/TransportModuleTest.php | 57 +++++++++++++++++++ 7 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 tests/Module/Transport/TransportModuleTest.php diff --git a/config/sidebar.php b/config/sidebar.php index 5d5ccb3..e38e1e0 100644 --- a/config/sidebar.php +++ b/config/sidebar.php @@ -78,6 +78,23 @@ return [ ], ], ], + // Section "Transport" (M4, ERP-153) : pole logistique, porte le repertoire + // transporteurs. L'item est gate par `transport.carriers.view` ; la section + // disparait automatiquement (SidebarProvider) si le module `transport` est + // desactive ou si l'user n'a pas la permission (Compta / Usine). + [ + 'label' => 'sidebar.transport.section', + 'icon' => 'mdi:truck-outline', + 'items' => [ + [ + 'label' => 'sidebar.transport.carriers', + 'to' => '/carriers', + 'icon' => 'mdi:truck-outline', + 'module' => 'transport', + 'permission' => 'transport.carriers.view', + ], + ], + ], // Section "Administration" : regroupe toutes les pages de configuration // applicative (RBAC, users, sites, audit log). // diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index 5709bef..14840fe 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -35,6 +35,10 @@ "section": "Technique", "providers": "Répertoire prestataires" }, + "transport": { + "section": "Transport", + "carriers": "Répertoire transporteurs" + }, "core": { "roles": "Gestion des rôles", "users": "Utilisateurs", diff --git a/frontend/tests/e2e/_fixtures/personas.ts b/frontend/tests/e2e/_fixtures/personas.ts index ededce8..b690cc2 100644 --- a/frontend/tests/e2e/_fixtures/personas.ts +++ b/frontend/tests/e2e/_fixtures/personas.ts @@ -95,6 +95,13 @@ export const personas: Record = { 'technique.providers.accounting.view', 'technique.providers.accounting.manage', 'technique.providers.archive', + // Transport — Repertoire transporteurs (M4, ERP-153). Meme logique : + // mappe sur le persona "tout", pas de nouveau persona (regle ABSOLUE + // n°7). transport.carriers.view n'ajoute pas de lien dans la section + // Administration, donc expectedAdminLinks reste inchange. + 'transport.carriers.view', + 'transport.carriers.manage', + 'transport.carriers.archive', ], expectedAdminLinks: ['users', 'roles', 'sites', 'categories', 'audit-log'], }, diff --git a/src/Module/Core/Application/Rbac/RbacSeeder.php b/src/Module/Core/Application/Rbac/RbacSeeder.php index fd882a6..d96d7b6 100644 --- a/src/Module/Core/Application/Rbac/RbacSeeder.php +++ b/src/Module/Core/Application/Rbac/RbacSeeder.php @@ -51,9 +51,9 @@ final class RbacSeeder * Definition unique des 4 roles + matrice § 2.7. La cle est le code du role, * `label` le libelle FR affichable, `permissions` la liste des codes RBAC a * attacher (admin n'apparait pas car il bypass tout via isAdmin ; - * `commercial.clients.archive`, `commercial.suppliers.archive` et - * `technique.providers.archive` ne sont attaches a aucun role metier — - * admin seul). + * `commercial.clients.archive`, `commercial.suppliers.archive`, + * `technique.providers.archive` et `transport.carriers.archive` ne sont + * attaches a aucun role metier — admin seul). * * Cloisonnement par site des prestataires (M3 § 2.13) : la permission * `sites.bypass_scope` est attribuee par defaut a Bureau / Compta / @@ -77,6 +77,9 @@ final class RbacSeeder // Prestataires (M3 § 2.9, ERP-138) : view + manage (hors Comptabilite). 'technique.providers.view', 'technique.providers.manage', + // Transporteurs (M4 § 5.2, ERP-153) : view + manage (PAS archive -> admin seul). + 'transport.carriers.view', + 'transport.carriers.manage', // Visibilite multi-site des prestataires (M3 § 2.13) : voit tous les sites. 'sites.bypass_scope', // Lecture des referentiels transverses pour les selects client (ERP-102). @@ -120,6 +123,9 @@ final class RbacSeeder // (onglet Comptabilite masque/filtre pour la Commerciale). 'technique.providers.view', 'technique.providers.manage', + // Transporteurs (M4 § 5.2, ERP-153) : view seul (consultation « Tout », + // ni manage ni archive pour la Commerciale). + 'transport.carriers.view', // Visibilite multi-site des prestataires (M3 § 2.13) : voit tous les sites. 'sites.bypass_scope', // Lecture des referentiels transverses pour les selects client (ERP-102). diff --git a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php index bbef32d..880a2cb 100644 --- a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php +++ b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php @@ -212,6 +212,11 @@ final class SeedE2ECommand extends Command 'technique.providers.accounting.view', 'technique.providers.accounting.manage', 'technique.providers.archive', + // Transport — Repertoire transporteurs (M4, ERP-153). Meme + // logique : mappe sur le persona "tout". Miroir de personas.ts. + 'transport.carriers.view', + 'transport.carriers.manage', + 'transport.carriers.archive', ], ], [ diff --git a/src/Module/Transport/TransportModule.php b/src/Module/Transport/TransportModule.php index f7248ba..7a69fbf 100644 --- a/src/Module/Transport/TransportModule.php +++ b/src/Module/Transport/TransportModule.php @@ -13,17 +13,22 @@ final class TransportModule /** * Liste declarative des permissions RBAC exposees par le module Transport. * - * Vide a ce stade : le module ne porte que des referentiels externes - * synchronises par commandes console (codes IDTF - ERP-149, transporteurs - * QUALIMAT - ERP-39), sans ecran ni action protegee. Les permissions seront - * ajoutees quand une page de consultation sera exposee. + * Socle du repertoire transporteurs (M4 § 5.1, ERP-153) : + * - `view` : consultation de la liste / fiche transporteur ; + * - `manage` : creation / modification (hors archivage) ; + * - `archive` : archivage / restauration (admin seul, cf. matrice § 5.2). * - * Consommee par `app:sync-permissions` (un tableau vide est valide). + * Consommee par `app:sync-permissions`. Matrice role -> permissions dans + * `RbacSeeder::MATRIX` (§ 5.2). * * @return array */ public static function permissions(): array { - return []; + return [ + ['code' => 'transport.carriers.view', 'label' => 'Voir les transporteurs'], + ['code' => 'transport.carriers.manage', 'label' => 'Créer / modifier les transporteurs'], + ['code' => 'transport.carriers.archive', 'label' => 'Archiver / restaurer un transporteur'], + ]; } } diff --git a/tests/Module/Transport/TransportModuleTest.php b/tests/Module/Transport/TransportModuleTest.php new file mode 100644 index 0000000..79b8880 --- /dev/null +++ b/tests/Module/Transport/TransportModuleTest.php @@ -0,0 +1,57 @@ +