refactor(commercial) : suppression du contact principal inline du Client (M1)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m57s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m13s

Le contact principal (firstName, lastName, phonePrimary, phoneSecondary,
email) n'est plus porte par l'entite Client : les contacts vivent uniquement
dans ClientContact (onglet Contact). RG-1.01 et RG-1.02 supprimees du Client
(equivalent RG-1.05 / RG-1.14 sur ClientContact).

- Migration (namespace racine DoctrineMigrations, ordre par timestamp) :
  backfill des clients sans contact vers client_contact (position 0) puis
  DROP des 5 colonnes inline. down() best-effort documente.
- Entite Client : retrait des 5 props + getters/setters + groupes.
- ClientProcessor : MAIN_FIELDS / changedBusinessFields / normalize alleges,
  validateMainContact (RG-1.01) supprimee.
- Recherche repertoire : companyName seul (D1).
- Export XLSX : colonnes de contact retirees (D2).
- Fixtures + catalogue de commentaires SQL alignes.
- Tests fonctionnels et unitaires mis a jour.
This commit is contained in:
Matthieu
2026-06-03 15:31:01 +02:00
parent 6f977d387d
commit 74f0f981d8
16 changed files with 253 additions and 375 deletions
@@ -12,41 +12,13 @@ use App\Module\Commercial\Domain\Entity\Client as ClientEntity;
* RG-1.16 (doublon de companyName parmi les actifs -> 409) est DEJA couvert par
* ClientApiTest::testPostDuplicateCompanyNameReturns409 (ERP-55). Ce fichier
* verifie l'envers de la decision Q4 (29/05/2026) : le SIREN (RG-1.15 supprimee)
* et l'email (RG-1.17 supprimee) NE SONT PLUS contraints uniques.
* n'est PLUS contraint unique. (L'email RG-1.17 — a disparu du Client avec la
* refonte contact, il vit desormais sur ClientContact.)
*
* @internal
*/
final class ClientUniquenessTest extends AbstractCommercialApiTestCase
{
private const string LD = 'application/ld+json';
/**
* RG-1.16 / RG-1.17 (Q4) : deux clients actifs peuvent partager le meme
* email principal — aucune contrainte d'unicite (un email peut servir
* plusieurs clients).
*/
public function testDuplicateEmailIsAllowed(): void
{
$client = $this->createAdminClient();
$cat = $this->createCategory('SECTEUR');
$iri = '/api/categories/'.$cat->getId();
$payload = static fn (string $name): array => [
'companyName' => $name,
'firstName' => 'A',
'phonePrimary' => '0102030405',
'email' => 'partage@test.fr',
'categories' => [$iri],
];
$client->request('POST', '/api/clients', ['headers' => ['Content-Type' => self::LD], 'json' => $payload('Email Share One')]);
self::assertResponseStatusCodeSame(201);
// Meme email, nom different -> doit passer (pas d'index unique email).
$client->request('POST', '/api/clients', ['headers' => ['Content-Type' => self::LD], 'json' => $payload('Email Share Two')]);
self::assertResponseStatusCodeSame(201);
}
/**
* RG-1.15 (Q4) : deux clients peuvent partager le meme SIREN (etablissements
* multiples). Le SIREN n'est pas ecrivable au POST (groupe accounting), on