Les tables idtf_product / idtf_sync_log sont des referentiels DBAL bruts
(sans entite ORM, synchronises par app:idtf:sync). Sans exclusion du
schema_filter, doctrine:schema:update --force les droppe juste apres la
migration dans test-db-setup, cassant SyncIdtfCommandTest (relation
"idtf_product" does not exist). Meme correctif que QUALIMAT (#99).
- garde-fou anti-desactivation de masse : fetchRemote leve sur un payload
non-list (2xx inattendu) et la commande abandonne sans ecriture si aucune
ligne exploitable, au lieu de soft-delete tout le referentiel
- verrou consultatif pg_try_advisory_lock pour serialiser les runs (anti-overlap)
- deduplication par SIRET dans le mapper (rows_upserted = transporteurs distincts)
- upsert par paquets (INSERT groupe) au lieu d'un aller-retour par ligne
- migration des tables qualimat deplacee vers le namespace modulaire Transport
(+ enregistrement du path dans doctrine_migrations.yaml)
- tests : deduplication + abandon sur source vide
Remplace l'UA 'Starseed-ERP' par un UA navigateur neutre : évite les filtres anti-bot des sources (qualimat.org WordPress/WAF, icrt-idtf.com) sans révéler l'application.
Commande console app:qualimat:sync : récupère les opérateurs de transport agréés depuis l'API publique qualimat.org, normalise et synchronise une table référentielle (upsert sur le SIRET + soft-delete des absents + journal). Prévue pour un cron quotidien.
- migration : tables qualimat_carrier + qualimat_sync_log (COMMENT ON COLUMN sur chaque colonne)
- QualimatRowMapper : normalisation pure (SIRET sans espaces, date dd/mm/yyyy -> ISO, skip sans SIRET) + tests unitaires
- SyncQualimatCommand : options --file / --ppp / --dry-run, upsert DBAL transactionnel
- activation de framework.http_client
- tests fonctionnels de la commande (upsert/normalisation/journal/soft-delete)
Module Transport (ID transport, non requis) destiné à héberger les référentiels externes synchronisés par commandes console (codes IDTF ERP-149, transporteurs QUALIMAT ERP-39).
- TransportModule.php avec permissions() vide à ce stade
- activation dans config/modules.php
- layer Nuxt front minimal (pas d'écran ni d'item sidebar)