Aller au contenu

Merchant Synchronization Playbook

Status: CURRENT + TARGET / OPERATIONS

Objet

Cette page définit la stratégie de synchronisation multi-marchands et distingue le scheduler CURRENT des évolutions Runtime cibles.

L'objectif industriel est de supporter plusieurs dizaines puis plusieurs centaines de marchands, avec plusieurs refreshs quotidiens, sans dupliquer le pipeline ni rendre WordPress propriétaire de l'exécution.

Principes invariants

  1. Un marchand possède une source, une configuration et un adapter, pas son propre moteur métier.
  2. Les données convergent vers un pipeline canonique commun.
  3. Une panne d'un marchand ne bloque pas les autres.
  4. Les traitements volumineux sont batchés et reprenables.
  5. Les mutations sont idempotentes ou protégées contre la double application.
  6. Les refreshs ciblent le périmètre réellement affecté lorsque cela est sûr.
  7. Le full reconciliation/rebuild reste disponible pour recovery et certification.
  8. Aucun scheduler ne contient mapping, classification, SQL métier, URL de source ou credentials.
  9. CCX_ACTIVE_FEEDS est l'autorité unique du périmètre marchand planifié ; systemd ne maintient aucune seconde liste.

Modèle logique

Generic scheduler
      ↓
active-feed use case
      ↓
canonical active feed registry
      ↓
FeedRun
      ↓
Download / source read
      ↓
Batches
      ↓
Canonical ingestion
      ↓
Normalization
      ↓
Classification / Identity / Quality si nécessaire
      ↓
Persistence
      ↓
Scoped projection refresh
      ↓
Cache/search invalidation ciblée

Isolation

Chaque run doit pouvoir être rattaché au minimum à merchant_id, feed_id, feed_run_id, batch_id lorsque le run est découpé et job_id lorsqu'une queue est utilisée.

Un run en erreur ne doit pas empêcher les autres feeds actifs d'être tentés. Le multi-runner CURRENT isole les exceptions par feed, poursuit la séquence et renvoie ensuite un échec agrégé.

Les limites de concurrence et la capacité DB restent à surveiller afin qu'un feed volumineux ne monopolise pas toutes les ressources.

Fréquence par type de donnée

La fréquence ne doit pas être pensée comme « rebuild complet X fois par jour ».

Donnée / traitement Stratégie cible
prix refresh fréquent et ciblé
disponibilité / stock refresh fréquent et ciblé
nouvelles offres plusieurs fois par jour selon source
changement produit traitement des produits impactés
classification uniquement si les preuves concernées changent
identity resolution uniquement pour périmètre affecté
projections scoped refresh après mutation
full reconciliation périodique / recovery
gros audits qualité périodes creuses ou jobs dédiés

La fréquence exacte dépend de la capacité mesurée du VPS et du volume de changements.

Batches

Un feed de plusieurs millions de lignes ne doit pas être un unique job monolithique.

FeedRun #92837
  batch 0001 : 1 - 5 000
  batch 0002 : 5 001 - 10 000
  ...

La taille optimale des batches est mesurée selon mémoire, débit DB, coût de normalisation et temps de reprise.

Idempotence et reprise

Après un crash, la plateforme doit savoir ce qui a déjà été appliqué, ce qui reste pending, ce qui peut être rejoué, ce qui a définitivement échoué et quelles projections restent à rafraîchir.

Un retry ne doit pas dupliquer une offre ni réappliquer une mutation déjà commitée.

Refresh incrémental

Le modèle cible est :

changed offers
   ↓
affected identities
   ↓
affected canonical products
   ↓
affected read projections

Le full rebuild doit rester disponible pour vérifier :

incremental final state == full rebuild final state

Des travaux de scoped refresh peuvent être certifiés sur des branches dédiées. Ils ne doivent être présentés comme CURRENT sur la branche de référence qu'après intégration et revalidation de cette branche.

CURRENT — scheduler générique via WP-CLI

Le Runtime courant utilise une seule autorité systemd :

ccx-active-feeds-sync.timer
    ↓
ccx-active-feeds-sync.service
    ↓
docker exec ccx-platform-worker
    ↓
wp ccx sync active-feeds
    ↓
ccx_sync_runner_run_feeds()
    ↓
CCX_ACTIVE_FEEDS

Il n'existe plus de timer CURRENT par marchand. Ajouter ou retirer un marchand planifié ne doit pas exiger de nouveau fichier systemd : le changement passe par l'autorité d'activation canonique, puis par le processus normal de configuration/déploiement.

La commande planifiée n'utilise pas --force.

Le chemin WP-CLI reste un adapter opérationnel CURRENT. La cible à long terme reste qu'un worker Platform puisse lancer le même use case sans charger WordPress.

Scheduling CURRENT

Le timer générique démarre quotidiennement à 03:15 UTC, avec Persistent=true et RandomizedDelaySec=10m. Les feeds actifs sont traités séquentiellement dans l'ordre fourni par le registry canonique.

Une erreur de résultat ou une exception sur un feed est agrégée comme échec mais n'empêche pas les feeds suivants d'être tentés. Le service sort non-zéro si au moins un feed échoue.

Le service générique n'utilise pas Restart=on-failure : une relance automatique de toute la séquence après un échec partiel ferait rejouer des feeds déjà réussis. Un retry doit être ciblé et explicite après diagnostic.

Interdit dans un scheduler : identifiant marchand codé en dur, URL avec credentials, téléchargement métier direct, SQL, mapping, classification, logique verticale ou refresh de projection implémenté localement.

Commandes CURRENT

Run générique planifié :

docker exec -i ccx-platform-worker \
  wp --allow-root --path=/var/www/html \
  ccx sync active-feeds

Run ciblé opérateur :

docker exec -i ccx-platform-worker \
  wp --allow-root --path=/var/www/html \
  ccx sync start --feed=<merchant>

Préconditions d'activation d'un marchand

Avant une première planification : source/configuration définie hors secrets Git, adapter/mapping certifié, fixtures représentatives, run manuel contrôlé, volume attendu documenté, erreurs/skips compris, identité/classification observées, projections cohérentes, retry/replay compris, isolation par rapport aux autres marchands vérifiée, monitoring lisible et rollback connu.

Validation CURRENT

Pour chaque feed actif :

docker exec -i ccx-platform-worker \
  wp --allow-root --path=/var/www/html \
  ccx sync status --feed=<merchant> --limit=1

docker exec -i ccx-platform-worker \
  wp --allow-root --path=/var/www/html \
  ccx sync doctor --feed=<merchant>

Puis valider les projections :

docker exec -i ccx-platform-worker \
  wp --allow-root --path=/var/www/html \
  ccx health projections

Ces commandes sont des adapters opérationnels CURRENT. Elles ne constituent pas la cible de dépendance du Core.

Métriques marchands

L'exploitation doit progressivement exposer par marchand : last_success, feed_age, run_duration, source_rows, processed_rows, changed_offers, rejected_offers, error_count, états identity/classification, projection_lag, queue_pending et retry_count.

Fairness et backpressure

À mesure que le nombre de marchands augmente, le Runtime doit gérer explicitement concurrence globale, concurrence par marchand, priorité, taille de batch, retries avec backoff, backlog, capacité DB et backpressure.

Le scheduler séquentiel CURRENT supprime la duplication systemd ; il ne prétend pas être la politique finale de concurrence pour des centaines de marchands. Cette évolution doit rester dans le Runtime, pas revenir sous forme de timers marchands.

Ajouter plus de workers n'est pas une solution correcte si MariaDB ou l'I/O est déjà le goulot.

Full reconciliation

Un traitement complet peut être programmé moins fréquemment pour détecter une disparition d'offre, réconcilier l'état incrémental, vérifier les invariants, rebuild les projections et certifier la convergence.

Ce mécanisme de sécurité complète l'incrémental ; il ne doit pas redevenir le chemin normal de chaque petite mise à jour.

Sécurité

Les credentials et URLs sensibles ne sont jamais commités dans Git ni copiés dans la documentation. Les commandes opérateur, logs et métriques doivent éviter de révéler des secrets.

Checklist

[ ] marchand identifié et configuré
[ ] secrets hors Git
[ ] adapter source isolé
[ ] pas de logique merchant dispersée dans le Core
[ ] fixtures / contract tests disponibles
[ ] run manuel validé
[ ] batch / retry / replay compris
[ ] projection health validée
[ ] métriques du marchand lisibles
[ ] CCX_ACTIVE_FEEDS cohérent
[ ] scheduler générique sans logique métier ni liste marchands
[ ] concurrence maîtrisée
[ ] rollback connu
[ ] documentation CURRENT/TARGET cohérente

Voir aussi