Passer au contenu principal
La couche décision est le moteur de recommandation de Solya. Elle s’exécute quotidiennement sur la data platform (Databricks) et transforme l’état brut de l’inventaire en recommandations classées et explicables — combien d’unités réassortir, quelle remise appliquer, quoi transférer entre magasins — que l’app surface dans les alertes, les plans, les tâches et les workflows. C’est un pipeline en trois étapes. Chaque étape est une table de la couche gold, calculée dans l’ordre :
  1. gold.decision_context — une ligne de snapshot consolidée par position (stock, marge, prévision, clés de dimension).
  2. gold.decision_vector — des scores de risque/urgence par domaine dérivés du contexte (urgence de réassort, risque de rupture, surplus/déficit, urgence de transfert…).
  3. gold.action_vector — la recommandation résolue (une quantité ou une remise) plus un snapshot enrichi du « pourquoi », dérivés des scores.
L’app lit l’action_vector précalculé (et les scores decision_vector sous-jacents) via Postgres et les utilise pour pré-remplir les plans, matérialiser les tâches, piloter les stratégies de workflow par score, et attribuer chaque article recommandé à sa source.

Les deux vecteurs, en une phrase

  • Un vecteur de décision répond à « à quel point cette position est-elle risquée / urgente ? » — des scores bruts dans [0, 1], sans unité.
  • Un vecteur d’action répond à « que faut-il donc faire ? » — une quantité ou un pourcentage de remise concrets, avec une confiance et une explication.
Le vecteur de décision est en amont ; le vecteur d’action est la forme résolue sur laquelle l’app agit. La résolution est faite par des « cœurs de résolution » partagés que le batch quotidien et la simulation à la demande de l’app appellent tous deux — garantissant que les valeurs précalculées correspondent à ce qu’une simulation interactive produirait.

Grain — variante × magasin, sans axe taille

Chaque étape est clé sur (organization_id, variant_id, shop_id, snapshot_date) — et, à partir du vecteur de décision, un axe domain. Il n’y a délibérément pas d’axe size : decision_context agrège chaque entrée de scoring sur size_taxonomy_id, donc les recommandations sont au niveau variante et l’app agrège les tailles pour l’affichage. (Le dimensionnement par taille — p. ex. la répartition par courbe de tailles du réassort — se fait plus tard, dans l’app, à l’ajout des articles au plan.)

Snapshots quotidiens et idempotence

Chaque table est un snapshot quotidien. Les writers utilisent MERGE sur la clé primaire, donc :
  • relancer un build le même jour calendaire met à jour les lignes en place (un no-op à l’octet près si les entrées sont inchangées — le scoring est déterministe) ;
  • différents domaines pour le même (variant, shop, snapshot_date) coexistent (valeurs de domain distinctes) ;
  • les tranches quotidiennes antérieures sont préservées (decision_context conserve une fenêtre de rétention de 90 jours).
Les tables de la couche décision sont répliquées vers Lakebase Postgres (<env>.gold_lakebase.*) via une sync CDC déclenchée, donc l’app les lit en Postgres à faible latence au grain variante / produit / marque.

Les trois domaines de décision

DomaineQuestionScores du vecteurAction recommandée
restockAllons-nous être en rupture ?restock_urgency, stockout_risk, overstock_riskrecommended_qty (unités à réassortir)
rebalanceLe stock est-il dans le mauvais magasin ?surplus_score, deficit_score, transfer_urgency, surplus_units, deficit_unitsrecommended_qty (unités à transférer)
markdownFaut-il démarquer ?markdown_score + fraction de remise (réutilise les slots restock)recommended_discount_pct
Les valeurs de domaine sont en minuscules partout dans la couche gold ("restock", "rebalance", "markdown"). L’app les reflète dans la constante DecisionDomain.

À lire ensuite

Contexte de décision

La table d’entrée fondatrice — ses sources, ses colonnes, et les slots toujours-NULL en v1.

Vecteur de décision

La couche de scoring — formules par domaine, pondérations, et la porte des actions.

Vecteur d'action

La couche de résolution — comment les scores deviennent quantités et remises, avec confiance.

Consommation par l'app

Comment l’app Next.js lit, filtre, attribue et agit sur les vecteurs.