Aller au contenu
Tous les projets

SaaS Fullstack — 2026

MIRA

SaaS de relance client pour opticiens (Côte d'Ivoire)

SaaS multi-tenant qui dit chaque matin à un opticien quels clients rappeler, avec le message déjà écrit et un bouton qui ouvre WhatsApp. Multi-boutique, abonnement en mobile money, isolation des données prouvée par test.

Aperçu du projet MIRA
Type
SaaS Fullstack
Année
2026

01Le problème

Les opticiens d'Abidjan tiennent leur fichier client dans un cahier ou un tableur, et perdent le revenu le plus facile du métier : le client qui devait revenir. Personne ne sait qui doit repasser pour un contrôle de vue à douze mois, qui doit racheter des lentilles, ni à qui la commande est prête depuis trois jours. Les relances se font de mémoire, au hasard, ou pas du tout ; quand elles se font, deux vendeuses écrivent parfois au même client la même semaine. Les logiciels d'optique existants coûtent cher, exigent un PC au comptoir, et gèrent le stock et l'atelier là où le besoin est ailleurs.

02La solution

J'ai conçu et développé le produit de bout en bout : Next.js 15 App Router, TypeScript strict, PostgreSQL via Drizzle. Le cœur est un moteur de relance en code pur — aucune I/O, la date du jour toujours passée en paramètre — qui calcule la file du jour à partir de six règles (contrôle de vue, renouvellement, lentilles, satisfaction, anniversaire, commande prête), la trie, la plafonne et la déduplique : un seul message par client et par jour, avec une pause anti-spam valable sur tout le réseau. Il est testé à 100 % de branches, seuil imposé par la CI. L'isolation multi-tenant repose sur la Row Level Security PostgreSQL, endossée par un rôle applicatif sans BYPASSRLS — l'attribut du rôle propriétaire annulait silencieusement les politiques, et seul un script qui tente réellement de lire chez le voisin l'a révélé. J'ai ajouté le réseau multi-boutique (cloisonnement applicatif éprouvé en navigateur, chaque officine recomposant exactement le fichier global), l'import CSV d'un cahier existant avec rapport ligne par ligne, l'abonnement en francs CFA avec essai, grâce et lecture seule, et les canaux WhatsApp/SMS/appel derrière une interface unique — le journal étant toujours écrit avant l'ouverture du lien.

03Le résultat

En production sur Vercel avec une base Neon. Une agence s'inscrit seule, choisit sa formule, reprend son cahier client par import CSV et envoie sa première relance sans intervention. Le propriétaire ouvre les accès de ses officines, compare leurs résultats et gère son abonnement ; chaque comptoir ne voit que son propre fichier. 325 tests unitaires, 27 parcours en navigateur, et deux scripts qui prouvent l'isolation plutôt que de l'affirmer. Trois intégrations sont écrites mais dormantes tant que les comptes ne sont pas ouverts — paiement CinetPay, SMS Orange — le produit retombant alors sur des consignes de mobile money et des liens transmis à la main, sans jamais échouer en silence. Restent au programme le mode hors ligne et le job de nuit de facturation.

Stack technique

  • Next.js 15.5
  • React 19.1
  • TypeScript 5 (strict)
  • PostgreSQL 16 + Row Level Security
  • Drizzle ORM 0.45
  • Auth.js 5 (argon2id)
  • Tailwind CSS 4
  • Zod 4
  • Vitest 4
  • Playwright 1.62
  • Neon
  • Vercel

Projet suivant

CIBLE