Skip to content
04Étude de casSW · 04 sur 10

Une plateforme de chatbot multi-tenant pour concessionnaires automobiles, avec trois bases de données qui gagnent leur place.

Les concessionnaires avaient la donnée — inventaire vAuto, valorisations TradePending, fiches ChromeData — mais aucun moyen de l'exposer aux acheteurs au bon moment. Nous avons bâti un SaaS multi-tenant : un constructeur de flux visuel pour les concessionnaires, un widget de chat pour les acheteurs, trois bases de données en dessous.

ClientConfidentiel
Année2017 — 2019
Durée3 yrs
StackPHP · Laravel · MongoDB · MySQL · Elasticsearch · Redis
Hero image for enterprise-conversational-data-platformFig 01 · Hero

La donnée était là. Le chemin vers elle, non.

Un concessionnaire automobile porte beaucoup de données : inventaire en direct avec prix et disponibilité, fiches techniques liées aux VIN, valorisations de reprise qui changent au jour le jour, options de financement, créneaux d'atelier. Ces données étaient réparties entre vAuto pour l'inventaire, TradePending pour les devis de reprise, ChromeData pour les fiches techniques des véhicules, et le CRM propre à chaque concessionnaire. Rien de tout cela n'était exposé aux acheteurs au moment où ils décidaient.

La conversation d'achat — qu'est-ce qui entre dans mon budget, qu'est-ce que vous me donneriez pour ma reprise, pouvez-vous l'entretenir la semaine prochaine — se passait par téléphone ou dans le showroom, des heures ou des jours plus tard. Les concessionnaires perdaient des prospects qui n'obtenaient pas de réponse assez vite.

Le brief : poser une interface de chat sur le site de chaque concessionnaire, capable de répondre à ces questions en temps réel, connectée aux systèmes qui avaient déjà les réponses.

Un constructeur visuel pour les concessionnaires, un widget de chat pour les acheteurs.

La plateforme avait deux surfaces distinctes. Les concessionnaires utilisaient un constructeur de flux visuel dans l'administration — un éditeur de graphe à cartes où ils bâtissaient des flux de conversation en reliant des cartes de question, des branches de réponse et des cartes d'action : afficher l'inventaire, récupérer un devis de reprise, prendre un rendez-vous d'atelier, capter un prospect. Aucun code requis. Chaque concessionnaire composait son propre bot ; la plateforme gérait le rendu et le routage.

Les acheteurs voyaient un widget de chat intégrable sur le site du concessionnaire. Le widget faisait tourner les flux configurés, tirait l'inventaire en direct depuis vAuto, faisait remonter les valorisations de reprise TradePending en ligne quand un acheteur décrivait sa voiture actuelle, et captait les coordonnées au format ADF pour le CRM du concessionnaire. La conversation se façonnait autour de ce que le concessionnaire avait configuré et de ce que l'acheteur demandait.

La plateforme était multi-tenant dès le premier jour. Chaque concessionnaire avait sa propre configuration de bot, son propre graphe de flux, sa propre connexion à l'inventaire et au CRM. Un seul compte pouvait gérer plusieurs concessions. L'authentification, la facturation et la tenance vivaient dans MySQL ; tout le reste vivait dans les magasins qui lui convenaient.

F · 01Constructeur de flux visuel
Les concessionnaires bâtissaient des flux de conversation dans un éditeur de graphe à cartes — questions, branches de réponse, recherches d'inventaire, devis de reprise, capture de prospects. Aucun code requis. Chaque concessionnaire configurait son propre bot.
F · 02Flux d'inventaire vAuto
Une tâche de file adossée à Redis parsait les exports FTP de vAuto, mettait à jour les données produit MongoDB et ré-indexait Elasticsearch par concessionnaire. Les changements de flux étaient isolés à une seule tâche.
F · 03Intégration de reprise TradePending
Le widget de chat récupérait les valorisations de reprise depuis TradePending en ligne, faisant remonter un devis dans la conversation quand un acheteur décrivait son véhicule actuel.
F · 04Export de prospects ADF
Les coordonnées d'acheteur captées dans le chat étaient formatées en XML ADF et acheminées vers le CRM du concessionnaire. Le format standard du secteur signifiait aucune intégration sur mesure par concession.
F · 05Backend à trois bases de données
MongoDB pour les schémas de bot et d'inventaire en évolution, MySQL pour l'authentification et la facturation multi-tenant, Elasticsearch pour la recherche d'inventaire par concessionnaire. Chaque magasin possédait un seul rôle.
F · 06Suite de tests d'automatisation de navigateur
Laravel Dusk couvrait les flux de conversation complets de bout en bout. Les changements de type de carte et de schéma dans MongoDB ne cassaient pas les chemins du widget ; la suite de tests le détectait si tel était le cas.

Trois bases de données, chacune gagnant sa place.

La décision de faire tourner trois magasins en parallèle était délibérée et défendue dès le premier jour. La tentation, sur un projet comme celui-ci, est de tout normaliser dans un seul magasin et d'accepter la friction aux bords. Nous ne l'avons pas fait.

MongoDB détenait les configurations de bot et les flux de conversation — types de cartes, logique de branchement, options de réponse rapide, le schéma d'affichage d'inventaire en évolution. Ce schéma changeait à chaque sprint à mesure que l'ensemble des fonctionnalités grandissait. Une migration relationnelle à chaque ajout de type de carte aurait étranglé la livraison. MongoDB absorbait ces changements sans cérémonie.

MySQL gérait tout ce qui exigeait une intégrité transactionnelle : authentification, facturation et frontières de tenance des concessionnaires. Nous n'allions pas laisser la cohérence à terme approcher du contrôle d'accès ou de l'état des abonnements. Elasticsearch indexait chaque produit d'inventaire actif par concessionnaire, enrichi des données du flux vAuto et des offres et interactifs que chaque concessionnaire avait configurés. Quand un acheteur posait une question sur une voiture précise dans le chat, le widget interrogeait Elasticsearch — pas une table relationnelle. La qualité du rappel correspondait à ce que le cas d'usage exigeait.

Trois bases de données, ce n'est pas de la complexité — c'est de la précision. Un seul magasin tentant de faire les trois rôles aurait été le choix complexe.

L'intégration vAuto tournait comme worker de file dédié. vAuto publiait des fichiers d'inventaire par FTP ; une tâche de file Laravel adossée à Redis les récupérait, parsait le flux, mettait à jour MongoDB avec les nouvelles données produit, et ré-indexait l'inventaire affecté dans Elasticsearch. Chaque étape était isolée. Quand vAuto changeait un format de fichier, une tâche changeait, pas toute la stack. La suite de tests d'automatisation de navigateur en Laravel Dusk empêchait les flux de conversation complets de régresser à mesure que les types de cartes et les schémas évoluaient. 1 736 commits sur environ deux ans. L'architecture a tenu.

Deux ans en production ; zéro réécriture.

La plateforme a été livrée aux premiers concessionnaires fin 2017. La conception multi-base — qui avait ressemblé à de la complexité sur le diagramme d'architecture — a prouvé sa valeur en exploitation. Les défaillances restaient contenues dans leur couche. Un échec de parsing du flux vAuto n'affectait pas la facturation. Une ré-indexation Elasticsearch ne bloquait pas une conversation d'acheteur. Chaque magasin tombait en panne comme son type tombe en panne, et pas davantage.

L'adoption par les concessionnaires a tenu. Quand le widget pose des questions au lieu d'afficher un formulaire de contact, les acheteurs répondent. Le flux de reprise — interroger un acheteur sur sa voiture actuelle, récupérer une valorisation TradePending, l'afficher en ligne — tournait sans nécessiter aucun membre du personnel du concessionnaire.

Le projet s'est clôturé avec 708 fichiers source, une suite complète de couverture PHPUnit et Dusk, et une couche de données que l'équipe du client a elle-même étendue après la passation. Nouveaux types de cartes, nouveaux connecteurs d'intégration — ils les ont ajoutés sans nous. Trois bases de données faisant trois rôles, et aucune ne faisant celui d'une autre.

Outcome
Source files at handoff
708
Commits over active window
1,736
Years in production
2+
Post-handoff rewrites
0
NEXTÉtude de cas 05SW · 05 sur 10
Hospitality2019

Une console de réservations pour un opérateur balnéaire multi-sites. Aucun backend requis.