Aller au contenu

← TravauxProduit indépendant · temps réel, multi-instance

Salle de vente en direct de Maison Dlala, vue acheteur

Maison Dlala : des enchères en direct où le serveur a toujours raison

Une place de marché d'enchères en quatre langues, dont l'arabe : offres idempotentes dans une seule écriture atomique, horloge serveur, salles en direct réparties sur plusieurs instances.

Vitrine privée, v2.6 — maisons, lots et enchérisseurs fictifs, paiements simulés

Rôle
Fondateur — produit, architecture, validation, mises en production
Période
2025 — 2026
Statut
En ligne — maisondlala.com
Outils
Next.jsTypeScriptExpressMongoDBRedisSocket.IOLiveKit

01Vue d'ensemble

Vendre à distance des objets de valeur, en direct, à des acheteurs qui doivent avoir confiance dans chaque enchère : même prix pour tout le monde, même horloge, aucune offre comptée deux fois — et des maisons de ventes qui pilotent elles-mêmes catalogues, lots et ventes.

Projet entrepreneurial (France / Algérie). Une version 2 ajoute des maisons de ventes professionnelles aux annonces des membres : ventes cataloguées, chronométrées et en direct, consignation, règlement entre acheteur, maison, consignataire et plateforme. Quatre langues : français, arabe (de droite à gauche), anglais, espagnol.

Ce que j'ai fait personnellement

  • 01Défini le produit, les règles métier et les rôles (propriétaire, manager, commissaire-priseur, catalogueur, support).
  • 02Pris les décisions d'architecture : MongoDB autorité unique, Redis simple transport, horloge et prix côté serveur.
  • 03Rédigé les contrats et audits (idempotence, confidentialité des offres, machine d'états des ventes, multi-instance) et validé chaque livraison.
  • 04Piloté les mises en production : versions étiquetées, vitrine puis production, contrôles publics après chaque déploiement.

Ce qui ne vient pas de moi —L'implémentation s'est appuyée sur des assistants de code, travaillant sur mes spécifications et sous ma revue. Je présente donc mon rôle au niveau où il est réel : produit, architecture, décisions, validation et intégration — pas chaque ligne de code.

02Contraintes

  • Le serveur possède la vérité : le navigateur ne décide jamais d'un prix, d'une horloge ni d'un gagnant.
  • MongoDB autonome, sans transactions multi-documents : toute garantie doit tenir dans une écriture atomique.
  • Paiements des ventes professionnelles bloqués pour l'argent réel tant que les vérifications juridiques et prestataires ne sont pas faites — l'interface ne doit pas laisser croire le contraire.
  • Arabe complet de droite à gauche, jusqu'aux flèches de galerie inversées.

03Architecture

NAVIGATEURSvendeur · acheteurs · visiteurs · téléphones-camérasSocket.IO · websocket, repli pollingAPI · AExpress + Socket.IOAPI · Bmême codeREDIS PUB/SUBtransporte, ne décide rienMONGODB — L'AUTORITÉoffres, prix, fins de vente, statut, gagnant, vente, paiements, revchaque état versionné (rev) — un événement en retard ne défait jamais un état plus récent
  1. 01

    MongoDB décide

    Une offre est acceptée par une seule mise à jour conditionnelle atomique ; une clôture aussi, qui enregistre la vente dans la même écriture.

  2. 02

    Redis transporte

    L'adaptateur Socket.IO relaie les émissions entre instances. Redis ne décide rien, ne tient aucun verrou, rien de financier n'en dépend.

  3. 03

    Les clients se réconcilient

    Un événement est un indice rapide. Chaque état porte une version (`rev`) : un événement en retard ou dupliqué ne peut jamais défaire un état plus récent.

  4. 04

    LiveKit pour la vidéo

    Caméra de l'ordinateur et téléphone en seconde caméra ; jetons émis par requête, aucun événement socket ne déclenche d'opération vidéo.

Principe de l'architecture temps réel — le dépôt de code reste privé.

04Décisions d'implémentation

  1. 01

    Idempotence dans l'écriture qui réclame le prix

    Chaque confirmation d'offre porte une clé client. La clé est enregistrée dans la même mise à jour atomique que le prix : une clé ne peut réclamer qu'une fois, sur n'importe quelle instance. Une nouvelle tentative reçoit le reçu d'origine ; réutiliser une clé pour un autre montant est refusé (409), même en concurrence.

  2. 02

    Confidentialité des offres à la frontière du serveur

    Aucun identifiant, nom, email ni téléphone d'enchérisseur n'atteint un navigateur via une réponse publique. Les enchérisseurs deviennent « Enchérisseur 004 » : un rang propre à chaque vente, stable, non dérivé de l'identifiant, sans secret à gérer.

  3. 03

    Brancher le direct sur le circuit de paiement existant

    Deux options : un modèle de commande direct (réécrire ~20 consommateurs, dont tous les prestataires de paiement) ou un adaptateur qui crée, pour un résultat en direct, l'enregistrement de vente que ces consommateurs attendent déjà. Choix : l'adaptateur — non parce qu'il est plus court, mais parce que l'autre option réécrivait le circuit de l'argent.

  4. 04

    Plusieurs instances, une seule vérité

    L'audit multi-instance a trouvé un état par processus faux après une offre sur une autre instance (supprimé), un adaptateur attaché après le démarrage et capable d'échouer en silence (corrigé), et une jonction de salle qui acceptait n'importe quel nom (corrigé : un socket ne peut plus écouter les événements privés d'un autre utilisateur).

NavigateurAPI · instance AAPI · instance BMongoDB✕

01 / 05

Confirmation d'une offre de 5 500

Une clé est générée pour cette confirmation : k·7f3a.

Même clé, autre montant → 409 IDEMPOTENCY_KEY_REUSED, même en concurrence.

05Difficultés

La fenêtre de crash

Sans transactions multi-documents, un crash entre la réclamation du prix et l'enregistrement de l'offre laissait un prix monté sans offre. La clé, réclamée atomiquement avec le prix, permet de régler la situation à la tentative suivante.

La vidéo qui disparaît

Les spectateurs perdaient l'image quand le vendeur rechargeait la régie. Un chien de garde réabonne la vidéo après 4 secondes ; la séquence qui échouait 4 fois sur 4 passe 4 fois sur 4.

Ne rien promettre de faux

Un virement n'est jamais appelé « payé » tant que personne ne l'a enregistré ou confirmé ; les statuts distinguent dû, reçu, retenu, libéré, autorisé, enregistré et confirmé.

06Évaluation

Chaque version passe des suites automatisées avant d'être étiquetée : suites backend en mode multi-instance, suites d'interface par parcours (salle en direct, offres, mobile, reconnexion), simulations dédiées (autorisation des ventes, vendeur-spectateur), puis contrôles publics après déploiement et audit d'accessibilité axe sur six pages en français et en arabe.

ContrôleRésultat
Contrôle public de production (v2.6.2)22 / 22
Contrôle de la vitrine, à chaque version29 / 29
Accessibilité axe — 6 pages, fr et ar0 violation
Décalage de mise en page, page lotCLS 0,29 → 0
JavaScript pour un visiteur francophone496 → 290 kB

Rapports de livraison du 1er novembre 2026.

07Résultats

  • v2.6.2 en production et en vitrine (novembre 2026) : comptes, double authentification, ventes chronométrées et en direct, consignation, espaces professionnels par rôle, quatre langues.
  • Offres idempotentes, confidentielles et cohérentes sur plusieurs instances.

Limites

  • Aucune maison de ventes n'est encore approuvée en production : les ventes professionnelles s'y affichent vides. La vitrine utilise des données fictives.
  • Le paiement en ligne est construit mais désactivé ; aucune transaction réelle n'est revendiquée.
  • Le direct n'a pas encore été testé sur de vrais téléphones à travers Internet.

Le produit, en vrai

Accueil — l'objet comme héros
Lot — prix, offres et compte à rebours du serveur
Direct, téléphone — une confirmation par offre
Arabe, de droite à gauche — offre dépassée
Espace professionnel — catalogue
Paiement — simulé dans la vitrine

Photos des lots : Wikimedia Commons, licences CC — crédits complets dans le produit.

08Ce que j'en retiens

  • 01Mettre la garantie dans l'écriture, pas autour : une clé enregistrée après coup ne protège de rien.
  • 02Le plus petit design sûr bat le plus propre quand il touche à l'argent.
  • 03Un statut « construit, désactivé » honnête vaut mieux qu'une fonctionnalité qui semble marcher.

09Preuves