La stack idéale pour un SaaS moderne
Next.js, Supabase et Stripe forment le trio technologique le plus puissant pour construire un SaaS en 2025. Next.js gère le rendu et le routage, Supabase fournit la base de données PostgreSQL avec l'authentification et la sécurité RLS, et Stripe s'occupe de toute la logique de paiement. Ensemble, ils couvrent 90% des besoins techniques d'un SaaS.
Ce guide vous accompagne étape par étape dans l'architecture d'un SaaS complet. Si vous préférez partir d'une base prête à l'emploi, Boilerplate-Stack intègre déjà toute cette architecture.
Étape 1 : Architecture centrée sur les comptes
L'erreur la plus courante en SaaS est d'attacher les données directement aux utilisateurs. Il faut plutôt adopter un modèle centré sur les comptes :
USER (auth.users)
│
│ peut avoir plusieurs
▼
MEMBERSHIPS (user_id, account_id, role)
│
│ appartient à
▼
ACCOUNT (personnel | workspace)
├── Solde de crédits
├── Abonnement (Stripe)
├── Sessions IA
└── Clés APICe modèle permet :
- Un utilisateur peut appartenir à plusieurs organisations
- Les rôles sont spécifiques à chaque organisation
- La facturation est liée au compte, pas à l'utilisateur
- Le passage B2C vers B2B est transparent
Étape 2 : Authentification avec Supabase Auth
Supabase Auth offre plusieurs méthodes d'authentification. Pour un SaaS, les magic links sont recommandés :
- Sécurité renforcée : pas de mot de passe à stocker ni à compromettre
- Expérience fluide : un clic dans l'email suffit
- Compatible OAuth : ajoutez Google, GitHub en parallèle
Point crucial : côté serveur, utilisez toujours getUser() et jamais getSession(). La session peut être falsifiée, getUser() valide le token auprès de Supabase.
Row Level Security (RLS)
Chaque table doit avoir une politique RLS qui filtre par appartenance au compte :
CREATE POLICY "members_access" ON table_name FOR SELECT
USING (EXISTS (
SELECT 1 FROM memberships
WHERE memberships.account_id = table_name.account_id
AND memberships.user_id = auth.uid()
));La RLS est votre dernière ligne de défense. Même si un bug expose une route API, les données restent protégées au niveau de la base.
Étape 3 : Facturation avec Stripe Webhooks
La facturation Stripe doit être pilotée par les webhooks, pas par des appels API synchrones. Voici le flux :
- checkout.session.completed → Création de l'abonnement ou achat de crédits
- customer.subscription.updated → Synchronisation des changements de plan
- customer.subscription.deleted → Marquage comme annulé
- invoice.paid → Recharge mensuelle des crédits
Les plans sont définis dans le code (fichier de configuration), pas dans la base de données. Le webhook fait la correspondance entre le stripePriceId reçu et le plan configuré.
Système de crédits atomique
Les opérations sur les crédits doivent être atomiques via des fonctions SQL RPC :
-- Ne jamais faire UPDATE credits_balance directement
SELECT decrement_credits(p_account_id, p_amount, p_reason);
SELECT add_credits(p_account_id, p_amount, p_source);Étape 4 : Sécurité OWASP
Un SaaS en production doit couvrir le Top 10 OWASP :
- CSRF : pattern Double Submit Cookie
- Rate limiting : Upstash Redis avec paliers (strict, standard, relaxed)
- Sanitisation : nettoyage de tous les inputs utilisateur
- CSP headers : Content Security Policy stricte
- Protection bot : Cloudflare Turnstile sur les formulaires sensibles
Étape 5 : Déploiement
Avec Next.js sur Vercel et Supabase en cloud, le déploiement est simplifié. Pour l'auto-hébergement, un Dockerfile multi-stage optimisé est essentiel.
La solution clé en main
Implémenter tout cela depuis zéro prend facilement 3 à 5 mois. Boilerplate-Stack vous offre cette architecture complète, testée et documentée, prête à personnaliser pour votre projet.
Chaque pattern décrit dans cet article est implémenté dans Boilerplate-Stack. Le code est structuré pour être lisible, extensible et compatible avec le développement assisté par IA.
Découvrez la documentation complète et les démos sur boilerplate-stack.com.