feat(corrections/eo): évaluation phonologique Gemini — 5 critères × /4 (Sprint 4.8)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
34b4bcdd82
commit
ec0598d122
15 changed files with 2086 additions and 290 deletions
|
|
@ -13,6 +13,7 @@
|
|||
## 1. Stubs temporaires — à compléter
|
||||
|
||||
### TD-01 — src/lib/supabase.ts (backend)
|
||||
|
||||
**Priorité :** 🔴 Critique
|
||||
**Statut :** Ouvert
|
||||
**Description :** Client Supabase créé comme stub. Fonctionne en développement avec les variables d'environnement mais n'a pas de gestion d'erreur robuste si `SUPABASE_URL` ou `SUPABASE_SERVICE_ROLE_KEY` sont absentes.
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
---
|
||||
|
||||
### TD-02 — src/lib/planController.ts (backend)
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — session Stripe
|
||||
**Description :** Stub créé pour permettre les tests de `updateUserPlan`. La vraie implémentation (mise à jour Supabase + gestion Stripe) n'est pas encore codée.
|
||||
|
|
@ -31,6 +33,7 @@
|
|||
---
|
||||
|
||||
### TD-03 — src/lib/stripe.ts (backend)
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — session Stripe
|
||||
**Description :** Stub créé pour permettre les tests de `verifyStripeWebhook` et `calculateProrata`. La vraie implémentation Stripe n'est pas encore codée.
|
||||
|
|
@ -42,6 +45,7 @@
|
|||
## 2. Décisions pragmatiques — à revisiter
|
||||
|
||||
### TD-04 — Déploiement manuel (frontend + backend)
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Ouvert — accepté jusqu'aux premiers revenus
|
||||
**Description :** Cloudflare Pages et Render ne supportent pas l'auto-deploy depuis Codeberg. Le déploiement est manuel (CLI + dashboard).
|
||||
|
|
@ -51,31 +55,36 @@
|
|||
---
|
||||
|
||||
### TD-05 — Comptes de test avec emails @gmail.com
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Ouvert
|
||||
**Description :** Les comptes de test utilisent `@gmail.com` au lieu de `@expria.local` prévu dans TEST_ENVIRONMENT.md. Raison : Supabase bloque la création d'utilisateurs avec des domaines non standards via l'API admin, et le dashboard est inaccessible depuis la Russie.
|
||||
**Emails actuels :**
|
||||
|
||||
- `test.free@gmail.com`
|
||||
- `test.standard@gmail.com`
|
||||
- `test.premium@gmail.com`
|
||||
- `test.quota@gmail.com`
|
||||
**À faire :** Mettre à jour TEST_ENVIRONMENT.md pour refléter les vrais emails. Vérifier que la validation `@expria.local` dans le middleware n'est pas implémentée (elle ne l'est pas).
|
||||
**À faire :** Mettre à jour TEST_ENVIRONMENT.md pour refléter les vrais emails. Vérifier que la validation `@expria.local` dans le middleware n'est pas implémentée (elle ne l'est pas).
|
||||
|
||||
---
|
||||
|
||||
### TD-06 — Pas de migration SQL versionnée pour les tables initiales
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Ouvert
|
||||
**Description :** Les tables `profiles` et `productions` ont été créées directement via SQL Editor, sans fichier de migration dans `supabase/migrations/`. Viole la Règle F de DEVELOPMENT_PRINCIPLES.md.
|
||||
**À faire :** Créer les fichiers de migration correspondants :
|
||||
|
||||
- `supabase/migrations/001_create_profiles.sql`
|
||||
- `supabase/migrations/002_create_productions.sql`
|
||||
- `supabase/migrations/003_create_test_accounts.sql`
|
||||
**Impact :** Si la base doit être recréée (nouveau projet Supabase), les migrations permettent de tout reconstruire en une commande.
|
||||
**Impact :** Si la base doit être recréée (nouveau projet Supabase), les migrations permettent de tout reconstruire en une commande.
|
||||
|
||||
---
|
||||
|
||||
### TD-07 — Ancien projet Supabase partagé
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Ouvert — accepté temporairement
|
||||
**Description :** Le nouveau projet Expria V2 utilise la même base Supabase que l'ancien projet (en maintenance). Les anciennes tables ont été remplacées mais d'autres tables de l'ancien projet subsistent (`sujets`, `eo_t2_results`, `payment_transactions`, etc.).
|
||||
|
|
@ -86,33 +95,38 @@
|
|||
---
|
||||
|
||||
### TD-13 — Webhook Stripe non idempotent
|
||||
|
||||
**Priorité :** 🔴 Critique
|
||||
**Statut :** Ouvert — à faire avant mise en production
|
||||
**Description :** Stripe peut livrer un même event webhook deux fois (retries réseau, rejeu manuel depuis le dashboard). La route `POST /stripe/webhook` traite chaque réception sans dédoublonnage. En pratique, les opérations `updateUserPlan` et `updateUserStripeInfo` sont idempotentes par nature (même résultat en cas de double appel), mais si de la logique non idempotente est ajoutée plus tard (ex: compteur, envoi d'email, crédit utilisateur), un double traitement causerait un bug.
|
||||
**À faire :**
|
||||
|
||||
- Créer une table `stripe_webhook_events(id TEXT PRIMARY KEY, processed_at TIMESTAMPTZ)`
|
||||
- Avant traitement, vérifier si `event.id` est déjà en base → si oui, retourner 200 sans rien faire
|
||||
- Après traitement, insérer l'`event.id` dans la table
|
||||
**Session concernée :** Stripe (POST /stripe/webhook)
|
||||
**Condition de résolution :** Avant la mise en production publique.
|
||||
**Session concernée :** Stripe (POST /stripe/webhook)
|
||||
**Condition de résolution :** Avant la mise en production publique.
|
||||
|
||||
---
|
||||
|
||||
### TD-15 — Jobs asynchrones modèle/exercices : status peut rester "pending" indéfiniment
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Ouvert — introduit au Sprint 3.6a
|
||||
**Description :** Le flux POST /corrections/ee lance deux jobs DeepSeek en fire-and-forget (`runModeleJob`, `runExercicesJob` dans `correctionController.ts`). Si le process Node redémarre (deploy Render, crash, OOM) pendant l'exécution d'un de ces jobs, la colonne `exercices_status` ou `modele_status` reste figée à `'pending'` — l'utilisateur voit un loader infini côté frontend.
|
||||
**Impact actuel :** faible en conditions normales (DeepSeek répond en ~5-15 s, Render redémarre rarement). Perceptible uniquement si un deploy a lieu pendant une correction active.
|
||||
**À faire :**
|
||||
|
||||
- Option 1 (simple) : job de reprise au boot → scanner `productions WHERE (exercices_status='pending' OR modele_status='pending') AND created_at < NOW() - INTERVAL '2 minutes'` → relancer.
|
||||
- Option 2 (robuste) : file d'attente persistée (pg-boss, BullMQ) au lieu de fire-and-forget.
|
||||
- Option 3 (minimal) : timeout côté frontend → si `pending` depuis > 2 min, afficher "La génération a échoué, réessayer ?" + endpoint `POST /simulations/:id/retry-jobs`.
|
||||
**Session concernée :** à planifier après livraison Sprint 3.6a/3.6b en prod stable.
|
||||
**Condition de résolution :** après 7 jours d'observation en prod avec monitoring des colonnes `*_status='pending'` âgées.
|
||||
**Session concernée :** à planifier après livraison Sprint 3.6a/3.6b en prod stable.
|
||||
**Condition de résolution :** après 7 jours d'observation en prod avec monitoring des colonnes `*_status='pending'` âgées.
|
||||
|
||||
---
|
||||
|
||||
### TD-14 — Erreurs TypeScript TS2835 pré-existantes
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — session correction build TypeScript
|
||||
**Description :** Erreurs TS2835 sur plusieurs fichiers de routes.
|
||||
|
|
@ -125,16 +139,17 @@ Gate de qualité actuel : npm run test.
|
|||
## 3. Fonctionnalités reportées
|
||||
|
||||
### TD-08 — Phonologie T2 EO à 0
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Ouvert
|
||||
**Description :** L'évaluation de la phonologie pour la T2 EO live est temporairement à 0 (non évaluée). L'évaluation se fait sur 4 critères au lieu de 5.
|
||||
**Raison :** La T2 live utilise un transcript texte — évaluer la phonologie nécessite l'audio brut, ce qui dépasse la limite de taille des requêtes.
|
||||
**À faire :** Implémenter l'évaluation phonologique via un endpoint séparé qui traite l'audio en chunks.
|
||||
**Session concernée :** T2 live (WebSocket)
|
||||
**Statut :** Partiellement résolu — Sprint 4.8
|
||||
**Description :** L'évaluation de la phonologie est désormais opérationnelle pour **EO T1 et T3** : `POST /corrections/eo` reçoit l'audio brut (Mode B), Gemini 2.5 Flash évalue la phonologie en parallèle de la transcription via `evaluatePhonology` (cf. `src/lib/geminiPhonology.ts`), et le score `/4` est injecté comme 5e critère du rapport. Le format passe officiellement à 5 critères × /4 (total /20 inchangé).
|
||||
**Reste à faire :** **EO T2 Live (Sprint 6)** continue de retourner phonologie 0/4 — pas d'audio brut côté backend dans le pipeline WebSocket actuel (`t2live.ts` proxifie l'audio entre client et Gemini Live sans le bufferiser pour évaluation différée). À résoudre lors du Sprint 6 en accumulant l'audio côté backend ou en demandant à Gemini Live de produire une note phonologique en fin de session.
|
||||
**Session concernée :** T2 Live (WebSocket) — Sprint 6.
|
||||
|
||||
---
|
||||
|
||||
### TD-09 — ScriptProcessorNode déprécié (T2 live)
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Reporté à après le lancement
|
||||
**Description :** Le traitement audio côté client utilise `ScriptProcessorNode` qui est déprécié. Doit être remplacé par `AudioWorklet`.
|
||||
|
|
@ -144,6 +159,7 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-10 — Analyse des patterns (Premium) non implémentée
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — Sprint 3.6c
|
||||
**Description :** La feature d'analyse des patterns sur les 5 dernières productions (Premium) a été livrée Sprint 3.6c (table `pattern_analyses`, `generatePatternExercices`).
|
||||
|
|
@ -151,6 +167,7 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-11 — Indice de préparation non implémenté
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Résolu — Sprint 3.6c
|
||||
**Description :** Le calcul de l'indice de préparation (0-100) a été livré Sprint 3.6c en même temps que l'analyse des patterns (colonne `preparation_index` + `preparation_message`).
|
||||
|
|
@ -160,6 +177,7 @@ Gate de qualité actuel : npm run test.
|
|||
## 4. Tests à automatiser
|
||||
|
||||
### TD-12 — Tests manuels du Golden Dataset non automatisés
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Accepté — par conception
|
||||
**Description :** Les 41 tests du Golden Dataset sont manuels. Certains pourraient être automatisés (tests d'intégration HTTP avec Supertest).
|
||||
|
|
@ -168,6 +186,7 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-16 — Bucket Supabase Storage `audio-productions` créé manuellement
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — Sprint 4b
|
||||
**Description :** Décision Hermann (2026-04-25) : abandon du stockage audio backend. La transcription live passe par Deepgram en connexion directe navigateur ↔ Deepgram via token éphémère. L'audio brut est téléchargé en local par l'utilisateur. Plus aucun bucket Storage requis côté serveur.
|
||||
|
|
@ -175,6 +194,7 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-17 — Limite audioBase64 in-memory à 14 Mo (≈ 10 Mo binaire)
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Résolu — Sprint 4b
|
||||
**Description :** Plus de payload audio reçu côté backend (POST /corrections/eo accepte uniquement `transcript`). La limite n'a plus lieu d'être.
|
||||
|
|
@ -182,6 +202,7 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-18 — RLS Storage `audio-productions` non testée en intégration
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Résolu — Sprint 4b
|
||||
**Description :** Plus de bucket Storage backend à protéger. Les policies RLS de la migration 006 sont supprimées (DROP IF EXISTS) au profit d'un commentaire historique.
|
||||
|
|
@ -189,45 +210,51 @@ Gate de qualité actuel : npm run test.
|
|||
---
|
||||
|
||||
### TD-19 — Token Deepgram non rotatif côté frontend
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Ouvert — introduit au Sprint 4b
|
||||
**Description :** `POST /transcriptions/token` retourne un token Deepgram éphémère valide 600 s (10 min). Une session EO T1 (2 min) tient largement, mais une session T3 (4:30) ou un enchaînement de 2 tâches dépasse la fenêtre si l'utilisateur prend des pauses. Si le token expire en cours de session, la connexion Deepgram drop sans renégociation automatique.
|
||||
**À faire (côté frontend Sprint 4c) :**
|
||||
|
||||
- Demander un nouveau token via `/transcriptions/token` à T-60 s avant expiration.
|
||||
- Reconnecter Deepgram en réutilisant la même session WebSocket si supporté.
|
||||
**Condition de résolution :** stratégie de rotation de token implémentée et testée côté frontend.
|
||||
**Condition de résolution :** stratégie de rotation de token implémentée et testée côté frontend.
|
||||
|
||||
---
|
||||
|
||||
### TD-20 — `transcribeAudio` (Gemini) sans consommateur
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Ouvert — introduit au Sprint 4b
|
||||
**Description :** La fonction `transcribeAudio` dans `src/lib/gemini.ts` n'est plus appelée par le flux EO (Deepgram a remplacé Gemini batch). Conservée volontairement comme point d'extension futur pour TD-08 (évaluation phonologique séparée) ou un fallback si Deepgram est indisponible.
|
||||
**À faire :**
|
||||
|
||||
- Si TD-08 reste fermé 30 jours après la mise en prod du Sprint 4b sans plan d'usage, supprimer `transcribeAudio` et `gemini.ts` complet.
|
||||
**Condition de résolution :** décision sur TD-08 (résolution ou abandon).
|
||||
**Condition de résolution :** décision sur TD-08 (résolution ou abandon).
|
||||
|
||||
---
|
||||
|
||||
### TD-21 — Pas de rate limiting sur `/transcriptions/token`
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Ouvert — introduit au Sprint 4b
|
||||
**Description :** Un utilisateur authentifié peut générer un nombre illimité de tokens Deepgram. Chaque token consomme un crédit côté Deepgram (selon usage de la connexion live qui suit). Un user malveillant pourrait scripter des appels en boucle pour épuiser le quota Deepgram.
|
||||
**À faire :**
|
||||
|
||||
- Ajouter un rate limit (par user, ex. 30 tokens/heure) via le middleware `rateLimit.ts` existant.
|
||||
**Condition de résolution :** middleware rate-limit branché sur la route et testé.
|
||||
**Condition de résolution :** middleware rate-limit branché sur la route et testé.
|
||||
|
||||
---
|
||||
|
||||
## 5. Historique des résolutions
|
||||
|
||||
| ID | Description | Résolu le | Comment |
|
||||
|---|---|---|---|
|
||||
| TD-02 | planController.ts complété | 2026-04-16 | Session Stripe |
|
||||
| TD-03 | stripe.ts complété | 2026-04-16 | Session Stripe |
|
||||
| TD-14 | Erreurs TS2835 + TS18046 + TS7053 corrigées | 2026-04-17 | Session build Render |
|
||||
| TD-10 | Analyse des patterns (Premium) livrée | 2026-04-25 | Sprint 3.6c |
|
||||
| TD-11 | Indice de préparation livré | 2026-04-25 | Sprint 3.6c |
|
||||
| TD-16 | Bucket Storage abandonné | 2026-04-25 | Sprint 4b — Deepgram direct |
|
||||
| TD-17 | Limite audio in-memory caduque | 2026-04-25 | Sprint 4b |
|
||||
| TD-18 | RLS Storage caduque | 2026-04-25 | Sprint 4b |
|
||||
| ID | Description | Résolu le | Comment |
|
||||
| ----- | ------------------------------------------- | ---------- | --------------------------- |
|
||||
| TD-02 | planController.ts complété | 2026-04-16 | Session Stripe |
|
||||
| TD-03 | stripe.ts complété | 2026-04-16 | Session Stripe |
|
||||
| TD-14 | Erreurs TS2835 + TS18046 + TS7053 corrigées | 2026-04-17 | Session build Render |
|
||||
| TD-10 | Analyse des patterns (Premium) livrée | 2026-04-25 | Sprint 3.6c |
|
||||
| TD-11 | Indice de préparation livré | 2026-04-25 | Sprint 3.6c |
|
||||
| TD-16 | Bucket Storage abandonné | 2026-04-25 | Sprint 4b — Deepgram direct |
|
||||
| TD-17 | Limite audio in-memory caduque | 2026-04-25 | Sprint 4b |
|
||||
| TD-18 | RLS Storage caduque | 2026-04-25 | Sprint 4b |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue