feat(transport) : schéma + entités Carrier + contrat lecture (ERP-155/157) #112

Merged
matthieu merged 3 commits from feat/erp-155-carrier-schema-entities into feat/erp-153-rbac 2026-06-16 13:47:40 +00:00
3 changed files with 19 additions and 2 deletions
Showing only changes of commit aa23189fe1 - Show all commits
@@ -23,11 +23,19 @@ interface CarrierRepositoryInterface
* Fetch-join uniquement qualimatCarrier (ManyToOne, sur — § 2.11) : la liste
* n'embarque aucune sous-collection. Tri par defaut name ASC.
*
* Perimetre d'archivage (aligne sur ClientProvider/SupplierProvider/
* ProviderProvider — toggle « Voir les archives » d'ERP-173) :
* - $archivedOnly = true -> uniquement les archives (is_archived = true) ;
* - sinon $includeArchived = true -> actifs + archives (echappatoire) ;
* - par defaut -> actifs seuls (is_archived = false).
* $archivedOnly a la priorite sur $includeArchived.
*
* @param list<string> $certificationTypes filtre repetable (OR) sur certificationType
*/
public function createListQueryBuilder(
bool $includeArchived = false,
?string $search = null,
array $certificationTypes = [],
bool $archivedOnly = false,
): QueryBuilder;
}
@@ -23,6 +23,8 @@ use Symfony\Component\DependencyInjection\Attribute\Autowire;
* Collection (GET /api/carriers) :
* - exclut par defaut les archives (is_archived = true) ET les soft-deletes ;
* - ?includeArchived=true reintegre les archives (soft-deletes toujours exclus) ;
* - ?archivedOnly=true n'expose QUE les archives (prioritaire sur includeArchived,
* aligne sur Client/Supplier/Provider — toggle « Voir les archives » ERP-173) ;
* - filtres ?search= (fuzzy name) et ?certificationType= (repetable) ;
* - tri par defaut name ASC ; pagination Hydra (regle n°13) + echappatoire
* ?pagination=false.
1
@@ -58,6 +60,7 @@ final class CarrierProvider implements ProviderInterface
{
Outdated
Review

🟡 Cohérence filtre archives avec les 3 autres répertoires. Ce provider n'expose que ?includeArchived=true. Or ClientProvider, SupplierProvider et ProviderProvider exposent aussi ?archivedOnly=true (afficher uniquement les archivés) — c'est précisément le toggle « Voir les archivés » aligné par ERP-173.

La spec-back M4 § 2.4 (rédigée avant ERP-173) ne mentionne que includeArchived, donc tu es conforme à ta spec. Mais le front Répertoire (ERP-164) réutilisera le composant « Voir les archivés » des autres écrans, qui envoie archivedOnly → le toggle sera silencieusement inopérant côté transporteurs.

Reco : ajouter le paramètre archivedOnly (prioritaire sur includeArchived, comme ProviderProvider/DoctrineProviderRepository) pour rester l'exact « jumeau » annoncé du SupplierProvider.

🟡 **Cohérence filtre archives avec les 3 autres répertoires.** Ce provider n'expose que `?includeArchived=true`. Or `ClientProvider`, `SupplierProvider` et `ProviderProvider` exposent aussi `?archivedOnly=true` (afficher *uniquement* les archivés) — c'est précisément le toggle « Voir les archivés » aligné par ERP-173. La spec-back M4 § 2.4 (rédigée avant ERP-173) ne mentionne que `includeArchived`, donc tu es conforme à *ta* spec. Mais le front Répertoire (ERP-164) réutilisera le composant « Voir les archivés » des autres écrans, qui envoie `archivedOnly` → le toggle sera silencieusement inopérant côté transporteurs. **Reco** : ajouter le paramètre `archivedOnly` (prioritaire sur `includeArchived`, comme `ProviderProvider`/`DoctrineProviderRepository`) pour rester l'exact « jumeau » annoncé du SupplierProvider.
$filters = $context['filters'] ?? [];
$includeArchived = $this->readBool($filters['includeArchived'] ?? false);
$archivedOnly = $this->readBool($filters['archivedOnly'] ?? false);
$search = $filters['search'] ?? null;
$certificationTypes = $this->readStringList($filters['certificationType'] ?? []);
@@ -65,11 +68,12 @@ final class CarrierProvider implements ProviderInterface
$includeArchived,
is_string($search) ? $search : null,
$certificationTypes,
$archivedOnly,
);
// Echappatoire ?pagination=false : collection complete (selects front).
if (!$this->pagination->isEnabled($operation, $context)) {
/** @var list<Carrier> $carriers */
// @var list<Carrier> $carriers
return $qb->getQuery()->getResult();
}
1
@@ -35,6 +35,7 @@ class DoctrineCarrierRepository extends ServiceEntityRepository implements Carri
bool $includeArchived = false,
?string $search = null,
array $certificationTypes = [],
bool $archivedOnly = false,
): QueryBuilder {
// Fetch-join de la SEULE relation ManyToOne qualimatCarrier (sur, pas de
// cartesien) pour exposer statut/date de validite QUALIMAT en liste sans
@@ -47,7 +48,11 @@ class DoctrineCarrierRepository extends ServiceEntityRepository implements Carri
;
// Pas de cloisonnement par site (§ 2.3) : referentiel global.
if (!$includeArchived) {
// Perimetre d'archivage : archivedOnly prioritaire sur includeArchived
// (jumeau de DoctrineProviderRepository — toggle « Voir les archives »).
if ($archivedOnly) {
$qb->andWhere('c.isArchived = true');
} elseif (!$includeArchived) {
$qb->andWhere('c.isArchived = false');
}