6.4 KiB
title, type, created, status, context
| title | type | created | status | context |
|---|---|---|---|---|
| Reconstruire le parcours utilisateur glossaire | refactor | 2026-05-16 | draft |
Intent
Problem: L'utilisateur Pro voit DEUX liens "Glossaires" dans la sidebar à cause d'un doublon dans constants.ts (baseNavItems contient un item glossary + proNavItem est aussi un item glossary → getNavItems(isPro=true) retourne les deux). Le GlossarySelector sur la page de traduction est un petit dropdown caché, visible uniquement pour les Pro, sans label ni indication de son rôle. L'utilisateur ne comprend pas le cheminement: créer un glossaire → le sélectionner → traduire.
Approach: Corriger le doublon de navigation, rendre le GlossarySelector visible et explicatif pour TOUS les utilisateurs (les Free voient un badge "Pro"), supprimer la page Context obsolète, et ajouter un lien clair entre la page Glossaires et la page Traduction.
Boundaries & Constraints
Always:
- Un seul lien "Glossaires" dans la sidebar, jamais deux
- Le GlossarySelector doit être visible sur la page de traduction pour TOUS les utilisateurs connectés
- Les utilisateurs Free doivent voir le sélecteur grisé avec un badge "Pro" (pas caché)
- Le system prompt reste sur la page Glossaires (déjà fusionné)
- Backend inchangé — seul le frontend est touché
Ask First: Aucune décision ambiguë — tout est clair.
Never:
- Ne pas toucher aux routes API ou au backend
- Ne pas recréer une page Context séparée
- Ne pas supprimer les presets professionnels (HVAC, IT, etc.)
I/O & Edge-Case Matrix
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|---|---|---|---|
| Utilisateur Pro voit la sidebar | isPro=true, page quelconque | Un seul lien "Glossaires" dans le menu | N/A |
| Utilisateur Free voit la sidebar | isPro=false | Aucun lien Glossaires (proOnly=true) | N/A |
| Utilisateur Free sur page traduction | isPro=false, mode LLM | GlossarySelector visible mais grisé, badge "Pro", clic → tooltip "Upgrade required" | N/A |
| Utilisateur Pro sur page traduction | isPro=true | GlossarySelector fonctionnel, dropdown avec ses glossaries | Toast si fetch échoue |
| Utilisateur avec 0 glossaries | glossaries=[] | Sélecteur affiche "Aucun glossaire — Créez-en un" avec lien vers /dashboard/glossaries | N/A |
| Utilisateur accède /dashboard/context par URL | N'importe quel état | Redirige vers /dashboard/glossaries | N/A |
Code Map
frontend/src/app/dashboard/constants.ts-- Navigation: contient le doublon glossary (baseNavItems + proNavItem)frontend/src/app/dashboard/translate/page.tsx-- Page traduction: emplacement du GlossarySelector, conditions de visibilitéfrontend/src/app/dashboard/translate/GlossarySelector.tsx-- Composant dropdown de sélection de glossairefrontend/src/app/dashboard/translate/useTranslationConfig.ts-- Hook qui gère glossaryIdfrontend/src/app/dashboard/context/page.tsx-- Page obsolète à supprimer/remplacer par redirectfrontend/src/app/dashboard/glossaries/page.tsx-- Page Glossaries fusionnée (OK, pas toucher)
Tasks & Acceptance
Execution:
frontend/src/app/dashboard/constants.ts-- SupprimerproNavItemet la fonctiongetNavItems, remettre les items proOnly dansbaseNavItemsavec le flag proOnly. Garder exactement 4 items: Translate, Profile, Glossaries (proOnly), API Keys (proOnly). -- Un seul lien glossary dans la sidebar, jamais de doublon.frontend/src/app/dashboard/translate/GlossarySelector.tsx-- Refactoriser: toujours rendre le composant visible (même pour Free). Si l'utilisateur n'est pas Pro: afficher le dropdown grisé avec badge "Pro" et tooltip "Upgrade required". Si l'utilisateur est Pro mais n'a pas de glossaries: afficher un message "Aucun glossaire" avec un lien cliquable vers /dashboard/glossaries. Ajouter le composantuseUserou recevoirisProen prop. -- Tous les utilisateurs voient le sélecteur, les Free comprennent que c'est Pro.frontend/src/app/dashboard/translate/page.tsx-- Retirer la conditionconfig.isPro &&autour du GlossarySelector. Placer le GlossarySelector à un endroit visible dans le panneau de config (entre ProviderSelector et le bouton Traduire). S'assurer queisProest passé en prop au GlossarySelector. -- Le sélecteur est visible pour tous, pas caché derrière une condition.frontend/src/app/dashboard/context/page.tsx-- Remplacer tout le contenu par un redirect côté client vers/dashboard/glossaries(useRouter+useEffectourouter.replace). -- L'ancienne URL redirige proprement.
Acceptance Criteria:
- Given un utilisateur Pro connecté, when il regarde la sidebar, then il voit exactement UN lien "Glossaires"
- Given un utilisateur Free connecté, when il va sur la page de traduction, then il voit le GlossarySelector grisé avec un badge "Pro"
- Given un utilisateur Pro avec des glossaries, when il va sur la page de traduction, then il peut sélectionner un glossary dans le dropdown
- Given un utilisateur Pro sans glossary, when il va sur la page de traduction, then le sélecteur affiche "Aucun glossaire" avec un lien vers la page Glossaires
- Given n'importe quel utilisateur, when il accède /dashboard/context, then il est redirigé vers /dashboard/glossaries
Spec Change Log
Design Notes
Parcours utilisateur attendu:
- L'utilisateur clique sur "Glossaires" dans la sidebar → arrive sur la page unifiée (system prompt + presets + CRUD glossaires)
- L'utilisateur crée ou charge un glossaire (manuel, CSV, template)
- L'utilisateur va sur "Traduire" → voit le sélecteur "Glossaire" en clair → sélectionne son glossaire → traduit
- Le glossaire est appliqué automatiquement à la traduction
Le GlossarySelector doit recevoir isPro et disabled en props. Si !isPro, le composant se rend en mode "locked" (grisé + badge Pro). Si isPro && glossaries.length === 0, afficher un CTA vers la page glossaires.
Verification
Commands:
cd frontend && npx next build --webpack-- expected: build réussi sans erreurs TypeScript
Manual checks:
- Sidebar Pro: exactement un lien Glossaires
- Sidebar Free: aucun lien Glossaires
- Page traduction Free: GlossarySelector visible mais grisé avec badge Pro
- Page traduction Pro: GlossarySelector fonctionnel
- URL /dashboard/context: redirige vers /dashboard/glossaries