From 4b3194d2076cca91b09e1f4d98e9d8b4030878f8 Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Fri, 1 May 2026 19:04:28 +0200 Subject: [PATCH] phone screen --- MEMORY.md | 76 ++++++++++++++++++++++++++++++ frontend/src/styles.css | 102 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/MEMORY.md b/MEMORY.md index 1005bf0..67f4ebd 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -100,6 +100,82 @@ Ce projet est un POC de professeur virtuel pour enfants, avec: - Lors d'un prochain demarrage, penser a installer les dependances frontend avant validation finale. - La TTS OpenAI suppose une `OPENAI_API_KEY` valide cote backend. +## Notes de Session 2026-04-25 - Auth, UI Eleve, Audio + +- Authentification ajoutee: + - table `users` + - roles `student`, `teacher`, `maintenance` + - login via `/auth/login` + - session via cookie HTTP-only `professeur_top_session` + - compte admin/prof seede depuis `.env` +- Acces eleve/admin: + - un compte eleve est rattache a un `student_id` + - un eleve ne peut acceder qu'a sa propre fiche/seance + - prof/maintenance gardent l'acces global + - creation d'un compte eleve via `POST /admin/student-accounts` +- UI eleve: + - page login active + - l'eleve ne voit plus la creation ni le choix d'eleves + - l'ecran de cours ne montre plus la conversation complete + - le cours courant remplace la consigne precedente au centre + - la zone de reponse eleve reste en bas + - card "Transmis au prof" ajoutee pour afficher le dernier texte envoye/capte + - bouton principal `Demarrer la seance` / `Fin de la seance` + - colonne gauche eleve limitee aux themes du jour, pas au bilan global +- Conversation et analyse: + - les messages restent stockes en base + - `GET /students/{student_id}/messages` permet de relire l'historique + - le chat complet sera surtout utile aux rapports admin +- Voix/TTS: + - les voix visibles sont libellees `Voix Douce`, `Voix Rigolote`, etc. + - la mention "Voix IA non humaine..." est deplacee en tooltip + - Professeur TOP a maintenant une consigne backend de tours de parole courts +- Transcription: + - `language="fr"` force dans la transcription OpenAI + - prompt de transcription ajoute pour phrases scolaires courtes + - correction faite apres erreur type langue asiatique sur une phrase simple comme "nous chantons" +- Deploiement serveur: + - `.env` du compose doit etre dans `/root/.env` ou passe via `--env-file` + - rebuild backend necessaire pour changements backend + - rebuild frontend necessaire pour changements UI + +## Idee Technique - Interruptions Trop Frequentes + +Objectif: permettre a l'enfant de couper Professeur TOP sans perdre le fil, tout en evitant les faux positifs. + +Approche progressive recommandee: + +1. Barge-in simple avec TTS MP3 actuel: + - garder l'analyse micro active pendant la lecture audio + - si volume/parole detectee pendant que `speaking=true`, mettre l'audio en pause ou l'arreter + - enregistrer un court segment jusqu'au silence + - transcrire en francais + - envoyer au backend avec un marqueur du type `interruption=true` + - demander au LLM de classer implicitement: pertinent, question, correction, bruit/accident + - si pertinent: repondre a l'enfant puis reprendre la lecon + - si accidentel: repondre tres court puis continuer la consigne + +2. Anti-faux positifs: + - imposer un seuil plus haut pendant la lecture TTS + - ignorer les segments tres courts, par exemple moins de 600 ms + - ignorer les transcriptions vides ou tres faibles + - utiliser une courte fenetre de cooldown apres chaque interruption + - afficher dans "Transmis au prof" uniquement ce qui est vraiment envoye + +3. Meilleure solution moyen terme: + - passer sur OpenAI Realtime/WebRTC + - gerer interruption, VAD, tour-taking et streaming audio nativement + - envoyer des evenements de session avec contexte pedagogique + - conserver en base les transcriptions et messages comme aujourd'hui + +4. Donnees a stocker plus tard: + - `session_id` + - `message_type`: text, image, audio, interruption + - `source`: keyboard, microphone, system + - `interruption_of_message_id` + - timestamp debut/fin de parole + - confiance transcription + ## Points de Vigilance - Les erreurs WebSocket Vite/HMR sur `wss://prof.open-squared.tech/...` sont du bruit de dev tant que le frontend tourne via Vite derriere nginx. diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 1646128..5920854 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -276,7 +276,36 @@ button:disabled { opacity: 0.5; cursor: not-allowed; } } @media (max-width: 920px) { - .layout { grid-template-columns: 1fr; } + body { + overflow: auto; + } + + .layout { + grid-template-columns: 1fr; + height: auto; + min-height: 100dvh; + overflow: visible; + padding: 0.75rem; + } + + .sidebar, + .main { + min-height: auto; + overflow: visible; + } + + .student-layout .sidebar { + order: 1; + } + + .student-layout .main { + order: 2; + } + + .card { + border-radius: 18px; + } + .composer { grid-template-columns: 1fr; } .hero { align-items: flex-start; } .session-user { @@ -284,4 +313,75 @@ button:disabled { opacity: 0.5; cursor: not-allowed; } margin-left: 0; justify-content: space-between; } + + .instruction-stage { + flex: 0 0 auto; + justify-content: flex-start; + min-height: 220px; + } + + .instruction-stage p { + max-height: none; + overflow: visible; + font-size: 1.1rem; + } +} + +@media (max-width: 560px) { + .layout { + gap: 0.75rem; + padding: 0.5rem; + } + + .card { + padding: 0.85rem; + border-radius: 16px; + } + + .sidebar, + .main, + .today-panel { + gap: 0.85rem; + } + + .sidebar h2, + .main h1 { + margin: 0; + } + + .main h1 { + font-size: 1.85rem; + } + + .hero { + gap: 0.75rem; + } + + .avatar { + width: 112px; + height: 112px; + border-radius: 22px; + } + + .session-user { + align-items: stretch; + flex-direction: column; + gap: 0.5rem; + } + + .today-card-head { + align-items: flex-start; + flex-direction: column; + gap: 0.25rem; + } + + .student-transmission p { + white-space: normal; + } + + button, + input, + select { + width: 100%; + } }