CLAUDE.md — UQO-Chat (copie de travail)
La spécification d'origine (28 sections) est la référence produit ; ce fichier résume ce qui est
implémenté, les écarts assumés et les règles à respecter en travaillant dans ce dépôt.
Voir README.md pour le démarrage et le déploiement.
Règles d'or (inchangées)
- Aucun code étudiant/LLM ne s'exécute dans le processus API : toujours
sandbox-runner(app/sandbox/client.py). - Un seul point d'entrée LLM :
app/llm/openrouter.py→LLMClient. - Slugs de modèles = config (
app/core/config.py, env). Vérifier https://openrouter.ai/models avant d'en changer (vérifiés 2026-09-05 :anthropic/claude-fable-5.1(primaire depuis le 2026-09-06),openai/gpt-5.5,anthropic/claude-opus-4.6,openai/gpt-5.4-nano). - Chaque outil =
app/tools/<nom>.py+app/tools/schemas/<nom>.json+ test + cartefrontend/src/components/tools/<nom>-card.tsx. - Streaming SSE partout (
app/api/v1/chat.py), français dans l'UI/prompts, anglais dans le code. - Jamais de contenu de message dans les logs (
app/core/logging.pymasquecontent,text,email…). - Mobile-first (375 px) ; QA Playwright :
python3 /tmp/uqo-qa/qa.py(captures 375/1440, détection d'overflow).
État (v0.3, 2026-09-06)
- 13 outils : search_course_content, appraisal_calc, financial_calc, unit_convert, execute_python, make_chart, create_excel, inspect_excel, edit_excel, create_docx, analyze_file, web_search, generate_quiz. Auth (v0.5) : liste blanche gérée par le professeur → invitation Resend « choisis ton mot de passe » (
/mot-de-passe?token=) → connexion courriel + mot de passe (PBKDF2) ; « première connexion / mot de passe oublié » par courriel ; plus de code d'accès. Tableau de bord prof : Activité, Étudiants (ajout en lot + invitations, relances, statut activé/invité, mots de passe manuels), Contenu, Réglages. Modèle par défautanthropic/claude-fable-5.1, budget 2 000 $ US/mois. - Backend FastAPI 3.12 : auth (invitation/réinitialisation par courriel Resend + mot de passe ;
services/mail.py,services/invites.py), conversations, chat SSE avec boucle agentique (8 itérations, outils en parallèle), 7 outils, RAG BM25 sur les sites de notes (rag/ingest.pylit le HTML générédist/<cours>/seance/NN), quiz, fichiers (TTL), tableau de bord prof (analytics anonymisées, ingestion, réglages, annonces), coûts admin, purge/anonymisation horaire. - Frontend React 18 + Vite + Tailwind : chat mobile/desktop, cartes d'outils, quiz interactif, panneau fichiers/sources, préférences, Loi 25 (consentement, suppression), PWA (précache ≈ 2 Mo).
- Sandbox :
sandbox-runner/(FastAPI) exécutepython -I -Bsoussandbox-exec(macOS) : réseau interdit, écriture confinée, rlimits, timeout, figures matplotlib capturées. - Déploiement :
mld(PM2uqo-chat-api:8190 +uqo-chat-sandbox:8191 +uqo-chat-ngrokwww.uqo-chat.app). Secrets dansM1M32:~/dispatch/apps/uqo-chat.json.
Écarts assumés
SQLite au lieu de Postgres/pgvector (Postgres accepté via DATABASE_URL) ; cache/limiteur mémoire au lieu de Redis ; fichiers sur disque au lieu de MinIO ; BM25 au lieu d'embeddings (OpenRouter n'en propose pas ; EMBEDDINGS_BASE_URL optionnel) ; create_all au lieu d'Alembic ; Resend (API HTTP) au lieu d'un SMTP, mot de passe au lieu du lien magique à chaque connexion. k8s/ + docker-compose.yml décrivent la cible complète de la spec.
À faire (roadmap spec)
Export PDF de conversation ; file d'attente hors-ligne (Background Sync) ; évaluation pédagogique automatique en CI (40 questions/cours, juge MODEL_FAST) ; tests adverses sandbox complets ; Alembic ; migration éventuelle Postgres/pgvector ; autorisation du logo officiel UQO (VITE_USE_OFFICIAL_LOGO).