Aller au contenu

Product Projection

Status: CONTRACT

Rôle

La Product Projection est un modèle de lecture stable destiné aux consommateurs de la Platform : Frontend, adapters Runtime, API et futurs clients.

Elle ne constitue pas le Product Domain et ne devient jamais une nouvelle source de vérité métier.

Son rôle est de fournir une représentation déjà préparée pour la lecture afin d'éviter que le Frontend reconstruise des décisions métier à partir de données brutes.

Product Domain
      ↓
Canonical Identity
      ↓
Variantes / offres / attributs résolus
      ↓
Projection Builder
      ↓
Product Projection
      ↓
Frontend / API / adapters

Pourquoi cette projection existe

Sans Product Projection, chaque consommateur pourrait être tenté de :

  • reconstruire un titre ;
  • recalculer un prix ou une remise ;
  • choisir lui-même une offre ;
  • fusionner des offres marchandes ;
  • déduire une identité produit ;
  • interroger directement les données brutes du Pipeline.

Ces comportements dupliqueraient la logique métier et créeraient plusieurs vérités concurrentes.

La Product Projection sert donc de frontière de lecture commune.

Ce qu'elle reçoit

Une Product Projection est construite à partir de données déjà interprétées en amont, par exemple :

  • Canonical Identity ;
  • Product et variante déjà résolus ;
  • attributs normalisés ;
  • offres déjà préparées ;
  • résultats de qualité déjà calculés ;
  • données de navigation autorisées ;
  • médias déjà sélectionnés ou classifiés par les couches compétentes.

Le Projection Builder ne doit pas aller rechercher lui-même des données dans WordPress, dans un template, dans un endpoint HTTP ou dans un feed brut.

Ce qu'elle produit

Le contrat historique de cette projection couvre notamment les familles de champs suivantes.

Identité

  • projection_id
  • product_id
  • canonical_identity_id
  • slug

Affichage

  • title
  • short_title
  • subtitle

Attributs produit

  • brand
  • series
  • model
  • variant_label
  • product_family
  • product_type

Images

  • primary_image
  • thumbnail_image
  • gallery_images

Résumé commercial

  • best_offer_id
  • price
  • old_price
  • saving
  • saving_percent
  • currency
  • offer_count
  • merchant_count
  • availability

Résumé marchand

  • merchant_name
  • merchant_logo
  • merchant_url
  • category_id
  • category_label
  • breadcrumbs
  • canonical_url

Qualité

  • confidence_status
  • consistency_status
  • projection_status

Cette liste décrit le contrat documentaire historique de la projection. Lorsqu'un diagnostic dépend de la forme exacte du DTO actif, vérifier le type canonique sous src/Contracts/Projection et le code consommateur actuel.

Ce que le Frontend a le droit de faire

Le Frontend peut :

  • lire les champs exposés ;
  • choisir leur présentation ;
  • rendre du HTML ;
  • appliquer des règles purement visuelles ;
  • masquer un bloc vide lorsque le contrat d'affichage le permet.

Ce que le Frontend ne doit jamais faire

Le Frontend ne doit pas :

  • reconstruire le titre métier ;
  • reconstruire le slug ;
  • choisir la meilleure offre ;
  • recalculer une remise ;
  • fusionner des offres ;
  • inférer l'identité produit ;
  • interroger des feeds bruts ;
  • transformer unknown, ambiguous ou conflict en valeur inventée.

Si une information nécessaire manque, le problème doit être corrigé dans la couche productrice de la projection, pas dans le renderer.

Données manquantes

Une donnée absente doit rester explicitement absente ou porter l'état prévu par le contrat.

Le consommateur ne doit pas fabriquer une valeur métier de remplacement.

Exemples :

  • absence de old_price : ne pas inventer une remise ;
  • identité non résolue : ne pas choisir un modèle par heuristique Frontend ;
  • image incertaine : ne pas remplacer silencieusement la source ;
  • navigation inconnue : ne pas inventer une catégorie.

Déterminisme

À état amont identique et version de contrat identique, la Product Projection doit produire le même résultat logique.

Elle ne doit pas dépendre :

  • de l'ordre accidentel des lignes SQL ;
  • d'un cache implicite ;
  • de l'heure courante non injectée ;
  • du template ou de la route qui la consomme ;
  • d'un état global WordPress caché.

Reconstruction

Une Product Projection doit être reconstruisible depuis les données amont qui font autorité.

La projection persistée n'est pas la vérité métier. En cas de divergence, il faut :

  1. identifier la source canonique ;
  2. observer les entrées du Builder ;
  3. reconstruire ou simuler la projection ;
  4. comparer avec la projection persistée ;
  5. n'écrire qu'au travers du Write Service prévu ;
  6. vérifier le résultat côté lecture.

Frontière Builder / Write Service

Le Builder construit la représentation en mémoire.

Le Write Service persiste la représentation lorsque la projection est stockée.

Projection Builder
      ↓
Product Projection en mémoire
      ↓
Write Service éventuel
      ↓
Stockage de projection

Le Builder ne doit pas écrire directement en SQL.

Contrat minimal d'une carte produit

Le contrat historique indique qu'une carte produit peut être rendue avec :

  • title ;
  • primary_image ;
  • price ;
  • old_price ;
  • saving_percent ;
  • merchant_name ;
  • canonical_url.

Cette règle signifie que le composant d'affichage ne doit pas recalculer d'information métier supplémentaire.

Diagnostic

Si une carte ou une page produit affiche une mauvaise valeur, vérifier dans cet ordre :

  1. la Canonical Identity est-elle correcte ?
  2. les attributs et variantes amont sont-ils corrects ?
  3. l'offre retenue en amont est-elle correcte ?
  4. le Builder construit-il la bonne valeur ?
  5. la projection persistée est-elle à jour ?
  6. l'adapter transmet-il le bon DTO ?
  7. le Frontend affiche-t-il fidèlement la valeur reçue ?

Ne pas corriger le Frontend si l'erreur provient de la projection ou de l'amont métier.

Invariants

  1. La Product Projection est une vue dérivée.
  2. Elle ne crée aucune vérité métier.
  3. Le Frontend consomme, il ne recalcule pas.
  4. Les données manquantes restent explicites.
  5. Le résultat est déterministe et reconstruisible.
  6. Le Builder ne persiste pas directement.
  7. Les écritures passent par un Write Service explicite lorsqu'elles existent.

Voir aussi