feat(credits): solde IA unique (option M), packs Stripe et polish billing

Un pot de crédits global (BASIC 100 / PRO 1 000 / BUSINESS 4 000) remplace
les seaux par fonction côté débit. Packs one-shot S/M/L, admin sans seaux
legacy, usage multi-features, hints de coût, anti-flash thème et hydratation
admin. Inclut aussi le pipeline slides renforcé et la page publique polishée.
This commit is contained in:
Antigravity
2026-07-16 20:43:18 +00:00
parent 704fed1191
commit 556a0b2f3f
77 changed files with 35745 additions and 10430 deletions

View File

@@ -1,161 +1,142 @@
# Guide d'utilisation — Admin Facturation & Quotas
# Guide admin — Facturation et crédits IA
## Objectif
La page **Admin > Facturation & Quotas** permet de gérer, sans redéploiement :
La page **Admin Facturation & crédits IA** sert à :
- les limites mensuelles par fonctionnalité IA (par tier)
- les Price IDs Stripe utilisés par le checkout
- l'activation/désactivation de l'interface de facturation
- un aperçu d'usage (requêtes/tokens)
1. Configurer Stripe (prix dabonnement + **packs de crédits** one-shot, activation)
2. **Comprendre le solde de crédits** par palier (source de vérité du débit)
3. Consulter un aperçu dusage agrégé
Le **débit réel** des utilisateurs nest **pas** un plafond par fonction (chat 50, slides 20…).
Cest un **pot unique de crédits** (modèle A, option M).
---
## Accès
1. Connectez-vous avec un compte **ADMIN**.
2. Ouvrez la console admin (`/admin`).
3. Cliquez sur **Facturation & quotas** dans la sidebar.
1. Compte **ADMIN**
2. Console admin **Facturation & crédits IA**
> Si vous n'êtes pas admin, les actions sont refusées côté serveur.
Les actions non-admin sont refusées côté serveur.
---
## Section 1 — Config Stripe (métier)
## 1. Config Stripe (métier)
Cette section sert à configurer les éléments business de Stripe :
### Abonnements
- `STRIPE_PRICE_PRO_MONTHLY`
- `STRIPE_PRICE_PRO_ANNUAL`
- `STRIPE_PRICE_BUSINESS_MONTHLY`
- `STRIPE_PRICE_BUSINESS_ANNUAL`
- toggle **Activer la facturation**
- `STRIPE_PRICE_PRO_MONTHLY` / `ANNUAL`
- `STRIPE_PRICE_BUSINESS_MONTHLY` / `ANNUAL`
- Case **Activer la facturation**
### Procédure
### Packs de crédits (paiement unique)
1. Renseignez/mettez à jour les `price_...` IDs.
2. Activez ou désactivez la facturation via la case.
3. Cliquez sur **Enregistrer la config**.
Produits Stripe en **mode payment** (one-shot), **pas** abonnement :
### Important sécurité
| Clé admin | Pack | Crédits | Prix catalogue (défaut UI) |
|-----------|------|---------|----------------------------|
| `STRIPE_PRICE_CREDITS_S` | S | **100** | 4,90 € |
| `STRIPE_PRICE_CREDITS_M` | M | **500** | 19,90 € |
| `STRIPE_PRICE_CREDITS_L` | L | **2 000** | 49,90 € |
- `STRIPE_SECRET_KEY` et `STRIPE_WEBHOOK_SECRET` **ne sont pas gérés ici**.
- Ils doivent rester dans les secrets d'environnement serveur (Docker/env/vault).
Dans Stripe Dashboard :
1. Créer 3 **Products** one-time (ex. « Memento crédits S / M / L »)
2. Prix uniques (EUR)
3. Copier les `price_...` dans Admin → Facturation
4. Webhook : événement `checkout.session.completed` déjà géré (mode `payment` + metadata `type=credit_pack`)
Les secrets (`STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`) restent dans lenvironnement serveur (Docker), **jamais** dans cette page.
---
## Section 2 — Quotas par palier
## 2. Crédits IA par palier (source de vérité)
Vous pouvez définir, pour chaque tier (**BASIC**, **PRO**, **BUSINESS**, **ENTERPRISE**) :
### Allocations mensuelles (option M)
- **Indisponible** : fonctionnalité non accessible
- **Limité** : plafond mensuel (nombre entier >= 0)
- **Illimité** : pas de plafond
| Palier | Crédits / mois | Notes |
|--------|----------------|--------|
| **BASIC** | **100** | Découverte |
| **PRO** | **1 000** | Aligné marché type « ~1 000 crédits » Pro |
| **BUSINESS** | **4 000** | Usage intensif / équipe |
| **ENTERPRISE** | **Illimité** | Contrat |
### Procédure
Ces valeurs sont définies dans le code : `lib/credits.ts``CREDIT_ALLOCATIONS`.
Elles sappliquent au premier usage / grant de période, et après **reset** utilisateur.
1. Cliquez sur le tier ciblé.
2. Pour chaque fonctionnalité :
- choisissez le mode d'accès
- si mode **Limité**, entrez la valeur mensuelle
3. Cliquez sur **Enregistrer** sur la ligne concernée.
### Packs achetés
### Délai d'effet
- Crédités via `addPurchasedCredits` (ledger `PURCHASE_PACK`)
- Stockés dans `purchasedBalance`**reportables** dun mois à lautre
- Consommés **après** lallocation abonnement du mois
Les changements sont appliqués rapidement (cache), en général sous **~60 secondes**.
### Coûts typiques (extrait)
| Action | Coût |
|--------|------|
| Recherche, chat, étiquettes, titres, reformulation… | **1** crédit |
| Flashcards, publication IA | **3** |
| Diagramme Excalidraw | **4** |
| Création brainstorm | **5** |
| **Présentation** (note) | **1 + N** (N = nombre de diapositives, 38) |
Exemple : 7 diapositives ≈ **8 crédits**.
### Réinitialiser un utilisateur
**Admin → Utilisateurs** → bouton **réinitialiser les crédits** sur la ligne du compte.
Cela recharge lallocation du palier pour le mois en cours (journal `ADMIN_RESET`). Les packs achetés sont **conservés** par défaut.
### Clé personnelle (BYOK)
Si lutilisateur a une clé active pour la voie concernée (chat / tags / embeddings), lusage **ne débite en général pas** le solde Memento.
---
## Section 3 — Aperçu consommation
## 3. Aperçu consommation
La section affiche :
- Agrégats par fonction (historique PostgreSQL / sync)
- Top utilisateurs
- Sync : cron `/api/cron/sync-usage` (compteurs legacy éventuels)
- usage par fonctionnalité (requêtes + tokens)
- top utilisateurs
- date de dernière synchronisation
### Source des données
- Compteurs temps réel : Redis
- Consolidation historique : table `UsageLog`
- Sync via cron (`/api/cron/sync-usage`)
Si la synchronisation n'a pas encore tourné, l'interface peut indiquer un état non synchronisé.
Le compteur **utilisateur** (sidebar / facturation) affiche le **solde de crédits** et la **répartition par fonction** (journal des consommations).
---
## Cas d'usage fréquents
## 4. Côté produit (rappel)
## 1) Augmenter temporairement le quota chat de PRO
1. Tier: **PRO**
2. Ligne `chat` -> mode **Limité**
3. Mettre par exemple `50 -> 100`
4. **Enregistrer**
## 2) Désactiver la vente (maintenance Stripe)
1. Décochez **Activer la facturation**
2. **Enregistrer la config**
3. Vérifiez côté utilisateur: `/settings/billing` montre l'état désactivé
## 3) Rendre une feature inaccessible en BASIC
1. Tier: **BASIC**
2. Ligne feature -> mode **Indisponible**
3. **Enregistrer**
| Surface | Message attendu |
|---------|-----------------|
| Landing / tarifs | Basic 100 · Pro 1 000 · Business 4 000 crédits / mois |
| Paramètres facturation | Même grille + **acheter des packs** (S/M/L) |
| Sidebar | Solde restant + tableau multi-fonctions |
| Publication IA / diagramme | Hint coût (3 / 4 crédits) |
| Fin de solde | Plan supérieur, pack de crédits, ou clé personnelle |
---
## Validation rapide après changement
## 5. Délai deffet
Après une modification importante, vérifier :
1. Le toast de succès en admin
2. Le comportement côté utilisateur (`/settings/billing` / appels IA)
3. Les logs serveur en cas d'erreur
4. L'`AuditLog` pour tracer qui a modifié quoi
- Allocations code : au prochain grant / reset / appel `ensureCreditAccount`
- Config Stripe (abos + packs) : immédiat après enregistrement
- Crédit pack après paiement : webhook `checkout.session.completed` (+ filet de sécurité sur `/api/billing/status?session_id=`)
---
## Dépannage
## 6. Fichiers techniques de référence
## "Le bouton Enregistrer ne semble rien faire"
- Vérifiez que vous êtes bien connecté en ADMIN.
- Regardez le toast d'erreur.
- Vérifiez les logs serveur (action rejetée, validation invalide, etc.).
## "Les quotas ne changent pas immédiatement"
- Attendez ~60 secondes (cache).
- Relancez une action IA qui consomme réellement le quota.
- Vérifiez que la feature est bien en mode attendu (indisponible/limité/illimité).
## "Le checkout ne démarre pas"
- Vérifiez les 4 `STRIPE_PRICE_*` IDs.
- Vérifiez que la facturation est activée.
- Vérifiez que les secrets Stripe serveur sont présents (`STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`).
| Rôle | Fichier |
|------|---------|
| Allocations + coûts + réserve + packs ledger | `lib/credits.ts` |
| Catalogue packs + price IDs | `lib/billing/credit-packs.ts` |
| Checkout pack | `app/api/billing/create-pack-checkout/route.ts` |
| Webhook abo + pack | `app/api/billing/webhook/route.ts` |
| UI admin | `app/(admin)/admin/billing/billing-admin-client.tsx` |
| UI facturation utilisateur | `components/settings/billing-plans.tsx` |
---
## Bonnes pratiques d'exploitation
- Éviter les changements massifs sans validation progressive.
- Journaliser les changements critiques (tiers très utilisés).
- Préférer des paliers de quota cohérents entre fonctionnalités similaires.
- Garder un rituel de revue hebdo des usages (section Aperçu consommation).
---
## Référence technique (fichiers clés)
- `app/(admin)/admin/billing/page.tsx`
- `app/(admin)/admin/billing/billing-admin-client.tsx`
- `app/actions/admin-billing.ts`
- `lib/plan-entitlements.ts`
- `lib/entitlements.ts`
- `lib/billing/stripe-prices.ts`
- `app/api/billing/status/route.ts`
## Note legacy
Le modèle `PlanEntitlement` (anciens seaux par fonction) peut encore exister en base pour déventuels garde-fous « fonction indisponible », mais **napparaît plus** dans lUI admin et **ne pilote plus** le débit principal.