feat(commercial) : messages de validation FR sur les contraintes back + garde-fou (ERP-107)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m45s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m12s

Audit et complete les messages des contraintes #[Assert\*] des entites metier
(pendant back du mapping d'erreur par champ front ERP-101) :

- Message FR explicite sur toutes les contraintes (Email, NotBlank, Length,
  Bic, Iban, PositiveOrZero, Count...) des entites Client, ClientContact,
  ClientAddress, ClientRib, Category, Role, User.
- Ajout des Assert\Length manquantes calees sur le length de la colonne ORM
  (telephones VARCHAR(20), siren, nTva, accountNumber, username...) : evite
  une erreur Postgres 500 non rattachee au champ au profit d'une 422 propre.
- Locale FR globale (symfony/translation + default_locale: fr) comme filet
  pour les messages natifs non surcharges.
- Garde-fou tests/Architecture/EntityConstraintsHaveFrenchMessageTest : echoue
  si une contrainte n'a pas de message FR explicite ou si Assert\Length.max
  diverge du length ORM (whitelist justifiee pour les formats Bic/Iban/Regex).
- Test fonctionnel du JSON 422 reel (message FR + propertyPath consommable
  par useFormErrors cote front).
- Convention documentee dans .claude/rules/backend.md.

Tests : 469 verts (1793 assertions).
This commit is contained in:
Matthieu
2026-06-04 10:11:33 +02:00
parent 97301dcd6c
commit 9202d2ee6f
16 changed files with 617 additions and 26 deletions
+3
View File
@@ -33,6 +33,7 @@ use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Serializer\Attribute\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource(
operations: [
@@ -85,6 +86,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Busines
private ?int $id = null;
#[ORM\Column(length: 180, unique: true)]
#[Assert\NotBlank(message: 'Le nom d\'utilisateur est obligatoire.', normalizer: 'trim')]
#[Assert\Length(max: 180, maxMessage: 'Le nom d\'utilisateur ne peut dépasser {{ limit }} caractères.', normalizer: 'trim')]
#[Groups(['me:read', 'user:list', 'user:write'])]
private ?string $username = null;