Aller au contenu

Conception du module "Jauges de places"

Ce document détaille la conception d'un module permettant de regrouper et de suivre les limites de ventes de plusieurs produits de manière transversale.

Objectifs

  • Regroupement : Créer des objets permettant de mutualiser les quotas de vente de plusieurs produits.
  • Suivi dynamique : Suivre les ventes en temps réel pour calculer les paliers de tarifs correspondants.
  • Intégration : S'intégrer aux flux de configuration existants (Template > Groupe de produits > Disponibilité de ventes).
  • Granularité : Permettre un paramétrage par catégorie de public (disponibilité de ventes), par catégorie de place et par configuration de stade.

Architecture Proposée

L'arborescence des objets se structure de la manière suivante :

  1. Objet Jauge : Défini au niveau du club.
  2. Objet JaugeCategoriePublic : Enfant de Jauge.
  3. Objet JaugeCategoriePlace : Enfant de JaugeCategoriePublic.
    • Comprend un compteur (Entier, optionnel, ≥ 0).
  4. Liaisons : Un générateur/parent de produit est lié à une Jauge. Ses enfants sont automatiquement liés aux JaugeCategoriePublic correspondantes. Les articles vendus sont ensuite décomptés des JaugeCategoriePlace rattachées.
  5. Spécificités par Stade : Pour chaque ConfigurationStade, on génère des ConfigurationJaugeCategoriePlace (copies des JaugeCategoriePlace), paramétrables de manière indépendante.

Logique d'Incrémentation et Intégrité des Données

Le système repose sur un mécanisme de propagation automatique de l'impact des ventes, basé sur la hiérarchie des objets et les points de contact entre événements.

1. Mécanisme de propagation (Vente active)

Lorsqu'un article est vendu (passage de la commande à l'état "payé"), le système exécute les étapes suivantes : 1. Incrémentation directe : Mise à jour du compteur de la jauge explicitement liée à l'article. 2. Incrémentation par propagation : Identification et mise à jour de toutes les jauges répondant aux critères cumulatifs suivants : * Même lignée : Partagent les mêmes ancêtres (Jauge mère, Catégorie de public, Catégorie de place). * Intersection d'événements : Possèdent au moins un match en commun avec le produit vendu.

2. Gestion des modifications structurelles (Calcul de Delta)

Toute modification de la configuration alors que les ventes sont ouvertes nécessite une synchronisation : * Cas concernés : Changement de la jauge d'un produit, introduction d'une nouvelle jauge en cours de saison, ou modification des matchs inclus dans un Pass/Formule. * Action : Déclencher un calcul de delta basé sur l'historique des ventes réelles pour réaligner les compteurs de toutes les jauges impactées par le changement de périmètre.

3. Conseils techniques de mise en œuvre

Pour garantir la fiabilité et les performances, les principes suivants sont recommandés :

  • Atomicité SQL : Ne pas charger les objets en mémoire pour les incrémenter. Utiliser des requêtes SQL directes (UPDATE ... SET counter = counter + 1) pour éviter les race conditions lors d'achats simultanés.
  • Transactions : L'ensemble des incrémentations (directes et propagées) doit être encapsulé dans une transaction unique pour garantir la cohérence (tout est mis à jour ou rien ne l'est).
  • Traitement Asynchrone pour les Deltas : Le recalcul des jauges lors d'un changement structurel peut être lourd. Il est préférable de l'exécuter via un Background Job (ex: Sidekiq) pour ne pas bloquer l'interface d'administration.
  • Indexation : Assurer une indexation performante sur les colonnes pivots (parent_id, match_id, type_jauge) pour que la recherche des jauges liées soit instantanée malgré le volume de données.

📋 Feuille de route d'implémentation (TODO)

1. Gestion des Jauges (Dashboard Admin)

  • Configuration des Jauges Mères :
    • Interface CRUD pour l'objet Jauge.
    • Gestion des relations avec les catégories de public (JaugeCategoriePublic).
  • Déclinaison par Catégories :
    • Gestion des JaugeCategoriePlace (liées aux catégories de public).
    • Paramétrage des quotas de base (tailles par défaut).
  • Spécification par ConfiguratonStade :
    • Interface de paramétrage fin pour les ConfigurationJaugeCategoriePlace au sein de chaque ConfigurationStade.

2. Module d'attribution et cycle de vie

  • Intégration aux Formulaires :
    • Ajout d'un sélecteur de jauge dans les formulaires de création/édition des produits et générateurs de produits.
  • Héritage et Génération :
    • Automatisation de l'attribution des jauges lors de la génération automatique des produits.
  • Gestion du Changement :
    • Mise en place des hooks de mise à jour lors de la modification d'un produit ou de son rattachement à une jauge (calcul du delta...).

3. Moteur de vente (Front-end & API)

  • Logique de Pricing :
    • Calcul dynamique des paliers tarifaires en fonction de l'état actuel de la jauge.
  • Flux de Vente :
    • Incrémentation : Mise à jour des compteurs lors de la validation de commande.
    • Contrôle de disponibilité : Vérification stricte des capacités lors de l'ajout au panier, de la finalisation du tunnel d'achat et pour l'affichage des jauges de disponibilité sur le site.

💡 Réflexions Métiers & Évolutions

Vers une structure de jauges "cross-catégories" ?

Question : Doit-on faire évoluer la structure vers un modèle plus flexible de type Jauge => JaugeItems avec une relation HABTM (Has And Belongs To Many) vers les CategoriePublic et CategoriePlace ?

Analyse : * Avantages : Cela permettrait de créer des jauges très spécifiques (ex: une jauge commune pour "Familles de joueurs" et "Licensiés" sur une ou plusieurs catégories de place données). * Complexité : La logique de propagation des ventes deviendrait plus complexe à calculer (plusieurs chemins possibles pour atteindre une ressource), à moins d'empecher les doublons au sein d'une même jauge (Pour une categorie de place et une catégorie de public données, impossible d'avoir une ambiguités de `JaugeItem)


Compte rendu de la réunion du 08/01/2026

  • Possibilité de propager les modifications du template de Jauge à ses enfants.
  • Ajout d'un 2eme compteur à l'ajout au panier (puis au retrait) afin de valider la disponibilité.
  • Création d'un script pour migrer les festivals => 1 Produit, 1 Jauge
  • Implémentation de la variante JaugeItem