- Menu déroulant GraduationCap : Flashcards + Exercices réunis
- Fix: language non défini dans toolbar (useLanguage destructuring)
- Fix: équations 658071 → KaTeX dans exercices (preprocessMathInHtml partagé)
- lib/text/math-preprocess.ts : utilitaire partagé wizard + exercices
- Toast avec bouton 'Voir' pour rafraîchir après création exercices
- emitNoteChange pour rafraîchir la liste
- i18n FR/EN
- Générateur d'exercices déplacé du menu ⋯ vers le panneau IA (onglet Actions > Outils de génération)
- Même design que les cartes slides/diagrammes
- Fix: import useLanguage supprimé de la route API (hook client en serveur)
- i18n FR/EN
- Générateur d'exercices : bouton dans menu note → IA crée 5 exercices
- Niveaux variés (facile/moyen/difficile) avec emojis 🟢🟡🔴
- Corrigés détaillés dans des toggles (cliquer pour révéler)
- Callout warning pour le niveau
- Notes créées dans le même carnet
- Planning de révision : bouton dans barre carnet → IA crée planning
- Choix date d'examen
- Répétition espacée (première lecture → revoir → révision globale)
- Rappels automatiques ajoutés aux notes (9h le jour J)
- Vue chronologique avec activités et notes par jour
- Services : exercise-generator.service.ts + study-planner.service.ts
- Endpoints : /api/ai/generate-exercises + /api/ai/study-plan
- i18n FR/EN complet
- Wizard IA: création de carnet complet (étudiant/prof/ingénieur)
- 3 profils, choix niveau, nombre de notes (3-12)
- Étapes numérotées, messages de progression, écran de succès
- Notes riches avec callouts, toggles, équations, colonnes
- Structured View auto-créé avec propriétés Statut/Difficulté
- Embeddings en arrière-plan
- Export PDF: clone le DOM réel, rend KaTeX, préserve couleurs callouts
- Fix: boutons toggle/callout en hover-only
- Fix: parsing JSON robuste (backslashes LaTeX)
- Fix: flushSync warning (queueMicrotask)
- Fix: drag handle clamp viewport
- Bouton wizard dans la sidebar (✨ à côté du +)
- i18n FR/EN complet
- Drag handle résout les blocs conteneurs (columns, toggle, callout) au lieu du paragraphe intérieur
- Delete agit sur tout le bloc conteneur, pas juste le paragraphe
- Menu popup (block action menu) clampé dans le viewport (Math.min + overflow auto)
- Drag handle clamped dans le viewport via MutationObserver + scroll/resize
- Architecture nested nodes: columns container → column children
- CSS seamless (pas de bordures, fin séparateur vertical entre colonnes)
- isolating: true sur les deux nœuds (curseur reste dans sa colonne)
- Commands addColumnBefore/addColumnAfter/deleteColumn
- Slash menu + drag handle + raccourci Mod+Shift+L
- i18n FR/EN complet
- Calculs en pied de tableau : Somme/Moyenne/Min/Max/Compte, cliquable pour changer
- Link Preview : métadonnées persistées + texte indexable pour recherche/embeddings
- Fix: bg-memento-paper → bg-card (dark mode) sur dialogs Structured Views
- Fix: bouton Ajouter un champ → brand-accent au lieu de primary
- Calendar view retiré du sélecteur (non pertinent)
- Bloc Link Preview : colle une URL → carte avec titre, description, image, favicon
- API /api/link-preview : extraction OpenGraph + meta tags
- API /api/image-proxy : contourne le hotlinking (Referer spoofing)
- Métadonnées persistées en HTML (data-preview JSON) — pas de refetch au reload
- Texte indexable : titre + description + URL inclus pour recherche/embeddings
- Modal propre pour saisir l'URL (plus de prompt())
- Slash menu + smart paste 'Coller comme carte aperçu'
- i18n FR/EN complet
- Fix: bouton calendrier retiré du sélecteur de vue
- Nouveau bloc Toggle : sections dépliables dans l'éditeur (slash menu + drag handle)
- Transformer un bloc existant en section repliable via le menu d'action
- Boutons désactiver (unwrap) et supprimer dans l'en-tête
- i18n FR/EN complet
- Infrastructure embeddings par fragments (inspiré AppFlowy)
- Table NoteEmbeddingChunk + index HNSW
- Chunking sémantique (~1000 chars, overlap 200, dedup par hash)
- Indexation incrémentale au save (createNote + updateNote + clip)
- Queue concurrence 4, retry backoff exponentiel
Le test 'should return FEATURE_NOT_AVAILABLE for BASIC user requesting chat'
était décalé par rapport à la config actuelle où BASIC a 10 crédits chat/mois.
Remplacement par deux tests reflétant la réalité:
- BASIC sous la limite (5/10) → allowed=true, limit=10
- BASIC à la limite (10/10) → allowed=false, reason=QUOTA_EXCEEDED
ESLint v9 avec flat config ne supporte pas --max-warnings -1 (exit code 2).
On utilise 9999 comme valeur pratiquement illimitée: seules les vraies erreurs
(ex: rules-of-hooks) font échouer le CI.
Le CI échouait avec '0 errors, 38 warnings' + exitcode 1 car ESLint considère
tout warning comme un failure par défaut dans certaines configs.
--max-warnings -1 désactive ce comportement: seules les vraies erreurs (ex:
rules-of-hooks) font échouer le CI.
- fix(calendar): prefer-const — let tokens → const tokens (ligne bloquante CI)
- fix(eslint): exhaustive-deps et prefer-const rétrogradés en warn (non bloquants)
→ seul rules-of-hooks reste une erreur fatale
- fix(prisma): ajoute linux-musl-openssl-3.0.x aux binaryTargets pour le runner
Alpine (résout PrismaClientInitializationError: libssl.so.1.1 not found)
- login.tsx: bouton 'Continuer avec Google' (expo-web-browser + deep link memento://auth)
- login.tsx: bouton oeil pour afficher/masquer mot de passe
- login.tsx: message d'erreur contextuel si compte Google (pas de mot de passe en DB)
- store.ts: loginWithToken() pour recevoir le token après OAuth Google
- google-start/route.ts: lance le flux NextAuth Google avec redirect callback
- google-callback/route.ts: reçoit la session, génère token mobile, redirige vers memento://auth
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ai-chat: sélecteur tone (Professional/Créatif/Académique/Décontracté)
passé via noteContext.tone dans le body vers /api/chat
- network-graph: dragended garde fx/fy → nœud épinglé après drag
double-clic sur nœud pour désépingler (fx=null, fy=null)
- sprint-status: 6-2 et 6-3 passés en done
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
L'input caché dans le toolbar était bloqué par le conteneur parent.
Maintenant l'input est créé dynamiquement dans le handler et détruit
après usage — garanti d'ouvrir l'explorateur fichiers.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- use-auto-tagging: onQuotaExceeded via ref stable → n'invalide plus
useCallback analyzeContent à chaque render parent
- note-editor-context: filteredSuggestions et existingLabelsLower
stabilisés avec useMemo (était recalculé sans memo → nouvelle ref
à chaque render → état useMemo state se réexécutait → boucle)
- deepseek.ts: generateTags via generateText (pas generateObject)
pour éviter response_format:json_schema non supporté
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Route /api/ai/tags: supprime l'incrément sur les suggestions (UI only)
→ chaque keystroke (debounce 1.5s) ne consommait plus de quota
- notes.ts: incrément unique quand des labels IA sont réellement appliqués
en background (syncNoteLabels)
- PRO limit: 200 → 500 auto_tag/mois (200 était trop bas)
Avant: écrire une note 5min = ~20 incréments pour UNE note
Après: 1 incrément uniquement si des labels sont effectivement appliqués
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Récupère note.language (détecté automatiquement) depuis la DB
- LANG_NAMES: mapping code → nom complet (fa→Persian, ar→Arabic, zh→Chinese...)
- Injecte règle de langue absolue dans le prompt: tous les textes
des slides doivent être dans la langue de la note
- Fonctionnement pour les 15 locales du projet
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- SlideChart reçoit isDark et adapte tooltip, tick, grid, cursor, légende
- margin bottom 40px pour que les labels X-axis ne soient plus coupés
- cursor et tooltip blancs en thème clair (fini le carré noir)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- slides-renderer: chart et diagram utilisent bg/text/muted du thème
(plus de fond #111827 forcé)
- slides.tool: prompt ultra-clair (<50 mots = max 3 slides)
+ cappedSlides.slice(0,8) côté serveur comme filet de sécurité
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- JAMAIS plus de 8 slides quelle que soit la note
- Zod schema: .max(8) coupe l'array si le modèle déborde
- Prompt: ignore markdown/URLs dans le comptage de mots
- Chart seulement si vraies données numériques dans la note
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Le graphe était noir car recharts cherchait xKey='name' mais les données
avaient {label,value}. Fix dans normalizeSlide case 'chart':
- data.map({label,value} → {name,value})
- xKey: 'name', yKeys: ['value'] explicitement
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- slides-renderer: SlideChart supporte le nouveau format plat
(slide.chartType + slide.data[{label,value}]) en plus de slide.chart
→ corrige la slide noire avec légende visible mais graphe vide
- slides.tool: nombre de slides adapté au contenu
(3-4 pour note courte, 5-7 moyenne, 8-12 longue)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reverts le changement qui avait cassé les graphes des slides.
data.spec → SlidesRenderer (recharts, graphes OK)
data.html → iframe (fallback si pas de spec)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- canvas-board.tsx: préfère data.html (iframe) sur data.spec (ancien renderer)
→ corrige slide 3 noire en mode HTML viewer
- pptx/route.ts: ajoute watermark 'memento-note.com' sur chaque slide
via buildPptx (PPTX téléchargé depuis le canvas)
- run-for-note/route.ts: checkEntitlementOrThrow avant création agent
- slides.tool.ts: incrementUsageAsync après canvas créé avec succès
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- export-pptx.ts: fix watermark position for LAYOUT_WIDE (13.33"×7.5")
→ moved from y:5.35 (71% height) to y:7.1 near bottom-right (x:10.0)
- export-pptx.ts: fix buildSummarySlide dark background (T.primary overlay
covered 100% of slide appearing black) → cream bg with colored stat cards
matching design of other brainstorm slides
- pptx.tool.ts: fix addImageFullSlide using t.primary as bg when no imageUrl
→ falls back to t.bg (light); text colors adapt accordingly
- pricing/page.tsx: create /pricing standalone page reusing exact landing
page pricing section (PLANS array, billing toggle, i18n keys)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>