Fellwin Studio
Le POS conçu pour la bijouterie sénégalaise.
18 mois
en production continue
0
incident bloquant
100 %
auto-hébergé · OVH
Le contexte
Sunu Bijou est le premier système jamais livré sous le nom Fellwin pour un client sénégalais. C'est un POS multi-tenant pour les bijouteries de Dakar et plus largement du Sénégal : un secteur structurant de l'économie locale, mais sur lequel il n'existait pas, au moment où nous avons démarré, de logiciel pensé pour la manière dont il fonctionne réellement.
Les solutions existantes étaient soit des POS occidentaux génériques adaptés à la marge, soit des outils maison construits sur Excel. Ni l'un ni l'autre ne modélisait correctement les opérations clés du métier : le dépôt (avance versée par le client sur une commande personnalisée), le rachat (achat d'or au client au prix du jour), la distinction entre or 18 carats et 21 carats, le coût façon (le travail de l'artisan, ajouté au prix de la matière), les paiements partiels étalés. Le système devait épouser ces réalités, pas les forcer dans une forme étrangère.
Les décisions d'architecture
NestJS sur PostgreSQL, pas Express + Postgres directement. Le métier comporte plusieurs sous-domaines (vente, dépôt, rachat, caisse, multi-locataire) qui partagent des invariants forts : un dépôt ne peut pas devenir négatif, un rachat doit être tracé, une caisse doit s'équilibrer en fin de journée. NestJS apporte la structure modulaire et le système de pipes/guards qui rendent ces invariants explicites au lieu de les dissimuler dans des conditions ad hoc.
Trade-off assumé : NestJS impose une courbe d'apprentissage non triviale et un coût de boilerplate par module. Le coût se paie une fois ; les invariants restent vrais pour toujours.
MikroORM en mode Unit-of-Work, pas Prisma. Une vente Sunu Bijou implique souvent plusieurs entités modifiées atomiquement : créer un mouvement de caisse, débiter le stock, mettre à jour le solde de dépôt du client, enregistrer la transaction. MikroORM offre nativement le pattern Unit of Work : on modifie les entités librement dans la requête, et un seul `flush()` à la fin écrit tout ou rien. Sur du code financier, c'est moins de bugs de cohérence que la pose manuelle de transactions Prisma.
Trade-off assumé : MikroORM a une communauté plus petite et un rythme de release plus lent que Prisma. Nous avons contribué quelques cas de tests upstream quand un edge case nous gênait ; c'est le prix accepté pour la cohérence transactionnelle.
Multi-tenant single-database avec discrimination par colonne tenant_id, pas Schema-per-tenant PostgreSQL. Le profil d'usage de Sunu Bijou est multi-bijouteries indépendantes, avec des volumes individuels modestes. Le single-database simplifie radicalement l'exploitation : une seule migration à appliquer, un seul backup à vérifier, un seul plan de monitoring. Toutes les requêtes passent par un middleware Row-Level Security qui injecte le tenant_id à partir du JWT : le code applicatif n'a jamais à y penser.
Trade-off assumé : Une faille au niveau du middleware RLS exposerait potentiellement les données d'un tenant à un autre. Nous compensons par des tests d'intégration spécifiques qui simulent un tenant essayant d'accéder aux données d'un autre, exécutés à chaque CI.
L'exécution
Sunu Bijou est conteneurisé avec Docker (Dockerfile multi-stage,
exécution non-root) et déployé sur OVH (deux VPS dédiés Fellwin, un
pour la base de données, un pour l'application). Le reverse-proxy
nginx termine TLS via Let's Encrypt (renouvellement automatisé). Les
sauvegardes PostgreSQL quotidiennes sont vérifiées par restauration
test une fois par trimestre. CI/CD passe par GitHub Actions : chaque
push sur main déclenche les tests Vitest, le build Docker, le push
de l'image vers GHCR, puis le déploiement par SSH avec
docker compose up --force-recreate. Le pipeline tient en cinq
minutes du commit à la production.
Les bijouteries qui utilisent Sunu Bijou aujourd'hui voient le système comme un outil quotidien : ouverture de caisse le matin, ventes à la caisse pendant la journée, fermeture-réconciliation le soir. Il fait ce qu'il fait, sans demander d'attention particulière. C'est exactement ce qu'on attend d'un logiciel d'exploitation.
Les leçons
La leçon principale de Sunu Bijou ne porte pas sur le code mais sur la modélisation. Les premières versions du module de dépôt traitaient le dépôt comme un solde positif simple : une somme à reporter sur les ventes suivantes. Cela suffisait pour 80 % des cas. Mais les bijouteries que nous accompagnions nous ont rapidement signalé deux configurations que notre modèle ne couvrait pas : le dépôt à plusieurs déposants (la mère et la fille déposent ensemble pour une commande commune) et le dépôt avec remboursement partiel en or (le client annule une partie de sa commande et récupère la moitié en gramme d'or). Repenser le module a pris une semaine. Ces deux configurations couvrent 5 % des transactions mais 100 % de la confiance du client.
La seconde leçon porte sur les sauvegardes. Nous avons testé la procédure de restauration trois mois après la première mise en production, en condition de panique simulée. La restauration a fonctionné ; mais nous avons trouvé en l'examinant un bug de chronologie sur la table des prix de l'or (un index manquant pouvait faire renvoyer le prix de la veille pour une vente du jour). Le bug était dormant ; sans le test de restauration, il aurait fini par se manifester en production un samedi à l'ouverture.
En production aujourd'hui
Sunu Bijou est en exploitation continue depuis 18 mois sur les bijouteries qui l'ont adopté. Aucun incident bloquant à ce jour. La roadmap 2026 ajoute un module de gestion d'atelier (suivi des commandes personnalisées de la prise de mesure à la livraison) et une interface mobile pour les déplacements en clientèle.
Un système à concevoir, déployer ou reprendre en main ?
Nous étudions chaque cahier des charges sérieusement. Réponse sous 48 h ouvrées.