Aller au contenu

Pipeline de données catalogue

Objectif

Transformer des flux marchands hétérogènes en un catalogue cohérent, classifié et exploitable par les consommateurs de lecture sans reconstruire la logique métier dans le frontend.

Étapes

1. Import et staging

Les flux sont importés dans des structures intermédiaires. Cette couche conserve les données sources nécessaires aux traitements suivants.

2. Normalisation des offres

Le pipeline plugins/ccx-feeds-industrial/includes/pipeline/90-offers-norm.php produit la projection normalisée ccx_offers_norm_v2.

Cette étape normalise notamment :

  • la marque et le modèle ;
  • les titres ;
  • la catégorie et la verticale ;
  • l’état du produit ;
  • les prix, promotions et disponibilités ;
  • les attributs techniques ;
  • les images ;
  • les identités produit et variante ;
  • les indicateurs de classification, qualité et revue.

3. Classification

La classification utilise plusieurs résultats complémentaires :

  • spec_type_probable ;
  • vertical_id ;
  • spec_type_final ;
  • classifier_confidence ;
  • classifier_reason_primary ;
  • classifier_reason_codes ;
  • classification_rule_code ;
  • classification_stage ;
  • review_required ;
  • status et reject_code.

Une offre utilisable par les projections d’enrichissement doit notamment satisfaire :

vertical_id = <verticale>
AND review_required = 0
AND status = 'ok'
AND COALESCE(brand_norm, '') <> ''
AND COALESCE(title_clean, '') <> ''

4. Projection produit canonique de lecture

ccx_canonical_products_v1 agrège les offres normalisées par product_identity_key non vide.

Cette projection fournit notamment :

  • product_identity_key ;
  • ean_norm ;
  • canonical_slug ;
  • canonical_title ;
  • marque, modèle et image de lecture ;
  • compteurs d’offres et de marchands ;
  • prix minimum / maximum et économie ;
  • meilleure offre et meilleur marchand ;
  • calculated_at.

Elle est reconstruisible depuis ccx_offers_norm_v2. Elle n’est pas la Canonical Identity du Domain Core et ne doit jamais être réparée manuellement ligne par ligne pour créer une vérité concurrente.

Invariant d’intégrité CURRENT :

pour toute offre avec product_identity_key non vide
→ une ligne ccx_canonical_products_v1 de même product_identity_key doit exister

Le health check ccx health projections vérifie cet invariant avec le contrôle missing_canonical_product_identity.

5. Projection des modèles

ccx_product_models_v1 regroupe les offres normalisées autour d’une identité de modèle.

Les principaux champs sont :

  • vertical_id ;
  • brand_norm ;
  • model_norm ;
  • model_key ;
  • slug ;
  • compteurs d’offres ;
  • prix minimum et meilleures économies ;
  • image principale.

Exemple de clé :

smartphone|samsung|galaxy a16

6. Projection des spécifications

La reconstruction des spécifications suit ce chemin :

ccx_offers_norm_v2
    ↓
ccx_product_models_fetch_enrichment_offer_rows()
    ↓
ccx_product_models_collect_enrichment_groups()
    ↓
ccx_product_specs_build_row()
    ↓
replaceVerticalSpecifications()
    ↓
ccx_product_specs_v1

La reconstruction ne part donc pas uniquement de ccx_product_models_v1. Elle repart des offres normalisées éligibles, puis rattache les groupes aux modèles disponibles.

7. Projection des galeries

La galerie combine :

  • l’image principale du modèle ;
  • image_norm ;
  • image_alt_1 à image_alt_4 ;
  • image_gallery_json.

Le résultat est enregistré dans ccx_product_gallery_v1 avec un maximum d’images défini par le code.

Cycle de synchronisation CURRENT

La finalisation d’un run marchand réussi suit notamment :

upsert ccx_offers_norm_v2
        ↓
ccx_sync_refresh_product_projections(feed)
        ↓
refresh ccx_canonical_products_v1
        ↓
rebuild des projections Product Models des verticales concernées
        ↓
finalisation du run

Le refresh canonique est exécuté avant la chaîne Product Models. Un échec de refresh est traité comme un échec critique de finalisation et le run ne doit pas être déclaré réussi silencieusement.

Un replay d’offre en mode apply rafraîchit également la projection canonique après le commit de l’offre. Si ce refresh échoue, l’erreur est explicite et la récupération normale passe par un nouveau refresh/rebuild ; il ne faut pas corriger directement la table dérivée.

Rejouabilité

Les étapes sont conçues pour être relancées séparément. Une reconstruction des spécifications ne nécessite pas nécessairement un nouvel import complet. En revanche, lorsque les données amont ont changé, l’ordre logique CURRENT est :

normalisation
→ projection produit canonique
→ modèles
→ variantes / spécifications / galerie selon l’orchestrateur

La projection canonique CURRENT est reconstruite globalement à partir de toutes les identités présentes dans ccx_offers_norm_v2, même lorsqu’un seul feed déclenche le refresh. Cette stratégie privilégie aujourd’hui la convergence et la correction ; son coût à l’échelle est suivi comme dette technique.

Risques de divergence

Une projection peut présenter un nombre différent d’éléments de la projection précédente lorsque :

  • une offre n’est plus éligible ;
  • un modèle ancien reste présent ;
  • les regroupements ont changé ;
  • une reconstruction partielle a été exécutée ;
  • le modèle ne possède plus aucune offre normalisée valide ;
  • un refresh a échoué après modification de l’état amont.

Pour ccx_canonical_products_v1, un écart offres→canonical sur product_identity_key est une anomalie de cohérence et non un comportement normal à masquer dans le frontend.

Ces différences doivent être diagnostiquées avant de modifier un générateur, un renderer ou une ligne SQL manuellement.