Commit graph

78 commits

Author SHA1 Message Date
868bd09397 feat(t1-live): examinateur avec interruption probabiliste pilotee backend (Sprint 7a)
- Session T1 Live : monologue candidat + interruptions pilotees backend (VAD manuel).
- Voix examinateur native Gemini ; le backend decide le timing (tirage probabiliste 0-2, fenetre [25s,75s]), Gemini formule la relance sur signal d'injection (anti-TD-22).
- Injection : activityEnd -> clientContent -> activityStart ; signaux WS interruption_start/end.
- Fin de session : activityEnd final flushe le dernier segment candidat ; relance terminale coupee (audio non renvoye, texte jete) ; seul le texte candidat conserve pour l'evaluation.
- buildT1SystemPrompt : nouvel artefact, regle 7 du T2 NON propagee (questions autorisees).
- Route /t1/live : auth Premium reutilisee, contexte questionnaire dynamique, persistance EO_T1 (sujet_id null), evaluation via correctEO('EO_T1'), phonologie stub /4 (TD-08 gele).
- geminiLive.ts : exports additifs + buildSetupFrame parametrable VAD (T2 inchange).
- gitignore : exclusion des artefacts jetables de test/spike.
2026-06-29 22:07:57 +03:00
5f7e52d88a docs(t2live): MAJ prompt §3, TD-22, CHANGELOG Sprint 6d
Some checks failed
CI / quality (push) Has been cancelled
- Prompt_t2live.md §3 réécrit (13 règles) + encadré spécificité T2 (règle 7
  non propageable au prompt T1).
- TECH_DEBT-backend.md: TD-22 (contournement prompt engineering Flash Live).
- CHANGELOG-backend.md: bloc Sprint 6d.
2026-06-28 11:49:45 +03:00
94387a71db fix(geminiLive): T2 prompt durci + VAD réintégré, retrait SDK @google/genai
- Bug 1: prompt système T2 durci (13 règles absolues, interdiction du "?",
  rôle inerte) pour stopper la relance systématique. Réf TD-22.
- Bug 2: realtimeInputConfig (VAD automaticActivityDetection, 4 champs)
  réintégré dans le setup frame Gemini.
- Bug 8: @google/genai retiré + test-gemini-live.js supprimé (SDK abandonné
  au profit du WebSocket brut).

Tests 292/292 verts. Validé Golden Dataset Groupe D.
2026-06-28 11:49:37 +03:00
eee75b53ca fix(geminiLive): remove speechConfig (unsupported by model)
Some checks are pending
CI / quality (push) Waiting to run
2026-04-27 04:38:29 +03:00
cca05df62c fix(geminiLive): nuanced no-question rule + Charon voice (male) 2026-04-27 04:27:17 +03:00
8863520a2e fix: T2 prompt calibration (25 words max) + JSONB parse guard (500 on getById) 2026-04-27 04:11:02 +03:00
452255d77f feat(geminiLive): restore audio transcription config 2026-04-27 03:42:31 +03:00
9a62fba0f2 feat(geminiLive): restore systemInstruction in setup frame 2026-04-27 03:31:12 +03:00
2b1a354791 fix(geminiLive): use gemini-3.1-flash-live-preview (confirmed working) 2026-04-27 03:19:34 +03:00
9da733d156 fix(geminiLive): revert to raw WebSocket (SDK close without reason)
- Replace @google/genai SDK with raw 'ws' WebSocket
- Setup frame minimal (model + responseModalities AUDIO only)
- Forward client {type:audio} → realtimeInput JSON to Gemini
- Forward Gemini messages verbatim to client
- Detailed [T2] logs for Render debug
- Tests adapted to mock raw WS via clientFactory
2026-04-27 03:05:12 +03:00
61be6b1959 debug(geminiLive): minimal SDK config to isolate rejected field 2026-04-27 02:59:07 +03:00
91bb93a07f fix(geminiLive): use Gemini Developer API (no vertexai flag) 2026-04-27 02:55:40 +03:00
f3eb7d615e fix(geminiLive): try gemini-2.0-flash-live-001 model 2026-04-27 02:52:13 +03:00
be2b325c4b chore(geminiLive): add detailed SDK logging for Render debug 2026-04-27 02:48:28 +03:00
0662e766d4 Sprint 6d — Migrate Gemini Live to @google/genai SDK
feat(geminiLive): rewrite with GoogleGenAI SDK (vertexai: true, apiKey)
  replaces raw WebSocket to generativelanguage.googleapis.com
feat(geminiLive): restore full setup config (systemInstruction,
  inputAudioTranscription, outputAudioTranscription, VAD)
fix(geminiLive): buildSetupFrame → SDK config object (no manual JSON)
fix(useT2LiveSession): cancelTokenRef for idempotent startDialogue,
  closeAllRef for stable unmount cleanup
chore: add @google/genai@^1.50.1 dependency
test: 11 geminiLive tests rewritten with SDK mock
  292/292 backend tests green
2026-04-27 02:25:58 +03:00
d89b0b1e89 Sprint 6a — Backend T2 Live (WS proxy + correction + persistance)
feat(geminiLive): dynamic prompt builder, transcript accumulation,
  VAD config (END_SENSITIVITY_LOW, 2s silence), 210s timeout + 180s warning
feat(t2live): sujet fetch + validation, correction pipeline (deepseekCorrectEO
  + PHONOLOGY_STUB TD-08), production insert + report delivery via WS
feat(deepseek): TacheEO extended with EO_T2, VALID_TACHES_EO updated
test: 11 geminiLive tests (rewritten + 4 new), 10 t2live integration tests
  292/292 backend tests green (+15)
2026-04-26 19:53:37 +03:00
28f8373f5d fix(stripe): cancel_url /tarifs → /plan
La route /tarifs n'existe pas côté frontend (route réelle: /plan).
Cancellation Stripe Checkout aboutissait sur un 404. Bug détecté lors
du Sprint 5c frontend (gestion des retours post-Checkout).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 05:49:50 +03:00
6671bac347 feat(billing): TD-13 webhook idempotency + Stripe Customer Portal + doc cleanup
- Table stripe_webhook_events + helpers isEventProcessed/markEventProcessed
- POST /stripe/customer-portal (auth + stripe_customer_id check)
- ARCHITECTURE-backend.md: suppression POST /plans/upgrade (duplication doc)
- TD-13 fermé dans TECH_DEBT-backend.md
- Tests: 261 → 278 verts (+17)
2026-04-26 04:15:46 +03:00
ec0598d122 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>
2026-04-26 03:09:13 +03:00
34b4bcdd82 docs: update CHANGELOG and ROADMAP for Sprint 4
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 08:54:58 +03:00
dba446b555 fix(timeouts): increase Gemini to 45s, DeepSeek EO to 90s + adaptive conseil_nclc
- Gemini GEMINI_TIMEOUT_MS: 30s → 45s
- callDeepSeek optional timeoutMs param, correctEO uses 90s
- conseil_nclc: 4 tiers based on score vs NCLC target (EE + EO)
- sanitizeJsonContent: handle single-quote JSON from DeepSeek
- MIME normalization for audio/webm;codecs=opus

Typecheck: OK · Tests: 248/248 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 08:30:51 +03:00
13aacf4d38 fix(deepseek): adaptive conseil_nclc based on score vs NCLC target
- 4 tiers: exceeded / reached / close / far from target
- Applied to both EE and EO correction prompts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 08:07:05 +03:00
c35727410c Revert "debug(eo): log raw DeepSeek response on parse failure"
This reverts commit 9420612abf.
2026-04-25 07:41:58 +03:00
c473e54ae8 fix(deepseek): handle single-quote JSON from DeepSeek responses
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 07:41:58 +03:00
9420612abf debug(eo): log raw DeepSeek response on parse failure
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 07:35:45 +03:00
4fde66d930 fix(eo): sanitize DeepSeek JSON response before parsing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 07:25:47 +03:00
0c6e4cfac1 fix(gemini): upgrade model from 2.0-flash to 2.5-flash (404 fix)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 07:16:51 +03:00
ff46cf61a5 fix(eo): normalize MIME type before validation (strip codec params)
- "audio/webm;codecs=opus" → "audio/webm" before isAcceptedAudioMime check
- Normalized MIME propagated to Gemini transcribeAudio

Typecheck: OK · Tests: 248/248 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 06:50:48 +03:00
8f8a900449 feat(eo): restore audioBase64 mode for Gemini batch transcription
- POST /corrections/eo accepts audioBase64 + mimeType (XOR with transcript)
- Gemini transcribeAudio called server-side before correction
- No audio storage (client downloads locally)
- /transcriptions/token kept for future Deepgram live use

Typecheck: OK · Tests: all green

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 05:59:53 +03:00
14880fe94c fix(deepgram): revert to /v1/auth/grant for temporary JWT tokens
- /v1/projects/{id}/keys creates permanent API keys, not WebSocket-compatible JWT tokens
- /v1/auth/grant requires Member-scoped API key (now configured)
- Remove DEEPGRAM_PROJECT_ID dependency
- Update tests

Typecheck: OK · Tests: 241/241 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 05:49:45 +03:00
a62b4816a2 fix(deepgram): use correct /v1/projects/{project_id}/keys endpoint
- Replace non-existent /v1/auth/grant with /v1/projects/{project_id}/keys
- Add DEEPGRAM_PROJECT_ID env variable
- Update request body and response parsing
- Update tests

Typecheck: OK · Tests: 241/241 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 05:36:19 +03:00
7cac057062 feat(eo): align correction EO on 3.6a format + Deepgram token + T1 presentation generation
Sprint 4a:
- correctEO aligned on CorrectionRapport format (revelation, diagnostic, criteres, conseil_nclc, erreurs_codes)
- nclc_cible parameter (default 9, accepts 9|10)
- Fire-and-forget modele + exercices jobs (same pattern as EE)
- EO-specific DeepSeek prompt (oral transcript tolerance, 4 TCF criteria)
- Gemini transcribeAudio: 30s timeout + 1 retry
- POST /presentations/generate: 5-field questionnaire → DeepSeek generates oral presentation (~220-260 words, NCLC 7-8)
- Migration 006_sprint_4a_eo.sql (documentation only — no audio storage)

Sprint 4b:
- POST /transcriptions/token: Deepgram temporary API key (600s TTL)
- Removed audio storage pipeline (audioStorage.ts, XOR validation, 14MB limit)
- Backend receives transcript text only, no audio files
- TD-10/TD-11 resolved (Sprint 3.6c), TD-16/17/18 resolved (4b cleanup)

Typecheck: OK · Tests: 241/241 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 05:04:26 +03:00
f5954e6d72 docs(changelog): add health check keepalive entry
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 02:29:05 +03:00
fa06daace8 fix(health): add Supabase keepalive ping to GET / health check
UptimeRobot pings GET / every 5 minutes. Previously static response
only kept Node process alive but let Supabase connection pool go cold.
Now executes a lightweight HEAD query (profiles, limit 1) to maintain
DB connection warmth. Always returns 200 with db status field for
observability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 02:07:27 +03:00
b5980ccce2 ci(semgrep): scan SAST --severity=ERROR (FTD-28)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:46:41 +03:00
8b0c2f795a ci: GitHub Actions workflow — test + audit (FTD-27)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:35:51 +03:00
5f5737c5a5 ci(dependabot): config version updates weekly (FTD-29)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:31:05 +03:00
c48ae8d443 feat(patterns): GET /users/patterns — agrégation erreurs récurrentes + exercices long terme + indice de préparation (Sprint 3.6c)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 22:06:14 +03:00
a394ce8429 feat(simulations): GET /simulations — liste paginée des productions (Sprint 3.7)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:54:36 +03:00
14d8d73991 fix(corrections): race condition modele_status + logs diagnostiques
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:13:56 +03:00
63bc43ddcf feat(corrections): Sprint 3.6a — nouveaux prompts + taxonomie erreurs + génération parallèle
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 17:27:29 +03:00
df7ef2cc31 fix(cors): ajouter PATCH/PUT/DELETE dans allowMethods 2026-04-21 04:52:41 +03:00
fcd8fe7017 feat(simulations): persistance session — autosave + sujet_id + getById tolère rapport=null (FTD-21) 2026-04-21 03:48:45 +03:00
fc76fac981 test(sujets): 5 tests POST /sujets/idees
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 03:07:13 +03:00
bd8ab4b72b feat(sujets): POST /sujets/idees — suggestions DeepSeek (G5)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 03:05:07 +03:00
ecb478e10c fix(simulations): déplacer incrément simulations_used après correction réussie (Option B) 2026-04-21 02:01:13 +03:00
1a5b79807e test(sujets): 8 tests route GET /sujets 2026-04-21 01:03:49 +03:00
cc72487013 feat(sujets): GET /sujets?mode=&tache= avec auth + filtre actif 2026-04-21 00:59:18 +03:00
b6b8c76cc2 feat(simulations): retourner un sujet aléatoire actif avec la production créée 2026-04-20 06:01:02 +03:00
0680a6382f feat(simulations): GET /simulations/:id — lecture rapport avec auth + REPORT_NOT_READY 2026-04-20 04:41:24 +03:00