docs: enrichir ARCHITECTURE, DEVELOPMENT_PRINCIPLES, GOLDEN_DATASET, TESTS_AUTOMATISES, TEST_ENVIRONMENT
This commit is contained in:
parent
52b8e9d011
commit
f343fb4696
5 changed files with 1649 additions and 1476 deletions
|
|
@ -1,365 +1,260 @@
|
|||
# TEST_ENVIRONMENT.md — Expria / Coach TCF Canada
|
||||
# TEST_ENVIRONMENT.md — Expria Frontend
|
||||
|
||||
> **Document de référence — Version 1.0**
|
||||
> Ce document décrit comment créer et réinitialiser l'environnement de test.
|
||||
> Les comptes de test permettent de rejouer tous les parcours utilisateur
|
||||
> sans créer de vrais abonnements ni passer par Stripe.
|
||||
> Ce document décrit comment configurer et utiliser l'environnement de test frontend.
|
||||
> Complément au `TEST_ENVIRONMENT.md` backend (qui décrit la base de données Supabase et les comptes de test).
|
||||
|
||||
---
|
||||
|
||||
## 1. Principe
|
||||
|
||||
L'environnement de test est une configuration connue et reproductible de la base de données.
|
||||
Il consiste en 4 comptes Supabase préconfigurés, un par situation critique.
|
||||
L'environnement de test frontend permet de faire tourner le code React localement, connecté soit au backend de production (`api.expria.app`), soit à une instance backend locale (pour tests isolés).
|
||||
|
||||
**Règles absolues :**
|
||||
- Ces comptes n'existent que dans l'environnement de développement / staging
|
||||
- Jamais en production
|
||||
- Les emails se terminent par `@expria.local` — bloqués à l'inscription dans le code
|
||||
- Les mots de passe sont documentés ici — ne jamais les utiliser pour de vrais comptes
|
||||
- Ne jamais utiliser de comptes réels (utilisateurs payants) pour les tests
|
||||
- Utiliser exclusivement les 4 comptes `@gmail.com` documentés dans le backend
|
||||
- Ne jamais committer les fichiers `.env` (présents dans `.gitignore`)
|
||||
|
||||
---
|
||||
|
||||
## 2. Les 4 comptes de test
|
||||
## 2. Prérequis
|
||||
|
||||
| Compte | Plan | simulations_used | Cas testé |
|
||||
| Outil | Version minimum | Vérification |
|
||||
|---|---|---|
|
||||
| Node.js | 20.x LTS | `node --version` |
|
||||
| npm | 10.x | `npm --version` |
|
||||
| Git | 2.x | `git --version` |
|
||||
| Navigateur moderne | Chrome 120+, Firefox 120+, Safari 17+ | — |
|
||||
|
||||
Recommandé :
|
||||
- VS Code (ou Cursor) avec extensions : ESLint, Prettier, Tailwind CSS IntelliSense, Vitest
|
||||
- DevTools React (extension navigateur)
|
||||
|
||||
---
|
||||
|
||||
## 3. Configuration — mode dev connecté au backend de production
|
||||
|
||||
C'est le mode par défaut. Le frontend local appelle `https://api.expria.app`.
|
||||
|
||||
### Fichier `.env` à créer à la racine du projet
|
||||
|
||||
```
|
||||
# URL du backend de production
|
||||
VITE_API_URL=https://api.expria.app
|
||||
|
||||
# Supabase (clé publique uniquement)
|
||||
VITE_SUPABASE_URL=https://<project>.supabase.co
|
||||
VITE_SUPABASE_ANON_KEY=<clé publique à obtenir auprès de Hermann>
|
||||
|
||||
# Flags de features (à ajuster selon le sprint)
|
||||
VITE_ENABLE_T2_LIVE=false
|
||||
|
||||
# Monitoring (optionnel)
|
||||
VITE_SENTRY_DSN=
|
||||
```
|
||||
|
||||
**Les vraies valeurs** sont à récupérer dans :
|
||||
- Le coffre-fort de Hermann (1Password / Bitwarden)
|
||||
- Ou auprès de Hermann directement
|
||||
|
||||
Après modification du `.env`, redémarrer le dev server (Vite charge les env au démarrage seulement).
|
||||
|
||||
### Lancement
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Le frontend est disponible sur `http://localhost:5173` (port Vite par défaut).
|
||||
|
||||
---
|
||||
|
||||
## 4. Configuration — mode dev connecté au backend local
|
||||
|
||||
Utile quand on veut :
|
||||
- Tester une modification backend avant déploiement
|
||||
- Déboguer un flux complet frontend + backend
|
||||
- Travailler sans connexion internet stable
|
||||
|
||||
### Prérequis
|
||||
|
||||
Le backend doit tourner localement dans un autre terminal :
|
||||
```bash
|
||||
cd D:\expria-backend
|
||||
npm run dev
|
||||
# Backend disponible sur http://localhost:3000 (vérifier le port exact)
|
||||
```
|
||||
|
||||
### Fichier `.env` (ajustement)
|
||||
|
||||
```
|
||||
VITE_API_URL=http://localhost:3000
|
||||
# Le reste reste identique
|
||||
```
|
||||
|
||||
### Points d'attention
|
||||
|
||||
- **CORS** : le backend doit autoriser `http://localhost:5173` dans sa configuration CORS. À vérifier dans `expria-backend/src/index.ts`. Si CORS bloque les requêtes, voir SEC-02 dans `SECURITY.md`.
|
||||
- **WebSocket T2** : devient `ws://localhost:3000/t2/live` (non sécurisé en dev local). Acceptable pour le dev.
|
||||
- **Supabase** : reste en production même en dev local (Supabase n'a pas de mode local simple). Les comptes de test `@gmail.com` fonctionnent identiquement.
|
||||
|
||||
---
|
||||
|
||||
## 5. Comptes de test (rappel)
|
||||
|
||||
Identiques aux comptes documentés dans `expria-backend/docs/TEST_ENVIRONMENT.md` :
|
||||
|
||||
| Email | Plan | Simulations utilisées | Cas testé |
|
||||
|---|---|---|---|
|
||||
| test.free@expria.local | free | 0 | Parcours Free normal |
|
||||
| test.standard@expria.local | standard | 12 | Parcours Standard complet |
|
||||
| test.premium@expria.local | premium | 28 | Parcours Premium complet |
|
||||
| test.quota@expria.local | free | 5 | Blocage quota Free |
|
||||
| test.free@gmail.com | free | 0 | Parcours Free normal |
|
||||
| test.standard@gmail.com | standard | 12 | Parcours Standard complet |
|
||||
| test.premium@gmail.com | premium | 28 | Parcours Premium complet |
|
||||
| test.quota@gmail.com | free | 5 | Blocage quota Free |
|
||||
|
||||
**Mot de passe pour tous les comptes de test :** `Expria2025!test`
|
||||
**Mot de passe commun :** `Expria2025!test`
|
||||
|
||||
Les comptes sont créés par le script SQL de `expria-backend/docs/TEST_ENVIRONMENT.md` §3. Si un compte manque ou est corrompu, demander à Hermann de rejouer le script côté Supabase.
|
||||
|
||||
---
|
||||
|
||||
## 3. Script de création — à exécuter dans Supabase SQL Editor
|
||||
## 6. Scénarios de test spécifiques
|
||||
|
||||
> ⚠️ À exécuter UNE SEULE FOIS dans l'environnement de développement.
|
||||
> Ne jamais exécuter en production.
|
||||
### 6.1 Simuler un utilisateur Free qui atteint le quota
|
||||
|
||||
```sql
|
||||
-- =============================================================
|
||||
-- EXPRIA — Création des comptes de test
|
||||
-- Environnement : développement / staging uniquement
|
||||
-- =============================================================
|
||||
1. Se connecter avec `test.free@gmail.com`
|
||||
2. Utiliser `test.quota@gmail.com` à la place (qui a déjà 5/5 utilisées)
|
||||
3. Tenter de lancer une simulation → modal de blocage doit apparaître
|
||||
|
||||
-- Étape 1 : Créer les utilisateurs dans auth.users
|
||||
-- (Supabase gère le hash du mot de passe automatiquement)
|
||||
**Ne pas** essayer de forcer le compteur en soumettant 5 simulations réelles — ça consomme des appels à DeepSeek (payant) et pollue la base.
|
||||
|
||||
INSERT INTO auth.users (
|
||||
id,
|
||||
email,
|
||||
encrypted_password,
|
||||
email_confirmed_at,
|
||||
created_at,
|
||||
updated_at,
|
||||
raw_app_meta_data,
|
||||
raw_user_meta_data,
|
||||
is_super_admin,
|
||||
role
|
||||
) VALUES
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'test.free@expria.local',
|
||||
crypt('Expria2025!test', gen_salt('bf')),
|
||||
NOW(), NOW(), NOW(),
|
||||
'{"provider":"email","providers":["email"]}',
|
||||
'{}', false, 'authenticated'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000002',
|
||||
'test.standard@expria.local',
|
||||
crypt('Expria2025!test', gen_salt('bf')),
|
||||
NOW(), NOW(), NOW(),
|
||||
'{"provider":"email","providers":["email"]}',
|
||||
'{}', false, 'authenticated'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000003',
|
||||
'test.premium@expria.local',
|
||||
crypt('Expria2025!test', gen_salt('bf')),
|
||||
NOW(), NOW(), NOW(),
|
||||
'{"provider":"email","providers":["email"]}',
|
||||
'{}', false, 'authenticated'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000004',
|
||||
'test.quota@expria.local',
|
||||
crypt('Expria2025!test', gen_salt('bf')),
|
||||
NOW(), NOW(), NOW(),
|
||||
'{"provider":"email","providers":["email"]}',
|
||||
'{}', false, 'authenticated'
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
### 6.2 Simuler un changement de plan
|
||||
|
||||
-- Étape 2 : Créer les profils dans la table profiles
|
||||
INSERT INTO profiles (
|
||||
id,
|
||||
email,
|
||||
plan,
|
||||
simulations_used,
|
||||
stripe_customer_id,
|
||||
stripe_subscription_id,
|
||||
plan_expires_at,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'test.free@expria.local',
|
||||
'free', 0, NULL, NULL, NULL,
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000002',
|
||||
'test.standard@expria.local',
|
||||
'standard', 12, 'cus_test_standard', 'sub_test_standard',
|
||||
NOW() + INTERVAL '14 days',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000003',
|
||||
'test.premium@expria.local',
|
||||
'premium', 28, 'cus_test_premium', 'sub_test_premium',
|
||||
NOW() + INTERVAL '21 days',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000004',
|
||||
'test.quota@expria.local',
|
||||
'free', 5, NULL, NULL, NULL,
|
||||
NOW(), NOW()
|
||||
)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
plan = EXCLUDED.plan,
|
||||
simulations_used = EXCLUDED.simulations_used,
|
||||
stripe_customer_id = EXCLUDED.stripe_customer_id,
|
||||
stripe_subscription_id = EXCLUDED.stripe_subscription_id,
|
||||
plan_expires_at = EXCLUDED.plan_expires_at,
|
||||
updated_at = NOW();
|
||||
Pour tester le flux d'upgrade sans vraiment payer :
|
||||
1. Aller sur `/pricing` avec `test.free@gmail.com`
|
||||
2. Cliquer "Choisir Standard"
|
||||
3. Sur la page Stripe Checkout, utiliser la carte de test `4242 4242 4242 4242`
|
||||
4. Date d'expiration : n'importe laquelle dans le futur
|
||||
5. CVC : n'importe lequel (3 chiffres)
|
||||
|
||||
-- Étape 3 : Insérer des productions de test pour les comptes Standard et Premium
|
||||
-- (nécessaire pour tester le dashboard, l'historique, et l'analyse des patterns)
|
||||
Le webhook Stripe met à jour `plan = 'standard'` dans Supabase. Pour revenir à l'état initial après test, Hermann peut rejouer le script de reset de `expria-backend/docs/TEST_ENVIRONMENT.md` §5.
|
||||
|
||||
INSERT INTO productions (
|
||||
id, user_id, tache, mode, contenu, score, nclc, rapport, created_at
|
||||
) VALUES
|
||||
-- 5 productions pour test.standard (active l'indice de préparation)
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002',
|
||||
'EE_T1', 'entrainement',
|
||||
'Texte de production test EE T1 — compte standard',
|
||||
14.5, 8,
|
||||
'{"criteres":[{"nom":"Cohérence","score":3},{"nom":"Lexique","score":4}],"erreurs":["Connecteurs logiques insuffisants"],"exercices":["Exercice connecteurs"]}',
|
||||
NOW() - INTERVAL '10 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002',
|
||||
'EE_T2', 'entrainement',
|
||||
'Texte de production test EE T2 — compte standard',
|
||||
15.0, 8,
|
||||
'{"criteres":[{"nom":"Cohérence","score":4},{"nom":"Lexique","score":3}],"erreurs":["Vocabulaire limité"],"exercices":["Exercice vocabulaire"]}',
|
||||
NOW() - INTERVAL '8 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002',
|
||||
'EE_T3', 'entrainement',
|
||||
'Texte de production test EE T3 — compte standard',
|
||||
13.5, 7,
|
||||
'{"criteres":[{"nom":"Cohérence","score":3},{"nom":"Lexique","score":3}],"erreurs":["Structure argumentative faible"],"exercices":["Exercice argumentation"]}',
|
||||
NOW() - INTERVAL '6 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002',
|
||||
'EO_T1', 'entrainement',
|
||||
NULL, 14.0, 8,
|
||||
'{"criteres":[{"nom":"Phonologie","score":4},{"nom":"Lexique","score":3}],"erreurs":["Liaisons manquantes"],"exercices":["Exercice liaisons"]}',
|
||||
NOW() - INTERVAL '4 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002',
|
||||
'EO_T3', 'entrainement',
|
||||
NULL, 15.5, 9,
|
||||
'{"criteres":[{"nom":"Phonologie","score":4},{"nom":"Lexique","score":4}],"erreurs":[],"exercices":[]}',
|
||||
NOW() - INTERVAL '2 days'),
|
||||
### 6.3 Simuler un paiement refusé
|
||||
|
||||
-- 7 productions pour test.premium (active patterns + indice)
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EE_T1', 'entrainement',
|
||||
'Texte production EE T1 — premium',
|
||||
16.0, 9,
|
||||
'{"criteres":[{"nom":"Cohérence","score":4},{"nom":"Lexique","score":4}],"erreurs":["Connecteurs logiques"],"exercices":["Connecteurs"]}',
|
||||
NOW() - INTERVAL '20 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EE_T2', 'entrainement',
|
||||
'Texte production EE T2 — premium',
|
||||
15.5, 9,
|
||||
'{"criteres":[{"nom":"Cohérence","score":4},{"nom":"Lexique","score":4}],"erreurs":["Connecteurs logiques"],"exercices":["Connecteurs"]}',
|
||||
NOW() - INTERVAL '16 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EE_T3', 'examen',
|
||||
'Texte production EE T3 — premium examen',
|
||||
17.0, 10,
|
||||
'{"criteres":[{"nom":"Cohérence","score":5},{"nom":"Lexique","score":4}],"erreurs":[],"exercices":[]}',
|
||||
NOW() - INTERVAL '12 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EO_T1', 'entrainement',
|
||||
NULL, 16.5, 9,
|
||||
'{"criteres":[{"nom":"Phonologie","score":4},{"nom":"Lexique","score":4}],"erreurs":["Connecteurs logiques"],"exercices":["Connecteurs oraux"]}',
|
||||
NOW() - INTERVAL '9 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EO_T2_LIVE', 'entrainement',
|
||||
NULL, 15.0, 8,
|
||||
'{"criteres":[{"nom":"Interaction","score":4},{"nom":"Phonologie","score":3}],"erreurs":["Hésitations fréquentes"],"exercices":["Fluidité orale"]}',
|
||||
NOW() - INTERVAL '6 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EO_T3', 'entrainement',
|
||||
NULL, 16.0, 9,
|
||||
'{"criteres":[{"nom":"Phonologie","score":4},{"nom":"Lexique","score":4}],"erreurs":["Connecteurs logiques"],"exercices":["Connecteurs oraux"]}',
|
||||
NOW() - INTERVAL '3 days'),
|
||||
(gen_random_uuid(), '00000000-0000-0000-0000-000000000003',
|
||||
'EE_T1', 'examen',
|
||||
'Texte production EE T1 examen — premium',
|
||||
17.5, 10,
|
||||
'{"criteres":[{"nom":"Cohérence","score":5},{"nom":"Lexique","score":4}],"erreurs":[],"exercices":[]}',
|
||||
NOW() - INTERVAL '1 day')
|
||||
ON CONFLICT DO NOTHING;
|
||||
Même flux que 6.2 mais avec la carte `4000 0000 0000 0002`. Stripe retourne "paiement refusé". Le plan reste inchangé, le message d'erreur doit s'afficher clairement.
|
||||
|
||||
### 6.4 Simuler une session expirée
|
||||
|
||||
1. Se connecter normalement
|
||||
2. Ouvrir DevTools → Application → Local Storage
|
||||
3. Trouver la clé contenant le JWT Supabase (`sb-<project>-auth-token`)
|
||||
4. Modifier la valeur pour casser le token (changer 1 caractère)
|
||||
5. Rafraîchir la page
|
||||
6. Le frontend doit détecter le JWT invalide → message "Session expirée" + redirect `/login`
|
||||
|
||||
Ce test vérifie SEC-06 (gestion des sessions expirées).
|
||||
|
||||
### 6.5 Simuler T2 Live sans avoir Premium
|
||||
|
||||
1. Se connecter avec `test.free@gmail.com` ou `test.standard@gmail.com`
|
||||
2. Accéder à l'URL `/t2-live` directement
|
||||
3. Le frontend doit afficher un PaywallModal ou rediriger
|
||||
4. Si malgré tout une requête WebSocket est envoyée, le backend doit fermer la connexion avec close code 4003 (`PLAN_INSUFFICIENT`)
|
||||
|
||||
---
|
||||
|
||||
## 7. Matrice de compatibilité navigateurs
|
||||
|
||||
Ces navigateurs sont ceux que Claude Code doit considérer comme supportés. Tester au minimum sur les deux premiers.
|
||||
|
||||
| Navigateur | Version minimum | Priorité de test | Notes |
|
||||
|---|---|---|---|
|
||||
| Chrome (desktop) | 120 | 🔴 obligatoire | Majoritaire chez les utilisateurs |
|
||||
| Chrome Mobile (Android) | 120 | 🔴 obligatoire | Audience Afrique = mobile-first |
|
||||
| Safari Mobile (iOS) | 17 | 🟡 recommandé | Audience Canada = iPhone courant |
|
||||
| Firefox (desktop) | 120 | 🟢 optionnel | Usage faible |
|
||||
| Safari Desktop | 17 | 🟢 optionnel | Niche |
|
||||
|
||||
**Attention particulière pour mobile Android (Afrique) :**
|
||||
- Connexions 3G/4G instables → vérifier que retry dans `api-client.ts` gère bien
|
||||
- RAM limitée → éviter les listes illimitées, paginer
|
||||
- Clavier virtuel qui masque les inputs → vérifier scroll automatique
|
||||
|
||||
Test mobile rapide via DevTools : Chrome → F12 → Toggle device toolbar → sélectionner "iPhone 12" ou "Galaxy S20".
|
||||
|
||||
Test mobile réel : idéal avant chaque release production, via un vrai téléphone ou un service comme BrowserStack (payant).
|
||||
|
||||
---
|
||||
|
||||
## 8. Simulation de conditions réseau dégradées
|
||||
|
||||
Dans Chrome DevTools → Network tab → Throttling dropdown :
|
||||
- **Fast 3G** : simule une connexion 3G typique (Afrique)
|
||||
- **Slow 3G** : simule une connexion 2G (zones rurales)
|
||||
- **Offline** : simule une perte réseau
|
||||
|
||||
Tests à effectuer en mode "Fast 3G" :
|
||||
- Login : doit répondre en < 10s
|
||||
- Submit simulation : timeout à 30s doit fonctionner
|
||||
- T2 Live : doit tenir la connexion WebSocket ou échouer gracieusement
|
||||
|
||||
---
|
||||
|
||||
## 9. Procédure avant chaque session Claude Code
|
||||
|
||||
```
|
||||
[ ] D:\expria-frontend existe et contient docs/ à jour
|
||||
[ ] .env est configuré (demander à Hermann si nécessaire)
|
||||
[ ] npm install a été exécuté récemment (dernière modification package.json)
|
||||
[ ] npm run dev démarre sans erreur
|
||||
[ ] Login test.free@gmail.com fonctionne
|
||||
[ ] Un commit Git propre existe avant de commencer
|
||||
[ ] Les documents de référence ont été lus (cf. ONBOARDING.md §7)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Script de vérification — confirmer que les comptes existent
|
||||
## 10. Procédure après chaque session Claude Code
|
||||
|
||||
```sql
|
||||
-- Vérifier les profils créés
|
||||
SELECT
|
||||
id,
|
||||
email,
|
||||
plan,
|
||||
simulations_used,
|
||||
plan_expires_at
|
||||
FROM profiles
|
||||
WHERE email LIKE '%@expria.local'
|
||||
ORDER BY email;
|
||||
|
||||
-- Vérifier les productions créées
|
||||
SELECT
|
||||
p.email,
|
||||
prod.tache,
|
||||
prod.mode,
|
||||
prod.score,
|
||||
prod.created_at
|
||||
FROM productions prod
|
||||
JOIN profiles p ON p.id = prod.user_id
|
||||
WHERE p.email LIKE '%@expria.local'
|
||||
ORDER BY p.email, prod.created_at;
|
||||
```
|
||||
|
||||
**Résultat attendu :** 4 profils, 12 productions au total.
|
||||
|
||||
---
|
||||
|
||||
## 5. Script de réinitialisation — remettre l'environnement à zéro
|
||||
|
||||
> À utiliser quand les comptes de test ont été modifiés par des sessions de test
|
||||
> et qu'on veut repartir d'un état propre.
|
||||
|
||||
```sql
|
||||
-- Supprimer les productions de test
|
||||
DELETE FROM productions
|
||||
WHERE user_id IN (
|
||||
SELECT id FROM profiles WHERE email LIKE '%@expria.local'
|
||||
);
|
||||
|
||||
-- Remettre les profils à leur état initial
|
||||
UPDATE profiles SET
|
||||
plan = 'free',
|
||||
simulations_used = 0,
|
||||
stripe_customer_id = NULL,
|
||||
stripe_subscription_id = NULL,
|
||||
plan_expires_at = NULL,
|
||||
updated_at = NOW()
|
||||
WHERE email = 'test.free@expria.local';
|
||||
|
||||
UPDATE profiles SET
|
||||
plan = 'standard',
|
||||
simulations_used = 12,
|
||||
stripe_customer_id = 'cus_test_standard',
|
||||
stripe_subscription_id = 'sub_test_standard',
|
||||
plan_expires_at = NOW() + INTERVAL '14 days',
|
||||
updated_at = NOW()
|
||||
WHERE email = 'test.standard@expria.local';
|
||||
|
||||
UPDATE profiles SET
|
||||
plan = 'premium',
|
||||
simulations_used = 28,
|
||||
stripe_customer_id = 'cus_test_premium',
|
||||
stripe_subscription_id = 'sub_test_premium',
|
||||
plan_expires_at = NOW() + INTERVAL '21 days',
|
||||
updated_at = NOW()
|
||||
WHERE email = 'test.premium@expria.local';
|
||||
|
||||
UPDATE profiles SET
|
||||
plan = 'free',
|
||||
simulations_used = 5,
|
||||
stripe_customer_id = NULL,
|
||||
stripe_subscription_id = NULL,
|
||||
plan_expires_at = NULL,
|
||||
updated_at = NOW()
|
||||
WHERE email = 'test.quota@expria.local';
|
||||
|
||||
-- Réinsérer les productions (copier-coller le bloc INSERT de la section 3)
|
||||
[ ] npm run typecheck : 0 erreur
|
||||
[ ] npm run test : 0 échec
|
||||
[ ] Les tests du Golden Dataset concernés ont été rejoués (cf. GOLDEN_DATASET.md)
|
||||
[ ] Si modifications d'état (profils de test modifiés par des actions de test),
|
||||
rejouer le script de reset backend
|
||||
[ ] Un commit Git a été fait avec un message clair
|
||||
[ ] CHANGELOG.md mis à jour
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Bloquer les inscriptions @expria.local en production
|
||||
## 11. Debugging
|
||||
|
||||
Ajouter cette validation dans le backend (middleware d'inscription) :
|
||||
### Erreur "CORS blocked" au démarrage
|
||||
- Vérifier que le backend autorise `http://localhost:5173`
|
||||
- Vérifier que `VITE_API_URL` dans `.env` pointe vers la bonne URL backend
|
||||
- Voir SEC-02 dans `SECURITY.md`
|
||||
|
||||
```typescript
|
||||
// src/middleware/auth.ts — backend Hono
|
||||
### Erreur "Invalid JWT" après login
|
||||
- Le JWT expire au bout de ~1h, se déconnecter et se reconnecter
|
||||
- Vider le localStorage (DevTools → Application → Clear site data)
|
||||
- Vérifier que `VITE_SUPABASE_URL` correspond bien au projet Supabase utilisé par le backend
|
||||
|
||||
const BLOCKED_EMAIL_DOMAINS = ['@expria.local']
|
||||
### Les variables d'environnement ne sont pas prises en compte
|
||||
- Vite charge `.env` au démarrage uniquement — redémarrer `npm run dev` après modification
|
||||
- Les variables doivent commencer par `VITE_` pour être exposées côté client
|
||||
- Vérifier qu'il n'y a pas d'espace autour du `=` dans `.env`
|
||||
|
||||
export function validateEmail(email: string): boolean {
|
||||
const isBlocked = BLOCKED_EMAIL_DOMAINS.some(domain =>
|
||||
email.toLowerCase().endsWith(domain)
|
||||
)
|
||||
if (isBlocked) return false
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
Et dans la route d'inscription :
|
||||
|
||||
```typescript
|
||||
// src/routes/auth.ts
|
||||
|
||||
app.post('/auth/register', async (c) => {
|
||||
const { email, password } = await c.req.json()
|
||||
|
||||
if (!validateEmail(email)) {
|
||||
return c.json({ error: 'Email non autorisé' }, 400)
|
||||
}
|
||||
// ... suite de l'inscription
|
||||
})
|
||||
```
|
||||
### WebSocket T2 Live ne se connecte pas
|
||||
- Vérifier `VITE_ENABLE_T2_LIVE=true` dans `.env`
|
||||
- Vérifier que l'utilisateur est bien Premium
|
||||
- Ouvrir DevTools → Network → filtrer par "WS" pour voir le handshake WebSocket
|
||||
- Vérifier les close codes : 4001 = auth, 4003 = plan insuffisant
|
||||
|
||||
---
|
||||
|
||||
## 7. Procédure complète — première mise en place
|
||||
## 12. Historique
|
||||
|
||||
```
|
||||
Étape 1 : Ouvrir Supabase Dashboard → SQL Editor
|
||||
Étape 2 : Copier-coller le script de la section 3
|
||||
Étape 3 : Exécuter
|
||||
Étape 4 : Copier-coller le script de vérification (section 4)
|
||||
Étape 5 : Vérifier : 4 profils + 12 productions affichés
|
||||
Étape 6 : Tester une connexion avec test.free@expria.local
|
||||
dans l'application (mot de passe : Expria2025!test)
|
||||
Étape 7 : Vérifier que le dashboard Free s'affiche correctement
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Procédure — avant chaque session Golden Dataset
|
||||
|
||||
```
|
||||
Étape 1 : Exécuter le script de réinitialisation (section 5)
|
||||
Étape 2 : Exécuter le script de vérification (section 4)
|
||||
Étape 3 : Confirmer que les 4 profils sont dans l'état attendu
|
||||
Étape 4 : Lancer les tests du Golden Dataset
|
||||
```
|
||||
| Version | Date | Changements |
|
||||
|---|---|---|
|
||||
| 1.0 | 2026-04-17 | Création initiale |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue