feat(field_sales) : fondations du module Tournées + VisitableInterface + RBAC (ERP-123)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m26s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Failing after 13s

- Module FieldSales (ID field_sales, REQUIRED false) avec 2 permissions
  field_sales.tours.view / .manage (scope V0.2, pas de reports.*), active
  dans config/modules.php.
- Contrat partage VisitableInterface (getId/getDisplayName/getVisitableType)
  implemente par Client (client) et Supplier (supplier) sans import inter-module.
  Note doctrine.yaml : contrat polymorphe (2 implementations) donc resolu par
  service via (tier_type, tier_id), pas via resolve_target_entities.
- 3 miroirs RBAC alignes : sidebar.php (section Tournées, item /tours, i18n
  sidebar.field_sales.*), personas.ts et SeedE2ECommand.php (user-full) ;
  matrice metier RbacSeeder (Commerciale = view+manage, Bureau = view, Compta
  exclue, Admin bypass).
This commit is contained in:
Matthieu
2026-06-11 14:51:52 +02:00
parent de4aaa1d64
commit be9204eca7
12 changed files with 214 additions and 2 deletions
+2
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
use App\Module\Catalog\CatalogModule;
use App\Module\Commercial\CommercialModule;
use App\Module\Core\CoreModule;
use App\Module\FieldSales\FieldSalesModule;
use App\Module\Sites\SitesModule;
return [
@@ -11,4 +12,5 @@ return [
CommercialModule::class,
SitesModule::class,
CatalogModule::class,
FieldSalesModule::class,
];
+7
View File
@@ -41,6 +41,13 @@ doctrine:
# Permet au module Commercial de referencer une Category via le contrat
# Shared sans importer la classe concrete du module Catalog (regle n°1).
App\Shared\Domain\Contract\CategoryInterface: App\Module\Catalog\Domain\Entity\Category
# NOTE (M6 / VisitableInterface) : VisitableInterface n'apparait PAS ici.
# resolve_target_entities mappe un contrat -> UNE seule classe concrete,
# or ce contrat a plusieurs implementations (Client M1, Supplier M2, et
# Prestataire a venir). FieldSales ne reference donc pas un Tiers via une
# association Doctrine mais via le couple polymorphe (tier_type, tier_id)
# de tour_stop, resolu par un service a partir de getVisitableType()
# (ERP-124). Aucune ligne resolve_target_entities n'est requise/possible.
mappings:
Core:
type: attribute
+17
View File
@@ -61,6 +61,23 @@ return [
],
],
],
// Section "Tournées" (module field_sales, M6) : planification de tournees
// commerciales terrain. Transverse Clients/Fournisseurs. Masquee si le module
// field_sales est desactivee (cle `module`) ou si l'user n'a pas la
// permission field_sales.tours.view.
[
'label' => 'sidebar.field_sales.section',
'icon' => 'mdi:map-marker-path',
'items' => [
[
'label' => 'sidebar.field_sales.tours',
'to' => '/tours',
'icon' => 'mdi:map-marker-path',
'module' => 'field_sales',
'permission' => 'field_sales.tours.view',
],
],
],
// Section "Administration" : regroupe toutes les pages de configuration
// applicative (RBAC, users, sites, audit log).
//