feat(commercial) : add Client API Platform provider + processor + business rules
Branche l'API REST du repertoire clients (M1) sur l'entite Client preparee en ERP-54. Operations GetCollection / Get / Post / Patch (pas de Delete au M1 : l'archivage passe par PATCH isArchived). ClientProvider : - liste paginee (Paginator ORM, aligne sur la convention ERP-72) + echappatoire ?pagination=false - exclut archives + soft-deletes par defaut (RG-1.24), ?includeArchived=true reintegre les archives (RG-1.25) - tri companyName ASC (RG-1.26), filtres ?search (fuzzy companyName/lastName/ email) et ?categoryType=<code> - detail : 404 sur soft-delete, embarque contacts/adresses/ribs ClientProcessor : - normalisation serveur via ClientFieldNormalizer (RG-1.18 a 1.21) - 409 sur doublon de nom de societe (RG-1.16) ; 409 dedie sur conflit de restauration (RG-1.23) - gating par onglet : champ comptable -> accounting.manage, isArchived -> archive, mode strict 403 sur tout le payload (RG-1.28) ; archivage exclusif (RG-1.22) + pose/retrait archivedAt - regles metier RG-1.01 (prenom/nom), RG-1.03 (distributor/broker exclusifs + controle du type de categorie), RG-1.12 (Virement -> banque), RG-1.13 (LCR -> >= 1 RIB), RG-1.04 (completude Information pour le role Commerciale) Lecture comptable conditionnelle : ClientReadGroupContextBuilder ajoute le groupe client:read:accounting selon commercial.clients.accounting.view. Resolution des references categorie : CategoryReferenceDenormalizer resout les IRI vers Category quand la propriete est type-hintee par le contrat CategoryInterface (denormalisation impossible sur une interface sinon). Contrats Shared : - CategoryInterface::getCategoryTypeCode() (implemente par Category) pour la verification de type sans import inter-modules - BusinessRoleAwareInterface (implemente par User) + BusinessRoles::COMMERCIALE pour detecter le role metier ; le code de role sera seede par ERP-74 et reutilise par ERP-59/60. RG-1.04 reste dormante tant qu'aucun user ne porte ce role. Coordination stack : - chaines de permission commercial.clients.* referencees ici, declarees en ERP-59 (tests RBAC complets en ERP-60) - config globale de pagination (itemsPerPage client, max 50) portee par ERP-72 - referentiels comptables (PaymentType/Bank/...) exposes en ERP-56 Tests : 31 tests Commercial (integration admin sur les regles metier + unitaires sur le gating, RG-1.04/1.12/1.13 et le context builder). Suite complete verte (339 tests).
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Shared\Domain\Security;
|
||||
|
||||
/**
|
||||
* Codes des roles METIER MALIO partages entre modules.
|
||||
*
|
||||
* Distincts des roles SYSTEME (cf. App\Module\Core\Domain\Security\SystemRoles :
|
||||
* `admin` / `user`). Un role metier porte une intention fonctionnelle (poste de
|
||||
* travail) et conditionne certaines regles de gestion au-dela des permissions
|
||||
* RBAC pures — ex : RG-1.04 du M1 Clients rend l'onglet Information obligatoire
|
||||
* pour le seul role Commerciale, alors que Commerciale et Bureau partagent les
|
||||
* memes permissions (commercial.clients.view + manage, cf. spec-back M1 § 5.2).
|
||||
*
|
||||
* Ces constantes vivent dans Shared (et non dans un module) pour que :
|
||||
* - le seed des roles cote Core (ERP-74) reference le meme code sans importer
|
||||
* une constante du module Commercial (regle ABSOLUE n°1 : pas d'import
|
||||
* inter-modules) ;
|
||||
* - le ClientProcessor (module Commercial) detecte le role Commerciale via ce
|
||||
* meme code, sans dependre de Core.
|
||||
*
|
||||
* Coordination stack M1 :
|
||||
* - ERP-74 seede le role `commerciale` avec ce code exact.
|
||||
* - ERP-59 / ERP-60 (declaration RBAC + tests personas) le reutilisent.
|
||||
* - ERP-55 (ici) ne fait que le REFERENCER : tant qu'aucun user ne porte le
|
||||
* role `commerciale`, la validation de completude Information reste dormante.
|
||||
*/
|
||||
final class BusinessRoles
|
||||
{
|
||||
/**
|
||||
* Role metier « Commerciale » — code de Role RBAC (champ Role::code,
|
||||
* snake_case impose par la regex Role). Conditionne RG-1.04.
|
||||
*/
|
||||
public const string COMMERCIALE = 'commerciale';
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
// Classe de constantes : non instanciable.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user