Sanu
Sanu est un progiciel de gestion et de caisse destiné au commerce de détail en Afrique de l’Ouest, que j’ai fondé et dont j’assure l’essentiel du développement depuis janvier 2025.
- Rôle
- Fondateur et développeur principal, en charge du produit, de l’architecture et du développement, avec deux autres développeurs
- Période
- De janvier 2025 à aujourd’hui
- État
- En développement. En développement, déployé en préproduction
- Technologies
- Java 21, Spring Boot 4, Spring Modulith, PostgreSQL, React, Flutter
- Dépôts
- Sept
Contexte
Une première version de Sanu, composée d’une API Django et d’une application Flutter, a été développée à partir de janvier 2025. La version actuelle, engagée en septembre 2026, sépare une API écrite en Java, un backoffice et une console d’administration en React, et une application de caisse en Flutter.
Elle a été précédée d’un travail de spécification, qui a produit un manuel d’utilisation organisé par profil et par module, publié sous la forme d’un site statique, ainsi qu’un prototype navigable des écrans. Ce prototype tient lieu de référence pour les trois interfaces, si bien qu’aucune d’elles ne décide seule de la forme d’un écran.


Problème
La difficulté principale tient au modèle d’accès. Une même personne peut appartenir à plusieurs sociétés, chaque société compose ses profils à partir de codes de permission, et un poste de caisse partagé entre plusieurs vendeurs doit permettre une connexion rapide par code PIN sans que cette facilité soit ouverte à n’importe quel appareil.
Trois interfaces écrites dans deux langages consomment par ailleurs la même API, ce qui suppose que les règles d’accès ne soient énoncées qu’à un seul endroit, faute de quoi elles finiraient par diverger d’une interface à l’autre.
Réponse apportée
Modèle d’accès
Le serveur résout les permissions à chaque requête, à partir des appartenances de la personne et du profil que la société lui a attribué. Le code PIN n’est accepté que depuis un terminal préalablement enregistré, et une personne ne dispose que d’une session à la fois. Ces décisions sont consignées dans un document d’architecture, que les trois interfaces prennent pour contrat.
L’API est une application Spring Boot unique, découpée en modules dont Spring Modulith vérifie les frontières à chaque exécution des tests ; la figure 1 en donne la disposition générale.
Canal temps réel
Le canal temps réel passe par un point d’accès WebSocket, /api/ws, ce qui suppose de lui réserver un emplacement dans la configuration de nginx. Sans transmission des en-têtes de mise à niveau, le proxy répond 400 et aucun client ne se connecte ; avec le délai de lecture par défaut, de soixante secondes, un canal inactif est coupé chaque minute. L’emplacement est déclaré avant celui de /api, afin que ces en-têtes ne soient pas posés sur les appels ordinaires.
location /api/ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}Méthode
La nouvelle version est écrite pour l’essentiel avec un assistant, Claude Code, que je conduis par rôles : un architecte arrête la structure, un développeur écrit à l’intérieur de ces règles, un testeur rend un verdict et un responsable du déploiement livre. Chaque rôle transmet au suivant un bloc de faits sourcés, et un travail n’est tenu pour terminé qu’une fois la commande de vérification passée. Sur les quatre dépôts de code, la plupart des commits portent la cosignature de l’assistant. Ces rôles sont décrits dans l’étude du dépôt de plugins.
Vérification
Chaque dépôt possède une commande unique de vérification, exécutée à l’identique sur le poste de développement et dans le pipeline, qui enchaîne le contrôle du formatage, la compilation et les tests. Côté serveur, les tests d’intégration s’exécutent sur une base PostgreSQL réelle, démarrée dans un conteneur.
La couverture exigée est de 100 % sur les paquets de domaine et de données de l’application Flutter. Elle a été assouplie pour les paquets de présentation, après qu’une fonctionnalité eut demandé plus de temps en tests de widgets qu’en développement.
| Dépôt | Contenu | Technologies |
|---|---|---|
sanu-backend-java | API | Spring Boot, PostgreSQL |
sanu-app-react | Backoffice | React, Vite |
sanu-apps-flutter | Application de caisse | Flutter |
sanu-app-prototype | Prototype des écrans | JavaScript |
sanu-erp-specification | Manuel et carnet de produit | MkDocs |
sanu-console-react | Console d’administration | React, Vite |
sanu-apps-portal | Portail d’accès aux services | JavaScript |
Limites et perspectives
Le backoffice atteint soixante-douze pages, dont la plupart restent des écrans d’attente tant que les lots fonctionnels correspondants ne sont pas traités. L’application de caisse couvre pour l’heure la vente au comptoir, et les applications destinées à la livraison et aux clients ne sont pas commencées.
La nouvelle version n’est par ailleurs déployée qu’en préproduction, si bien que les choix décrits ici n’ont pas encore été éprouvés par un usage réel. Il conviendra de reprendre cette étude une fois les premiers points de vente équipés, afin d’y consigner ce que l’usage aura confirmé ou démenti.
