Bot de vente, tableau de bord d’administration et support IA

Boutique de guides vendus par bot de messagerie, back-office web et assistant de support qui cherche dans les guides avant de répondre.

Année
2026
Type
Projet personnel
Domaine
Développement
Période
mai – août 2026
Stack
TypeScript, Node.js, discord.js, Fastify, SQLite, Drizzle ORM, Next.js, React, NextAuth, zod, Vitest
Page Overview du back-office : barre latérale de navigation à gauche (sections Helper Bot, Sales Bot, Système), deux rangées de cartes d’indicateurs du bot d’assistance et du bot de vente, puis les courbes des sessions et du revenu sur trente jours.
Vue d’ensemble — indicateurs des deux bots, données de démonstration39 écransOuvrir la visite

En bref

Problème
Vendre mes guides par bot demande de tenir ensemble stock chiffré, paiements venus de plusieurs canaux, livraison et support, sans jamais livrer deux fois ni laisser une question sans réponse.
Ce que j’ai réalisé
Trois services TypeScript sur une base SQLite partagée : un bot de vente, un assistant de support adossé aux guides, et un back-office web à rôles, audit et 2FA.
Résultat
La réservation de stock et l’anti-rejeu des paiements tiennent dans une requête et un index ; l’assistant indexe les guides en fragments et trace chaque réponse avec son coût en jetons.
Rôle
Conception, architecture, orchestration et vérification.
Équipe
Projet individuel
Statut
Terminé
Confidentialité
Certains détails sont volontairement anonymisés.

Le back-office, écran par écran

Captures d’un serveur de démonstration alimenté par des données entièrement factices : aucun client réel, aucune boutique réelle, aucune commande réelle n’y figure.

01 sur 04

Commandes — liste filtrable et temps réel

Chaque commande avec son client, son guide, son prix, l’état du paiement et de la livraison ; filtres par paiement, livraison, méthode, origine, guide et fondateur.

Accès

  • Page de connexion sur fond sombre : logo « Bot Dashboard », carte « Connexion » avec les champs Email et Mot de passe, un bouton « Se connecter » et, sous un séparateur « ou », un bouton de connexion par la plateforme du bot., ouvrir la capture complète
    Connexion L’accès au back-office passe par un e-mail et un mot de passe, ou par le compte de la plateforme du bot.

Vue d’ensemble

  • Page Overview : barre latérale de navigation, deux rangées de quatre cartes d’indicateurs (sessions, temps de résolution, satisfaction ; revenu, commandes, stock, clients), deux courbes « Sessions sur 30 jours » et « Revenu sur 30 jours », puis un anneau « Répartition des résolutions » avec sa légende., ouvrir la capture complète
    Vue d’ensemble — indicateurs des deux bots Indicateurs du bot d’assistance et du bot de vente, courbes des sessions et du revenu sur un mois, répartition des résolutions.

Ventes

  • Tableau des commandes : barre de recherche et six filtres déroulants, puis une ligne par commande avec référence, identifiant client, guide (Pack Cloud, Pack Streaming, Pack Musique), quantité, prix, origine, badges de paiement (Confirmé, En attente, Échec, Remboursé) et de livraison, code promo et date., ouvrir la capture complète
    Commandes — liste filtrable et temps réel Chaque commande avec son client, son guide, son prix, l’état du paiement et de la livraison ; filtres par paiement, livraison, méthode, origine, guide et fondateur.
  • Fiche d’une commande : quatre cartes (Client, Produit, Paiement / Livraison, Réception), liste des exemplaires livrés avec un bouton « Révéler (vérif. client) » chacun, frise « Timeline paiement », bloc « Paiements reçus » avec barre de progression complète, et l’e-mail de paiement rapproché en bas., ouvrir la capture complète
    Fiche commande — paiement, livraison et révélation du guide livré Client, produit, paiement et compte de réception en tête ; chaque exemplaire livré se révèle après vérification, et l’e-mail de paiement rapproché est joint.
  • Page Stock, onglet Vue d’ensemble : trois cartes Pack Cloud, Pack Musique et Pack Streaming, chacune avec une jauge « Disponible » et les compteurs Dispo, Réservés et Livrés., ouvrir la capture complète
    Stock — disponibilité par guide et variante Pour chaque guide, le disponible, le réservé et le livré, avec une jauge de disponibilité.
  • Page Variantes pour le guide Pack Cloud : tableau avec une ligne de prix de base et deux variantes actives, colonnes Stock, Prix (deux paliers), Source, Promos, Expiration et un bouton Éditer par ligne., ouvrir la capture complète
    Variantes — paliers de prix et contenu produit Prix de base et prix par variante d’un guide, avec paliers dégressifs, stock, source et expiration ; seule l’édition des prix se fait ici.
  • Page Revenus : filtres par méthode de paiement et par compte de réception, quatre cartes (Aujourd’hui, Cette semaine, Ce mois, Panier moyen), courbe « Revenu cumulé (90 jours) » et histogramme « Revenu par méthode de paiement (mois) »., ouvrir la capture complète
    Revenus — séries temporelles et répartition Revenu du jour, de la semaine, du mois et panier moyen, filtrables par méthode et compte de réception ; courbe cumulée et histogramme par méthode.
  • Page Analytics — Sales Bot : dix cartes d’indicateurs, courbe du revenu par jour, histogramme empilé des commandes par jour par statut, deux anneaux (méthodes de paiement, paiements par fournisseur), barres du revenu par guide, top clients, webhooks reçus par jour et tableau des derniers e-mails non rapprochés., ouvrir la capture complète
    Statistiques de vente Conversion, paiements en attente, taux de rapprochement des webhooks ; revenu et commandes par jour, répartition par méthode, par guide et par fournisseur ; derniers e-mails non rapprochés.

Clients et paiements

  • Page Clients : filtres (identifiant, minimum de commandes, minimum de revenu, accès actif, tri), puis tableau trié par revenu avec identifiant, nombre de commandes, revenu total, dernière commande, date d’inscription et pastille d’accès actifs., ouvrir la capture complète
    Clients — segmentation et historique Un client par ligne : commandes, revenu total, dernière commande, ancienneté et accès actifs ; filtres par minimum de commandes et de revenu.
  • Fiche du client Nour : avatar, total dépensé et accès actifs, bloc « Accès aux guides » (Pack Streaming et Pack Musique, actifs), puis tableau de ses commandes avec référence, guide, quantité, prix, paiement, livraison et date., ouvrir la capture complète
    Fiche client — historique d’achat et fidélité Dépenses et accès actifs en tête, guides accordés avec leur date, puis l’historique complet des commandes du client.
  • Page Comptes de paiement : bandeau Sécurité, cartes de synthèse (comptes actifs, dernier paiement reçu, compteurs par fournisseur), puis tableau des comptes avec fournisseur, libellé, adresse masquée, cible de courrier, titulaire, statut, et boutons Désactiver, Révéler, Modifier., ouvrir la capture complète
    Comptes de réception — multi-fournisseurs Les comptes qui reçoivent les paiements, par fournisseur, avec adresse masquée, cible de courrier entrant, état et dernière utilisation ; chaque action est auditée et demande une ré-authentification.

Fondateurs

  • Page Fondateurs : tableau du règlement en attente (Nadia, Ruben, Theo avec part, reçu, théorique, écart, statut), historique des règlements, encart explicatif, quatre cartes de totaux, détail par fondateur avec répartition par méthode, deux transferts à effectuer, et histogramme empilé des revenus par fondateur sur 90 jours., ouvrir la capture complète
    Fondateurs — règlement des parts Règlement entre co-fondateurs : part de chacun, reçu, théorique et écart, historique des règlements, détail par méthode, transferts à effectuer et revenus par fondateur sur trois mois.
  • Page Stats avancées — Fondateurs × Méthodes : trois cartes (revenu total, fondateurs actifs, méthodes en usage) et un tableau croisé avec une ligne par fondateur, une colonne par méthode de paiement, et une ligne de total., ouvrir la capture complète
    Fondateurs — statistiques avancées Tableau croisé du revenu confirmé par fondateur et par méthode de paiement depuis le dernier règlement.
  • Page Overrides par guide : tableau des overrides actifs (guide Pack Cloud, fondateur, part en pourcentage, date, bouton Supprimer) et formulaire « Ajouter / modifier un override » avec guide, fondateur et part., ouvrir la capture complète
    Fondateurs — surcharges de parts par produit Une part spécifique peut être fixée pour un couple guide / fondateur ; elle s’applique aux commandes futures.

Fidélisation

  • Page Codes promo : tableau de quatre codes (réduction en pourcentage, utilisations sur un plafond, revenu impacté, économies, guide, expiration, statut Actif ou Désactivé) avec boutons Désactiver et Supprimer., ouvrir la capture complète
    Codes promo Chaque code avec sa réduction, ses utilisations, le revenu impacté, les économies accordées, son expiration et son statut.
  • Page Campagnes auto : filtres Statut et Type, puis liste de trois règles (palier fidélité, relance, réveil des clients dormants) avec déclencheur, type, condition, action, statut Active ou En pause, dernière exécution et compteur d’attributions., ouvrir la capture complète
    Campagnes automatiques de fidélisation Règles de cadeau automatique : déclencheur, type, statut, dernière exécution et nombre d’attributions.
  • Fiche de la campagne « Relance 2e achat » : carte Configuration (statut, cap par jour, dates), carte JSON brut (condition et action), et tableau « Historique des cadeaux » avec bénéficiaire, statut Livré, Échec ou En attente, commande et dates., ouvrir la capture complète
    Campagne — règle de déclenchement et attributions Configuration d’une règle, son JSON brut de condition et d’action, et l’historique des cadeaux attribués, livrés ou échoués.
  • Page Avis clients : bloc « Relance d’avis post-livraison » avec interrupteur activé et avertissement sur le salon manquant, puis Réglages : identifiant du salon, délai après livraison, délai avant rappel, message personnalisé et bouton Enregistrer., ouvrir la capture complète
    Avis clients — sollicitation post-livraison Après chaque livraison, le bot invite le client à laisser un avis puis le relance une fois ; salon, délais et message sont réglables.

Telegram

  • Page Support : bloc « Système de tickets Support » avec interrupteur et encart « Supergroupe Support (lecture seule) », puis liste des catégories (livraison, compte, paiement, remboursement, pré-achat, autre), chacune avec clé, libellé, réponse FAQ et deux interrupteurs., ouvrir la capture complète
    Telegram — support et tickets Système de tickets du bot de vente : activation, supergroupe de support, et catégories avec réponse FAQ, demande de référence et état.
  • Page Onboarding (tenants) : carte « Lien d’invitation (deeplink) » avec bouton « Générer un deeplink », et carte « Liaisons tenant » vide affichant « Table indisponible »., ouvrir la capture complète
    Telegram — parcours d’accueil Génération d’un lien d’invitation signé qui lie un utilisateur à une boutique à la première ouverture ; le registre des liaisons est en lecture seule.
  • Page Annonces : éditeur de texte avec boutons de mise en forme, champ de lien, boutons Texte, Citation, Photo, Boutons, interrupteur « Désactiver l’aperçu de lien », et à droite l’aperçu vide, le compteur de caractères, l’état « Message valide » et le bouton Publier., ouvrir la capture complète
    Telegram — annonces Composition d’un message riche (texte, citation, photo, boutons) avec aperçu ré-assaini avant publication.
  • Page Observabilité : cinq cartes d’indicateurs (accès canaux actifs, opt-outs DM, outbox en attente, outbox échouées, incidents failover en cours)., ouvrir la capture complète
    Telegram — observabilité Indicateurs en lecture seule de la boutique : accès canaux actifs, refus de messages privés, file de notifications en attente ou en échec, incidents de bascule.
  • Page Drops : texte d’explication, compteur de drops à zéro et carte vide « Table indisponible »., ouvrir la capture complète
    Telegram — drops et récompenses Drops promo de canal : les premiers membres qui réclament reçoivent un code à usage unique ; aucun drop n’existe encore.
  • Tableau des commandes de la boutique Aurora Shop : barre de recherche, six filtres, puis une ligne par commande avec référence, identifiant client, guide (Aurora Pro, Aurora Starter), quantité, prix, origine, badges de paiement et de livraison, code promo et date., ouvrir la capture complète
    Commandes de la boutique Telegram La liste des commandes d’une seconde boutique : mêmes filtres, produits et codes promo propres, recherche par référence ou identifiant client.

Assistant IA

  • Page Sessions : filtres par guide, état, catégorie et résolution, puis tableau avec identifiant de session, utilisateur, guide, catégorie, badge d’état (Résolu, Escaladé, Diagnostic, Qualification, IA active, Accueil), résolution, durée, note de feedback et date., ouvrir la capture complète
    Assistant IA — sessions de support Chaque session d’assistance avec son guide, sa catégorie, son état, son mode de résolution, sa durée et la note laissée.
  • Fiche d’une session : quatre cartes (Guide, État Résolu, Durée, Tokens IA avec entrées et sorties), bloc Feedback avec note et commentaire, puis transcript de quatre messages alternant Utilisateur et Assistant, chaque réponse du bot portant son temps de génération et sa source., ouvrir la capture complète
    Conversation d’assistance — transcription et coût en jetons Guide, état, durée et jetons consommés en tête, retour de l’utilisateur, puis la transcription message par message avec le temps de réponse de l’assistant.
  • Page Analytics — Helper Bot : neuf cartes d’indicateurs, courbe des sessions par jour, anneau de répartition des résolutions, barres des sessions par guide, top catégories, carte de chaleur des heures de pointe par jour de la semaine et courbe de l’évolution de la satisfaction., ouvrir la capture complète
    Assistant IA — statistiques Sessions par période, part résolue sans IA, temps moyen, jetons consommés, satisfaction ; sessions par jour et par guide, répartition des résolutions, heures de pointe et évolution de la satisfaction.
  • Page Guides : trois cartes (Pack Cloud, Pack Musique, Pack Streaming) avec version, description courte et badges chunks, arbre, rôle et accès., ouvrir la capture complète
    Assistant IA — guides indexés Chaque guide indexé avec sa version, sa description, le nombre de fragments, d’arbres de diagnostic, de rôles et d’accès.
  • Fiche du guide Pack Streaming : onglets Chunks, Diagnostic, Rôles, Prompt, Stats ; liste dépliable des fragments « section 1 » et « section 2 » par catégorie (Appareils, Connexion, Livraison, Paiement, Qualité de flux, Remplacement), chacun avec son nombre de caractères., ouvrir la capture complète
    Guide — fragments indexés et arbre de diagnostic Les fragments indexés d’un guide, classés par catégorie, avec leur taille ; onglets Diagnostic, Rôles, Prompt et Stats.
  • Page Knowledge Base : champ de recherche, filtres Guide et Statut, puis tableau des entrées avec identifiant, guide et catégorie, problème, solution tronquée, utilisations, note de feedback, statut Actif et date., ouvrir la capture complète
    Base de connaissance Une entrée par problème connu avec sa solution, son guide, sa catégorie, son nombre d’utilisations, sa note et son statut ; recherche par mot-clé.
  • Page Incidents : encart « Incidents actifs » (deux lignes, Connexion et Qualité de flux, avec description, reports et date) et tableau Historique avec identifiant, catégorie, statut Actif ou Résolu, reports, durée, dates de détection et de résolution., ouvrir la capture complète
    Incidents détectés Incidents actifs détectés à partir des signalements, avec description et nombre de reports, puis l’historique avec durée et date de résolution.
  • Page Feedbacks : quatre cartes (avis ce mois, positifs, négatifs, avec commentaire), filtres Guide et Score, puis tableau des avis avec date, utilisateur, guide, score sur cinq, commentaire et lien vers la session., ouvrir la capture complète
    Retours utilisateurs Avis laissés après chaque session : part de positifs, de négatifs, avec commentaire ; chaque ligne renvoie à sa session.

Exploitation

  • Page Alertes : compteur d’alertes non lues, boutons Actualiser et Tout marquer lu, puis six cartes d’alerte avec titre, badge warning ou critical, clé technique, description, date et coche de lecture., ouvrir la capture complète
    Alertes Notifications automatiques classées par gravité : stock bas ou épuisé, commandes en attente, quota anti-fraude, erreurs IA, bot hors ligne.
  • Page Utilisateurs dashboard : tableau de quatre comptes (nom, e-mail, rôle Manager, Viewer, Admin ou Super Admin, état du 2FA, statut, dernière connexion, menu d’actions) et carte « Plateforme de la boutique » avec sélecteur et bouton Enregistrer., ouvrir la capture complète
    Utilisateurs — rôles et isolation par boutique Comptes du back-office avec e-mail, rôle, 2FA, statut et dernière connexion ; la plateforme de chaque boutique est épinglée dans le registre.
  • Page Configuration : carte Guild (nom, setup, AI tier, version de guide), tableau Helper Bot de deux clés et long tableau Sales Bot de clés avec leurs valeurs, dont des grilles de prix en JSON., ouvrir la capture complète
    Configuration Vue en lecture seule des clés de configuration des deux bots : méthodes de paiement, minimums, grilles de prix par palier, relance d’avis, alertes de stock.
  • Page Logs : barre de filtres (bot, domaine, boutique, niveau, recherche, interrupteur Auto-scroll) et zone de logs vide affichant « Aucun log »., ouvrir la capture complète
    Logs applicatifs Visualisation en temps réel des logs des bots, filtrée par bot, domaine, boutique et niveau, avec défilement automatique.

Audit et sécurité

  • Page Audit trail : long tableau d’actions avec date, administrateur, badge d’action (proposition de règlement, export CSV, annulation de commande, mise à jour d’utilisateur, connexion…), ressource, détails en JSON et adresse IP, puis pagination., ouvrir la capture complète
    Journal d’audit Chaque action d’administration horodatée avec son auteur, sa ressource, ses détails et l’adresse d’origine.
  • Page Audit log : filtres (action, identifiant utilisateur, dates ISO), boutons Filtrer et Exporter CSV, et carte « Événements » vide affichant « Aucun événement pour ces filtres »., ouvrir la capture complète
    Audit de sécurité Surface des événements de sécurité réservée au super-administrateur : filtres par action, utilisateur et période, export CSV.
  • Page Paramètres, onglet Profil : champs Nom affiché et Email pré-remplis, champs Mot de passe actuel et Nouveau mot de passe vides, bouton Enregistrer ; onglet « Sécurité (2FA) » à côté., ouvrir la capture complète
    Paramètres du compte et 2FA Profil du compte connecté (nom affiché, e-mail, changement de mot de passe) et onglet de sécurité pour la double authentification.

01 sur 01

Commandes — liste filtrable et temps réel

Sommaire7 sections

Contexte

Projet personnel mené de mai à août 2026 : une boutique de mes propres guides numériques, vendus par bot de messagerie et administrés depuis un back-office web. Dans la boutique, un guide est une famille de produits : il regroupe plusieurs pièces d’un même lot, que l’acheteur choisit parmi ses variantes. Trois services TypeScript partagent un seul fichier SQLite en mode WAL : le bot de vente, l’assistant de support et le dashboard Next.js. La boutique vend par un bot Telegram ; le code est né sur Discord, et la version Telegram tourne comme quatrième service depuis un dépôt frère, sur la même base et le même back-office. Seul sur le projet, j’ai vérifié chaque livraison par le typage et par 307 fichiers de tests. Le projet est terminé depuis fin août : je n’y apporte plus que des correctifs et des vérifications, sans nouvelle fonctionnalité majeure.

Le problème

Pour chaque vente, le bot réserve un lot de stock chiffré, attend un paiement venu de l’un des canaux, puis livre le guide par message privé. Un virement ne porte pas de référence de commande : deux commandes au même prix sont indiscernables. Une ligne de stock peut partir deux fois si la livraison relit le stock par acheteur et non par commande : c’est arrivé une fois. Côté support, une question mal formulée échappe à une recherche par termes exacts.

Architecture et décisions

Dans la base commune, le bot de vente et l’assistant ont des tables disjointes : commandes et stock pour le premier, guides, sessions et connaissance pour le second. Le stock est chiffré en AES-256-GCM, clé dérivée par scrypt, dans un format d’enveloppe commun au bot et au dashboard. Le dashboard lit sur une connexion WAL en lecture seule, sans jamais bloquer sur une écriture du bot.

Un dépôt séparé porte une autre version du même back-office. Une seule table de transitions y décrit les machines à états des commandes et des paiements ; celle des commandes est à sens unique. Les montants y sont des entiers de centimes. Les écritures monétaires y passent par des transactions BEGIN IMMEDIATE, verrouillées en écriture dès l’ouverture. Des triggers SQLite y rendent le journal d’audit immuable. L’anti-rejeu figure parmi les invariants de son schéma. À la différence de la version décrite plus haut, le bot et le dashboard n’y partagent ni format d’enveloppe ni dérivation de clé ; un test de contrat a été écrit pour déchiffrer côté bot ce que chiffre le dashboard.

Stock et paiements

La réservation est un seul UPDATE … RETURNING : il réserve les lignes disponibles du guide et de la variante demandés et renvoie exactement celles qu’il a prises. Une ligne ne peut être livrée qu’après avoir été réservée. Depuis l’incident, la livraison relit les lignes par référence de commande.

Les paiements entrent dans une boîte de réception en base, puis un worker les apparie aux commandes par un score : confirmation automatique à partir de 0,8, revue manuelle à partir de 0,6, refus au-delà de 2 % d’écart de montant. Pour les virements, un sel de −5 à +5 centimes rend chaque total unique parmi les commandes en attente de paiement. La confirmation d’un virement exige un montant exact, un nom d’expéditeur reconnu et un candidat unique. Un index unique sur méthode et référence de paiement interdit de rejouer un paiement sur deux commandes.

Assistant de support, indexation et diagnostic

Une session traverse des états : accueil, diagnostic, qualification, IA active, puis résolu ou escaladé. Le diagnostic est un arbre de questions par guide et par catégorie, à feuilles de réponse ou d’escalade. Sinon, l’IA répond à partir des guides découpés en fragments versionnés et hachés. La recherche est hybride : BM25 sur un index FTS5 pour les termes exacts, cosinus sur des embeddings pour le sens, fusionnés par Reciprocal Rank Fusion ; sans vecteurs, le lexical seul sert.

Chaque message garde ses jetons d’entrée et de sortie et sa latence ; la fiche de session en fait la somme.

Une résolution devient un candidat pour la base de connaissance, dédupliqué par hachage, qu’un humain approuve ou rejette. Un incident s’ouvre quand cinq utilisateurs distincts signalent la même catégorie en quinze minutes, seuils réglables par boutique.

Exploitation, rôles, audit et 2FA

Quatre rôles ordonnés : super-administrateur, administrateur, gestionnaire, lecteur. L’isolation par boutique se tranche côté serveur, dans une table d’attributions. Le cookie de boutique choisit la boutique courante parmi celles attribuées au compte ; un cookie modifié n’ouvre l’accès à aucune autre. La connexion combine mot de passe haché par bcrypt et TOTP ; cinq échecs verrouillent le compte quinze minutes, et un secret 2FA en attente d’activation expire en dix minutes. Les actions sensibles (révéler un lot, supprimer, exporter) exigent une ré-authentification : un jeton de cinq minutes dans un cookie httpOnly, lié à l’utilisateur et à son IP. Chacune écrit dans le journal d’audit l’utilisateur, l’action, la ressource, un détail plafonné à 8 Ko et l’IP.

Le monitoring alerte, sans doublon, sur un stock à cinq lots ou moins, une commande en attente depuis une heure ou un bot silencieux depuis cinq minutes.

Ce que j’ai appris, ce que je referais

La réservation du stock repose sur un UPDATE conditionnel et l’anti-rejeu des paiements sur un index unique : la base de données tient ces deux garanties. L’incident de double livraison venait d’une requête correcte mais mal bornée.

La liaison du jeton de ré-authentification à une action précise est codée mais optionnelle : un jeton vaut cinq minutes pour toutes les actions. L’isolation stricte reste derrière un drapeau, avec un repli « toutes les boutiques » pour un compte sans attribution. Je câblerais la liaison par action et j’activerais l’isolation stricte par défaut. Le module d’achat dépasse 8 000 lignes ; je le découperais avant toute nouvelle fonctionnalité.