Features
Tenant Management & Billing
ProductsManager est une application multi-tenant avec gestion des plans SaaS, quotas, metering d'usage et facturation Stripe integree.
Plans tarifaires
5 plans disponibles, configurables depuis la base de donnees (plan_definitions dans db_core) :
| Plan | Produits | Imports/mois | Enrichissements IA | Connecteurs | Prix/mois |
|---|---|---|---|---|---|
| Free | 100 | 10 | 5 | 1 | 0 EUR |
| Starter | 1 000 | 50 | 50 | 3 | 29 EUR |
| Growth | 10 000 | 200 | 500 | 7 | 79 EUR |
| Scale | 100 000 | Illimite | 5 000 | 14 | 199 EUR |
| Enterprise | Illimite | Illimite | Illimite | 14 | Sur devis |
Chaque plan definit des stripe_price_id_monthly et stripe_price_id_yearly pour la facturation.
Le plan Enterprise inclut un SLA dedie, support prioritaire, et deploiement on-premise possible.
Isolation tenant
Modele de donnees
Chaque tenant est identifie par un tenant_id (UUID) present sur toutes les tables metier. L'isolation est assuree a plusieurs niveaux :
- SQLAlchemy auto-filter : middleware injecte automatiquement
WHERE tenant_id = :current_tenantsur toutes les requetes - Middleware FastAPI :
TenantMiddlewareextrait le tenant du JWT et le place dans le contexte de requete - Contexte async :
tenant_context.pyutilisecontextvarspour propager le tenant_id
# Le filtre tenant est automatique — pas besoin de le specifier
async with db_router.session_scope("catalog") as session:
products = await session.execute(select(Product)) # filtre par tenant_id auto
Provisioning
A la creation d'un tenant, le ProvisioningService :
- Cree l'enregistrement tenant dans db_core
- Initialise les quotas selon le plan
- Cree le bucket MinIO dedie (si isolation stockage activee)
- Envoie l'email de bienvenue
Quota enforcement
QuotaChecker
Le service QuotaChecker verifie les quotas avant chaque operation :
# Verification avant import
await quota_checker.check("imports", tenant_id)
# Leve QuotaExceededError si limite atteinte
Quotas verifies :
- Nombre de produits actifs
- Imports par mois
- Enrichissements IA par mois
- Nombre de connecteurs actifs
Reponse en cas de depassement
{
"error": "quota_exceeded",
"detail": "Import quota exceeded (50/50). Upgrade to Growth plan for 200 imports/month.",
"current_usage": 50,
"limit": 50,
"upgrade_url": "/pricing"
}
Usage metering
Architecture
Le metering d'usage utilise Redis comme buffer haute-performance :
- Increment Redis : chaque operation incremente un compteur Redis (
tenant:{id}:usage:{type}:{month}) - Flush horaire : tache Celery Beat
flush-usage-countersecrit les compteurs en base - Stockage : table
tenant_usage(db_core) avec granularite mensuelle
Types d'usage mesures
| Type | Description |
|---|---|
products_count | Nombre de produits actifs |
imports_count | Imports lances dans le mois |
ai_enrichments | Enrichissements IA consommes |
api_calls | Appels API externes |
storage_bytes | Espace stockage MinIO utilise |
Stripe Billing
Integration
L'integration Stripe couvre le cycle complet de facturation :
- Checkout : creation de session Stripe Checkout pour les nouveaux abonnements
- Portal : acces au portail client Stripe (gestion carte, factures)
- Webhooks : reception des evenements Stripe (paiement, annulation, upgrade)
Flux d'abonnement
- L'utilisateur choisit un plan sur
/pricing POST /api/v1/billing/checkoutcree une session Stripe- Redirection vers Stripe Checkout
- Webhook
checkout.session.completed: mise a jour du plan tenant - Webhook
invoice.paid: renouvellement confirme
Idempotence webhooks
Les webhooks Stripe sont idempotents grace a la table stripe_webhook_events :
- Chaque
event_idStripe est enregistre - Un evenement deja traite est ignore (HTTP 200 sans action)
- Signature HMAC verifiee via
STRIPE_WEBHOOK_SECRET
Page Pricing
La page publique /pricing affiche :
- Grille des plans avec toggle mensuel/annuel
- Comparaison des fonctionnalites par plan
- CTA vers Stripe Checkout
Page Billing (Settings)
La page /settings/billing affiche pour le tenant connecte :
- Plan actuel et date de renouvellement
- Usage du mois en cours vs quotas
- Historique des factures
- Lien vers le portail Stripe
Endpoints API
| Methode | Endpoint | Description |
|---|---|---|
| GET | /api/v1/billing/plans | Liste des plans disponibles |
| POST | /api/v1/billing/checkout | Creer une session Checkout |
| POST | /api/v1/billing/portal | URL portail client Stripe |
| GET | /api/v1/billing/subscription | Abonnement actuel |
| GET | /api/v1/billing/invoices | Historique factures |
| POST | /api/v1/stripe/webhooks | Webhooks Stripe (public) |
| GET | /api/v1/tenants/ | Liste des tenants (admin) |
| POST | /api/v1/tenants/ | Creer un tenant (admin) |
| GET | /api/v1/tenants/{codename} | Detail tenant |