Toutes les études de cas

Étude de cas · SaaS d’entreprise · Architecture multilocataire

Concevoir une plateforme d’entreprise modulaire et multilocataire

AxisOne Cloud · SaaS d’entreprise · Multi-industrie

Comment AxisOne Cloud a été conçue comme un seul modèle de données, douze modules et sept rôles : licences activées par locataire, isolation par la sécurité au niveau des lignes sur chaque table, et un hub d’intégration bâti sur des clés d’API hachées et des webhooks signés.

  • 12 modules — 7 cœur, 5 complémentaires
  • 7 rôles avec leur propre navigation
  • 37 tables isolées par locataire

Statut En production Site web: axisonecloud.com

Contexte

AxisOne Cloud est née d’une question que je rencontrais sans cesse dans les entreprises qui fonctionnent par projets : pourquoi une société qui gère des projets, des sous-traitants et des instruments bancaires a-t-elle besoin de cinq outils qui ne se parlent pas? Le premier cahier des charges visait la construction — devis quantitatifs, sous-traitance, lettres de garantie et lettres de crédit en sont les instruments quotidiens. Dans la même séance de travail, je l’ai élargi à toute industrie : le cœur — comptes, projets, factures, tâches, documents, approbations — est le même partout; seuls les modules complémentaires sont propres à un secteur. Cette distinction entre un cœur universel et des modules complémentaires sous licence est devenue la décision fondatrice de la plateforme, et la raison pour laquelle elle se dit modulaire.

Défi

Bâtir un seul produit qui se comporte comme un produit différent pour chaque client, sans dupliquer le code. Trois choses devaient tenir en même temps. L’isolation : plusieurs entreprises partagent une seule base de données, et aucune requête ne doit franchir la frontière d’un locataire — ni dans l’application, ni dans le stockage de fichiers, ni par l’API. Les licences : un module qu’un locataire n’a pas activé doit disparaître de ses routes, de ses menus et de son tableau de bord, et le même catalogue doit alimenter la console qui l’active. Les rôles : sept rôles aux métiers différents — du propriétaire de la plateforme au partenaire externe —, chacun avec sa navigation et ses droits sur les données. Et l’ensemble devait rester ouvert vers l’extérieur : une telle plateforme remplace rarement un ERP, elle s’installe à côté.

Mon rôle

Fondateur, architecte et concepteur. J’ai rédigé la spécification de la plateforme sous forme de cahiers des charges structurés : le modèle locataire, module et module-par-locataire; la règle de licence — cœur toujours actif, modules complémentaires par locataire; les rôles nommés et ce que chacun voit; la séparation en couches entre authentification, contexte de locataire, gardes de route et accès aux données; et le hub d’intégration — connecteurs, profils de mappage, tâches, file d’événements, webhooks, clés d’API, audit. J’ai pris les décisions techniques en cours de route : rapatrier tôt la base de données dans notre propre projet, fermer l’inscription, traiter chaque alerte de sécurité comme bloquante, séparer le site vitrine et l’application sur deux sous-domaines. Mon équipe chez SOFT M POWER CANADA a porté la réalisation et exploite la plateforme.

Architecture / approche

Trois tables portent tout le modèle de licences : un catalogue de modules avec un indicateur « cœur », les locataires, et l’activation d’un module pour un locataire. Un contexte de locataire charge l’entreprise et ses modules actifs; la garde de route et la navigation par rôle s’y alimentent : un module non licencié n’est ni accessible ni visible. L’isolation n’est pas confiée à l’application : chaque table métier porte l’identifiant du locataire, la sécurité au niveau des lignes est activée partout, et les vérifications de locataire et de rôle sont des fonctions à droits définis, réutilisées par chaque politique. Les tables enfants sont protégées par leur parent; le stockage de fichiers est cloisonné par locataire. Les rôles vivent dans une table distincte des profils : un utilisateur ne peut pas élever ses droits en modifiant son profil.

Technologie

Une application monopage React et TypeScript avec une couche de requêtes typée et des mécanismes génériques de pagination et d’accès aux données par locataire; un système PostgreSQL avec authentification intégrée, stockage d’objets privé et fonctions côté serveur écrites en TypeScript. Trente-sept tables, quatre fonctions SQL exposées, trois fonctions de déclencheur — dont un déclencheur d’audit générique qui photographie la ligne avant et après chaque modification, réutilisé sur six entités. Le hub d’intégration repose sur une file d’événements sortants aux états en attente, envoyé, échoué et rebut, un répartiteur qui signe chaque envoi en HMAC-SHA256 et réessaie trois fois, et des fonctions REST entrantes et sortantes authentifiées par clés d’API hachées à préfixe visible. Quinze migrations appliquées décrivent l’ensemble du schéma.

Exécution

La première version de l’application et de son site public a été spécifiée et bâtie en décembre 2025, dans une boucle pilotée par la spécification : chaque capacité était rédigée sous forme de cahier des charges, réalisée par mon équipe avec des outils de développement assistés par l’IA, puis revue selon une seule règle — rien n’est livré tant que ce n’est pas visible dans l’interface. Deux audits de couverture par rapport à la spécification initiale ont été menés avant d’entreprendre le site. Le site public reprend la même structure cœur et modules complémentaires, avec une présentation du produit en cinq pages et un assistant de vente qui qualifie les demandes. Les dernières étapes ont été la fermeture de l’inscription derrière un code d’entreprise et la configuration des deux sous-domaines personnalisés, l’un pour le site et l’autre pour l’application.

Contraintes

Rapatrier la base de données de l’environnement d’hébergement de la construction initiale vers notre propre projet PostgreSQL a obligé à abandonner le premier schéma et à le réécrire; la migration morte reste dans le dépôt, comme trace. Trois alertes du scanneur de sécurité — comptes clients lisibles au-delà des rôles, courriels des profils exposés, protection contre les mots de passe compromis — ont chacune été traitées comme bloquantes et fermées par des politiques au niveau des lignes durcies en deux itérations. Le service de courriel transactionnel a rejeté l’importation du paquet dans l’exécution serveur puis, en mode test, tout destinataire autre que le titulaire du compte : les deux problèmes ont été réglés en appelant directement son API et en acheminant vers une boîte interne. Une régression d’interface introduite par une refonte a été repérée et corrigée le jour même.

Impact d’affaires

Ce que la plateforme offre aujourd’hui : un modèle de données multilocataire de 37 tables isolées; un catalogue de 12 modules — 7 cœur, 5 complémentaires — activés par entreprise; sept rôles avec leur propre navigation; CRM, projets, tâches, facturation, paiements, documents et une file d’approbation; des modules complémentaires construction et finance commerciale pour les devis quantitatifs, les appels d’offres, les contrats de sous-traitance, les lettres de garantie et les lettres de crédit; un tableau de bord de rapports; et un hub d’intégration avec importation et exportation REST, clés d’API hachées, webhooks signés et journal d’audit. Le site vitrine présente aux prospects la même structure cœur et modules complémentaires. Cette architecture est celle que je réutilise maintenant quand un client a besoin d’une plateforme qui sert plusieurs organisations à partir d’une seule base de code.

Leçons clés

  1. Décider ce qui est cœur et ce qui est complémentaire avant la première table : ce partage est le produit, et le modèle de données, les licences, la navigation et la tarification en découlent.
  2. L’isolation appartient à la base de données, pas à l’application : la sécurité au niveau des lignes avec des fonctions à droits définis, réutilisées par chaque politique, est plus facile à prouver que cent requêtes filtrées.
  3. Posséder sa base de données dès le premier jour; la migrer plus tard coûte un schéma.
  4. Un scanneur de sécurité est un réviseur gratuit : traiter chaque alerte comme bloquante et la fermer par une migration, pas par une rustine.
  5. Rien n’est livré tant que ce n’est pas visible dans l’interface — cette règle garde honnête une construction pilotée par la spécification.