Aperçu
Quotery est un SaaS B2B multi-tenant qui transforme les demandes d'achat entrantes — PDF, feuilles Excel, listes CSV de lignes d'article — en devis chiffres, apparies et auditables en quelques minutes. Concu pour les distributeurs, entrepreneurs et ateliers de service rapides, il combine une orchestration OpenAI en trois appels avec un matcher deterministe base sur les codes, de sorte que les correspondances exactes ne consomment jamais de tokens LLM. Du brouillon de devis au bon de livraison emis, tout le parcours quote-to-cash vit sur une seule plateforme.
Le défi
Les equipes commerciales B2B passent des heures a ressaisir les demandes d'achat clients dans des logiciels de devis, a rapprocher des descriptions produit en texte libre de catalogues utilisant plusieurs conventions de code (fournisseur, interne, import, export), et a ressaisir les memes donnees dans les outils de fulfillment et d'inventaire. Les ERP tout-en-un sont lourds et lents a configurer ; les feuilles de calcul improvisees perdent la tracabilite des qu'un ajustement de stock se produit.
La solution
Nous avons construit Quotery comme un backend Django 5 + DRF scope par tenant, avec une SPA React 19 et un site vitrine deploye sur Render. Chaque modele metier herite d'une classe de base a cle UUID et suppression douce, chaque requete est auto-filtree par tenant, et chaque mutation de la couche service invalide un ensemble precis de groupes de cache Redis (dashboard, product-usage, quotes-map) avec un motif de cle qf:v1:<groupe>:<portee>:<hash> qui echoue en douceur en cas de panne de Redis. L'import de devis par IA execute trois appels OpenAI sequentiels dans une transaction atomique : extraction de structure depuis PDF (pypdf), XLSX (openpyxl), CSV ou texte brut ; correspondance deterministe sur quatre champs de code produit, puis une decision LLM pick-or-reject en lot sur les lignes non appariees avec garde-fou anti-hallucination ; et un resume de 1 a 3 phrases sensible a la locale. Les devis suivent une machine a etats formelle (draft -> sent -> closed -> partially_delivered -> delivered) qui alimente un grand livre de stock append-only sur plusieurs emplacements, avec sur-reservation autorisee pour que les commerciaux puissent s'engager avant qu'une reception ne soit validee. Bons de livraison, bons de retour et receptions de stock partagent un meme flux brouillon-vers-emis. Les PDF sont rendus via WeasyPrint, l'authentification est Google OAuth via django-allauth avec JWT base session dans des cookies HttpOnly, le RBAC utilise un catalogue de permissions personnalise, et chaque mutation atterrit dans un journal d'audit immuable. Un assistant embarque repond aux questions sur les devis, les clients et les stocks la ou l'utilisateur a pose la question.