Gerex Food
SaaS multi-tenant de gestion de restaurant
Plateforme SaaS multi-tenant pour la restauration : stocks, commandes, finances, alertes et reporting temps réel, avec des interfaces distinctes pour la salle et la cuisine. Une seule API sert le dashboard des restaurants et le back-office de la plateforme.
- 0
- ligne servie sans tenant
- 3
- applications
Architecte & développeur — API multi-tenant, dashboard, superadmin
En SaaS multi-tenant, la fuite de données entre clients n'est jamais une décision — c'est un oubli. Il suffit d'une requête écrite sans le filtre `tenant_id`, dans un rapport ou un export ajouté six mois plus tard, pour qu'un restaurant voie le chiffre d'affaires d'un autre. Compter sur la discipline de chaque développeur sur chaque requête est une stratégie qui échoue toujours, tôt ou tard.
J'ai rendu l'isolation structurelle plutôt que déclarative. Un middleware résout le tenant courant à chaque requête, un singleton le porte pour la durée du cycle, et un trait applique un scope global sur tous les modèles concernés en estampillant automatiquement `tenant_id` à la création. Le développeur n'a rien à se rappeler.
Le point clé est le comportement en cas d'absence de tenant : le scope n'ouvre pas l'accès, il le ferme. Sans tenant résoluble, la requête renvoie zéro ligne. Un bug de résolution produit une page vide — visible, corrigible — au lieu d'un déversement silencieux de toutes les données de la plateforme.
Le contournement existe, mais il est explicite : la couche d'analytics cross-tenant doit retirer les scopes globaux à la main et filtrer elle-même. Rendre le cas dangereux verbeux et le cas sûr automatique, c'est tout l'objectif.
- 01
Résolution du tenant
Un middleware ajouté au groupe `api` lit l'en-tête `X-Tenant-Slug` (ou le paramètre de route), avec repli sur le `tenant_id` de l'utilisateur authentifié.
TenantMiddleware
- 02
Scope fail-safe
Un scope global qui, sans tenant résoluble, renvoie zéro ligne. L'échec est fermé par défaut, pas ouvert.
TenantScope
- 03
Files & temps réel
Laravel Horizon sur Redis pour les traitements de fond, et Laravel Reverb pour pousser commandes et alertes en direct vers la salle et la cuisine.
Horizon · Reverb
- 04
Dashboard restaurant
Next.js 16, l'application quotidienne des équipes : stocks, commandes, finances, alertes.
Next.js 16
- 05
Superadmin plateforme
Application séparée pour la supervision de tous les tenants, avec analytics cross-tenant explicitement déscopé.
Next.js 16
Le scope ferme au lieu d'ouvrir
L'implémentation naïve d'un scope multi-tenant ne filtre rien quand le tenant est absent — et livre donc tout. J'ai inversé la valeur par défaut : absence de tenant, absence de résultats. La seule exception est le modèle utilisateur, qui doit rester consultable pour que l'authentification puisse fonctionner avant même qu'un tenant soit connu.
- Isolation des tenants appliquée automatiquement par scope global, avec échec fermé par défaut
- Stocks, commandes, finances et reporting temps réel dans une seule application
- Interfaces distinctes pour les équipes en salle et en cuisine
- Traitements de fond sous Horizon, temps réel via WebSockets Reverb
- Une API unique servant le dashboard tenant et le superadmin plateforme