19 KiB
19 KiB
Memoire Projet
Contexte
Ce projet est un POC de professeur virtuel pour enfants, avec:
- frontend React + Vite
- backend FastAPI
- PostgreSQL pour les donnees eleve
- Redis present dans la stack
- integration OpenAI pour reponses texte et transcription audio
Points Importants
- Le frontend appelle l'API via le prefixe
/api. - Le backend expose une route
POST /transcribepour la transcription audio. - La route
/transcribeutiliseUploadFile, doncpython-multipartest requis dans le backend. - Le backend a un socle d'authentification avec comptes
users, rolesstudent,teacher,maintenance. - Le compte admin/prof initial est seede depuis
.envviaADMIN_USERNAMEetADMIN_PASSWORD. - Le login pose un cookie HTTP-only
professeur_top_sessionet renvoie aussi un token bearer. - Le frontend affiche maintenant une page de connexion avant l'application et verifie la session via
/auth/me. - Apres connexion admin/prof, l'interface actuelle reste accessible avec un bouton de deconnexion.
- Les routes eleves principales verifient maintenant les roles:
teacheretmaintenancepeuvent acceder aux elevesstudentne peut acceder qu'a son proprestudent_id
- Le backend expose
POST /admin/student-accountspour creer une fiche eleve et son compte login en une seule operation. - Le frontend masque le choix/creation d'eleve pour un compte
studentet ouvre directement sa propre seance. - Le backend expose
GET /students/{student_id}/messagespour relire l'historique de conversation stocke en base. - Les reponses aux mini-tests sont maintenant aussi enregistrees dans
messagesavec le roleuser. - Le frontend recharge l'historique quand un eleve est selectionne, mais ne met plus automatiquement la derniere ancienne phrase au centre.
- Au demarrage d'une nouvelle seance, Professeur TOP doit faire une courte reprise de l'historique puis annoncer le cours du jour.
- L'interface de seance est maintenant en hauteur fixe
100vh: pas de scroll global, cours central au milieu, pas de conversation visible. - La conversation reste stockee en base pour analyse, mais l'ecran de cours remplace la consigne/reponse courante au lieu d'empiler des bulles.
- Les reponses de mini-test utilisent la meme zone de reponse eleve en bas; le texte du prof reste au-dessus et pourra accueillir une image sous le texte.
- Cote eleve, le bouton principal bascule entre
Demarrer la seanceetFin de la seance. - Cote eleve, la colonne gauche affiche les themes du jour: une card lecon avec pourcentage local, une card exercice avec statut.
- Le bilan complet de progression reste reserve aux vues prof/admin.
- Les options TTS visibles doivent etre libellees
Voix Douce,Voix Rigolote, etc.; la mention "Voix IA non humaine..." est portee par un tooltip. - Le declenchement manuel de mini-test/exercice doit disparaitre de l'interface eleve; le programme doit etre determine par Professeur TOP.
- A prevoir cote admin: tableau par eleve et prompts/instructions personnalises pour guider Professeur TOP par eleve.
- L'ecran eleve affiche une petite card "Transmis au prof" au-dessus de la zone de saisie pour montrer le texte capte/envoye.
- Le backend ajoute une consigne de tours de parole courts pour que Professeur TOP laisse le temps a l'enfant de repondre.
- Gestion interruption a prevoir: detection de parole pendant TTS, pause audio, transcription, classification pertinent/accidentel, puis reprise courte.
- La transcription audio force maintenant
language="fr"avec un prompt francais pour eviter les erreurs de detection de langue sur phrases tres courtes. - Le vrai
docker-compose.ymlde production n'est pas dans ce repo. Il est situe un niveau au-dessus sur le serveur. - La conf nginx reelle route:
/api/verstutor-backend:8000/verstutor-frontend:3000
Dictée Vocale
- L'ancien bouton de dictee marchait en mode manuel avec
MediaRecorder.start()puisstop(). - Le mode actuel est un mode mains libres:
- activation via un clic utilisateur
- enregistrement automatique
- detection du silence
- transcription automatique
- envoi automatique du message
- Firefox s'est montre capricieux avec la mesure temps reel via
AnalyserNode. - La solution retenue s'appuie sur un traitement plus direct du flux audio pour determiner le niveau sonore.
- L'ecoute se rearme automatiquement apres:
- la transcription/envoi du message eleve
- la fin de lecture vocale du professeur
Voix du Professeur
- L'ancien systeme de voix navigateur a ete remplace par une vraie TTS OpenAI.
- Le backend expose maintenant:
GET /tts/profilespour lister les profils de voixPOST /ttspour generer un MP3 a partir d'un texte et d'unprofile_id
- Les profils actuels sont:
rigolotepetillantedoucesobre
- Chaque profil TTS definit:
- une voix OpenAI
- une vitesse
- des instructions de style vocal
- Le frontend ne depend plus de
speechSynthesispour la voix sortante. - Le choix de voix est memorise dans
localStorageavec la cleprofesseur-top-tts-profile. - La lecture audio se fait via un blob MP3 retourne par le backend.
- Le mode micro auto doit continuer a se re-armer apres la fin de lecture du MP3.
Identite Produit
- Le personnage et le nom visibles dans le frontend ont ete renommes de
ProfAmiversProfesseur TOP. - Le nouvel avatar image est stocke dans:
frontend/src/assets/professeur-top.png
- Le composant avatar React utilise maintenant l'image raster au lieu du visage CSS/SVG precedent.
- Le backend a aussi ete aligne dans le prompt systeme et le message de debut de session avec le nom
Professeur TOP.
Notes de Session 2026-04-24 21:58:39 +02:00
- Repo clone dans
c:\DataS\OpenSquared\OpenSchool\ProfTop. safe.directoryGit ajoute globalement pour ce dossier a cause d'un mismatch d'ownership Windows.- Image utilisateur
face.pngintegree dans le frontend sousfrontend/src/assets/professeur-top.png. - Libelles assistant remplaces par
Professeur TOPdans l'UI. - README mis a jour pour refleter la TTS OpenAI au lieu de la voix navigateur.
- Le frontend n'a pas encore ete verifie par build local car
frontend/node_modulesest absent. - Lors d'un prochain demarrage, penser a installer les dependances frontend avant validation finale.
- La TTS OpenAI suppose une
OPENAI_API_KEYvalide 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
- table
- 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
- un compte eleve est rattache a un
- 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}/messagespermet 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
- les voix visibles sont libellees
- 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:
.envdu compose doit etre dans/root/.envou 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:
-
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
-
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
-
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
-
Donnees a stocker plus tard:
session_idmessage_type: text, image, audio, interruptionsource: keyboard, microphone, systeminterruption_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. - Ces erreurs ne sont pas la cause principale si
/api/*renvoie des502ou si le micro se comporte mal. - En cas de
502sur/api/*, verifier d'aborddocker logs tutor-backend. - Pour tester l'auth locale actuelle:
.envcontientADMIN_USERNAME=adminetADMIN_PASSWORD=admin; a changer avant tout usage partage.
Note Programme Pedagogique par Eleve
- Le mode admin doit devenir une gestion du programme par eleve.
- Pour chaque eleve configure, le professeur/admin doit pouvoir choisir une lecon dans le contenu disponible localement.
- La source prioritaire du contenu est:
C:\DataS\OpenSquared\OpenSchool\Programme\contenus_pedagogiques
- Le contenu est classe par cycle, niveau et matiere:
- cycle 3: CM1, CM2, 6e
- cycle 4: 5e, 4e, 3e
- Pour un eleve de CM1, l'admin doit pouvoir choisir par exemple:
- mathematiques > nombres entiers
- Les fiches
.svgassociees a la lecon choisie doivent s'afficher dans la zone centrale de Professeur TOP cote eleve. - Premier essai implemente: une affectation active par eleve, selectionnee en admin, puis visible dans l'ecran eleve.
- A prevoir ensuite:
- plusieurs cours possibles par eleve
- progression equilibree entre lecons et matieres
- instructions personnalisees par eleve
- suivi fin des fiches vues / exercices faits
- Vigilance langue française: les libellés visibles doivent utiliser les accents et formulations françaises correctes, par exemple
Démarrer la leçon.
Session Programme / Mobile / Fiches SVG
- Le contenu pedagogique a ete copie dans le repo sous:
backend/contenus_pedagogiques
- Objectif: le
git pullserveur doit recuperer les contenus pedagogiques en meme temps que l'application. - Le backend cherche maintenant le contenu prioritairement dans:
backend/contenus_pedagogiquesen local/app/contenus_pedagogiquesdans le conteneur backend- puis les anciens chemins externes si besoin
- Le cas test valide localement:
- niveau:
CM1 - lecon:
CM1 - Nombres entiers - 7 fiches SVG detectees
- niveau:
- Le mode admin ne doit plus afficher Professeur TOP ni permettre de dialoguer avec lui.
- Le mode admin est maintenant une console de gestion:
- selection / creation d'eleve
- affectation d'une lecon active
- resume de l'eleve selectionne
- apercu des fiches SVG de la lecon
- Le mode eleve reste le seul mode avec Professeur TOP, voix, saisie, micro et affichage de lecon.
- Les fiches SVG sont decoupees dynamiquement en etapes/cards a partir des grands groupes
<g>internes. - Exemple pour la premiere fiche
Lecture Ecriture Nombres Entiers:La méthodeExempleÀ retenirExemples résolus
- Le frontend avance maintenant par etape de fiche plutot que seulement par fiche entiere.
- Le pourcentage affiche dans la lecon est calcule sur toutes les etapes detectees:
- progression proportionnelle
- fin de parcours arrondie a 100%
- Sur laptop:
- la fiche/card reste lisible dans la zone centrale
- le parcours pedagogique doit quand meme suivre les cards une par une
- Sur telephone:
- ne pas afficher les 7 fiches d'un coup
- ne pas afficher la fiche paysage complete
- afficher une seule card recadree en gros plan
- la card doit prendre le maximum de largeur possible
- eviter les doubles encadrements: pas de card dans une card dans l'encadre bleu
- les bords de la card doivent presque toucher les cotes de l'ecran
- les boutons precedent/suivant doivent rester petits et secondaires
- une seule zone eleve en bas: elle sert a la fois a taper et a recevoir la transcription micro
- Le bouton/lien "Agrandir la fiche" a ete retire apres decoupage des cards: la card doit etre lisible directement.
- Le texte visible de Professeur TOP est compacte a l'ecran pour garder de la place a la card.
- La voix peut rester plus longue, mais l'affichage texte ne doit pas occuper trop de hauteur.
- Le frontend envoie maintenant au backend un contexte de lecon avec
/chat:- titre de lecon
- titre de fiche
- titre de card/section affichee
- pourcentage d'avancement
- Le backend ajoute ce contexte au prompt pour que Professeur TOP parle de la card actuellement affichee.
- Au demarrage de seance, si une lecon est affectee, Professeur TOP doit parler de la premiere card affichee et verifier la comprehension.
- Probleme restant important:
- Professeur TOP ne pilote pas encore automatiquement le changement de card.
- Prochaine brique: faire produire une intention structuree du type
advance_lesson_step=truequand l'eleve dit qu'il a compris. - Le frontend devra alors avancer automatiquement a la card suivante.
- Probleme principal restant:
- Le discours de Professeur TOP n'est pas encore assez correle a la card affichee.
- Le simple contexte
titre de card + titre de fichene suffit pas toujours: le modele peut repartir sur l'historique ou une notion voisine. - Il faudra probablement generer et stocker un texte pedagogique specifique par fiche/card.
- Ce texte de card devra decrire exactement ce qui est affiche, proposer une consigne orale courte et verifier la comprehension.
- Exemple attendu: pour la card
La méthode, Professeur TOP doit expliquer le decoupage en groupes de 3 chiffres, puis demander si l'eleve comprend cette methode. - Ces textes pourraient etre generes depuis les SVG/Markdown puis sauvegardes comme metadonnees de programme, plutot que recrees a chaque seance.
- Direction pedagogique retenue:
- Professeur TOP presente la card active.
- Il demande si l'eleve comprend.
- Si oui, il passe a la card suivante.
- Si non, il explique uniquement cette card, avec un exemple court.
- Sur laptop il peut dire par exemple "en haut a gauche, tu vois la méthode".
- Sur telephone il doit parler de la card affichee en gros plan.
Plan de Dev Acces Eleve / Admin
- Socle comptes et roles: table
users, hash password, seed admin depuis.env, login, session courante. - Separation UI:
LoginPage,StudentApp,AdminApp, composants partages. - Conversation persistante: endpoints de lecture messages, puis sessions et rattachement des messages/tentatives.
- UI eleve sans scroll: Professeur TOP en haut, log de seance a gauche, derniere instruction au centre, saisie/micro en bas.
- Dashboard prof/admin: creation eleves/comptes, rapports, historique seances, conversation complete, stats de reussite.
Fichiers Touchés Pendant Cette Session
frontend/src/App.jsxfrontend/src/styles.cssfrontend/src/assets/professeur-top.pngfrontend/vite.config.jsbackend/app/main.pybackend/app/schemas.pybackend/app/services.pybackend/requirements.txtREADME.mdMEMORY.md
Session 2026-05-12 - Architecture contenus programme et SVG fractions
- Decision structurante: chaque lecon doit suivre l'arborescence canonique
lecon.md,fiches/*/fiche.md + fiche.svg,cards/*/card_XX.md + card_XX.svg,exercices/*/exercices.md + exercices.svg,tests/*,exercices/parcours_adaptes/*,sources/*. kit_adaptatif,svg/,card_contexts/etexercices_svg/sont des dossiers legacy. Une nouvelle generation ne doit plus les produire.- Chaque contenu pedagogique doit garder une section
Sourcesou un contexte equivalent pour audit Education nationale: PDF officiel, extraction locale, cycle, niveau, matiere, theme, date/validation si connue. PROGRAM_CONTENT_ARCHITECTURE.mdest la reference de l'arborescence canonique et du flux pedagogique.01B_fractionset01A_nombres_entiersont ete migres dans cette structure, dans les deux miroirsbackend/contenus_pedagogiques/...etProgramme/contenus_pedagogiques/....- Le loader programme doit parcourir les types utiles dans l'UI:
lesson,fiche,card,exercice,test,support. Plus de type editorialkit. - Le modele doit charger
lecon.mdcomme contexte general, puis le contexte specifique de l'objet actif: fiche, card, exercice ou test. backend/app/program_content.pylit les parcours adaptes recursivement avecrglob, afin queexercices/parcours_adaptes/<profil>/exercices.md + exercices.svgsoit visible dans l'arbre et dans le contexte adaptatif.- La validation globale doit afficher SVG et contexte ensemble. Dans l'onglet
Programme global, la zone de droite a ete reorganisee: SVG et Markdown se partagent l'espace, et le boutonOuvrir dans Validation contenusflotte discretement en bas a droite. - Piege majeur sur les fractions SVG:
text@yest une baseline, pas le bord visible du chiffre. Les tests qui regardent seulementbar_y - text_ydonnent de faux verts. - Regle retenue pour les fractions: tester la clairance visible estimee entre barre et glyphes, via
numerator_bottom = y + font_size * 0.25etdenominator_top = y - font_size * 0.85. - Les fractions doivent porter
class="math-expression fraction-g",data-math="fraction"et undata-boxrecalcule autour du rendu reel. - Les outils importants:
backend/tools/validate_svg_quality.py,backend/tools/regenerate_fraction_exercise_svgs.py,backend/tools/compact_fraction_svg_spacing.py,backend/tools/migrate_nombres_entiers_content.py. - Validation de fin de session: fractions strictes OK dans les deux miroirs, nombres entiers OK pendant migration,
npm.cmd run buildOK apres ajustement UI. - A retenir pour la suite: avant toute validation humaine des SVG fractions, lancer le validateur strict sur les deux miroirs et inspecter visuellement au moins le premier exercice de chaque famille, car les faux verts de baseline ont deja ete observes.