## Translation Files - Add 11 new language files (es, de, pt, ru, zh, ja, ko, ar, hi, nl, pl) - Add 100+ missing translation keys across all 15 languages - New sections: notebook, pagination, ai.batchOrganization, ai.autoLabels - Update nav section with workspace, quickAccess, myLibrary keys ## Component Updates - Update 15+ components to use translation keys instead of hardcoded text - Components: notebook dialogs, sidebar, header, note-input, ghost-tags, etc. - Replace 80+ hardcoded English/French strings with t() calls - Ensure consistent UI across all supported languages ## Code Quality - Remove 77+ console.log statements from codebase - Clean up API routes, components, hooks, and services - Keep only essential error handling (no debugging logs) ## UI/UX Improvements - Update Keep logo to yellow post-it style (from-yellow-400 to-amber-500) - Change selection colors to #FEF3C6 (notebooks) and #EFB162 (nav items) - Make "+" button permanently visible in notebooks section - Fix grammar and syntax errors in multiple components ## Bug Fixes - Fix JSON syntax errors in it.json, nl.json, pl.json, zh.json - Fix syntax errors in notebook-suggestion-toast.tsx - Fix syntax errors in use-auto-tagging.ts - Fix syntax errors in paragraph-refactor.service.ts - Fix duplicate "fusion" section in nl.json 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Ou une version plus courte si vous préférez : feat(i18n): Add 15 languages, remove logs, update UI components - Create 11 new translation files (es, de, pt, ru, zh, ja, ko, ar, hi, nl, pl) - Add 100+ translation keys: notebook, pagination, AI features - Update 15+ components to use translations (80+ strings) - Remove 77+ console.log statements from codebase - Fix JSON syntax errors in 4 translation files - Fix component syntax errors (toast, hooks, services) - Update logo to yellow post-it style - Change selection colors (#FEF3C6, #EFB162) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
34 KiB
Product Requirements Document (PRD)
Notebooks & Labels Contextuels avec IA
Project: Keep (Memento Phase 1 MVP AI) Date: 2026-01-11 Author: Sally (UX Designer) + Ramez (Product Owner) Status: Draft - Ready for Architecture Priority: High - Core Feature Reorganization
📋 Executive Summary
Vision
Transformer l'organisation de Keep d'un système de tags plat en une structure de Notebooks avec Labels Contextuels, où chaque notebook a sa propre taxonomie de labels, permettant une organisation plus naturelle et contextuelle.
Objectifs Principaux
- ✅ Introduire les Notebooks comme organisation principale
- ✅ Rendre les Labels contextuels à chaque notebook
- ✅ Créer une Inbox ("Notes générales") pour les notes non organisées
- ✅ Intégrer l'IA intelligemment dans cette nouvelle structure
- ✅ Permettre une migration douce depuis le système actuel
🎯 User Stories
Primary Users
- Ramez (Power User): Utilise Keep quotidiennement pour organiser voyage, travail, vie perso
- Professionnel: Gère des projets avec des contextes différents
- Voyageur: Organise ses préparatifs de voyage avec des notes spécifiques
User Journey Exemple
Scénario 1: Création de note dans Notebook
1. Ramez ouvre Keep, navigue vers Notebook "Voyage"
2. Il voit les labels contextuels: #hôtels, #vols, #restos
3. Il clique "Nouvelle note"
4. La note est automatiquement assignée au Notebook "Voyage"
5. Il peut tagger avec #hôtels (disponible car dans le bon contexte)
Scénario 2: Note rapide dans Inbox
1. Ramez a une idée rapide, ouvre Keep (page d'accueil)
2. Il tape son idée et sauve
3. La note va dans "Notes générales" (Inbox)
4. Plus tard, il la déplace vers "Notebook Perso"
5. Les labels de "Perso" deviennent disponibles
Scénario 3: Organisation IA-assistée
1. Ramez a 15 notes dans "Notes générales"
2. Il clique "Organiser avec l'IA"
3. L'IA analyse les notes et propose:
- "3 notes pour Notebook Voyage"
- "5 notes pour Notebook Travail"
- "7 notes pour Notebook Perso"
4. Ramez valide les suggestions
5. Les notes sont déplacées automatiquement
🏗️ Structure de l'Organisation
Hiérarchie
KEEP
├─ 📥 Notes générales (Inbox)
│ └─ Notes sans notebook assigné
│ └─ PAS de labels (zone temporaire)
│
├─ 📚 Notebooks (ordonnés manuellement)
│ ├─ ✈️ Voyage
│ │ ├─ Labels: #hôtels, #vols, #restos, #à_visiter
│ │ └─ Notes assignées à "Voyage"
│ │
│ ├─ 💼 Travail
│ │ ├─ Labels: #réunions, #projets, #urgent, #à_faire
│ │ └─ Notes assignées à "Travail"
│ │
│ └─ 📖 Perso
│ ├─ Labels: #idées, #rêves, #objectifs, #réflexions
│ └─ Notes assignées à "Perso"
│
└─ [+] Nouveau Notebook
Règles Métier
R1: Appartenance des Notes
- Une note appartient à UN seul notebook (ou aucune)
- Les notes dans "Notes générales" n'appartiennent à aucun notebook
- Une note ne peut être dans plusieurs notebooks simultanément
R2: Labels Contextuels
- Chaque notebook a ses propres labels (100% isolés)
- Les labels sont créés/supprimés au niveau notebook
- Les notes dans "Notes générales" n'ont pas accès aux labels
R3: Ordre des Notebooks
- Les notebooks sont ordonnés manuellement (drag & drop)
- L'ordre est personnalisé par utilisateur
- Drag & drop dans la sidebar pour réorganiser
R4: Vue "Notes générales"
- Affiche SEULEMENT les notes sans notebook
- PAS de vue "Toutes les notes" (tous notebooks confondus)
- C'est une zone temporaire d'organisation
🎨 UX/UI Specifications
1. Navigation - Sidebar
┌─────────────────────────────────────┐
│ KEEP LOGO │
├─────────────────────────────────────┤
│ 🔍 Search │
├─────────────────────────────────────┤
│ 📚 NOTEBOOKS │
│ ┌───────────────────────────────┐ │
│ │ 📥 Notes générales (12) │ │ ← Compteur de notes
│ │ │ │
│ │ ✈️ Voyage (8) │ │ ← Notebook actif = highlight
│ │ ┌─ 🏷️ Labels contextuels │ │
│ │ │ • #hôtels (3) │ │ ← Labels seulement si actif
│ │ │ • #vols (2) │ │
│ │ │ • #restos (3) │ │
│ │ │ [+ Nouveau label] │ │
│ │ └─────────────────────────────┘ │
│ │ │ │
│ │ 💼 Travail (15) │ │ ← Handles pour drag & drop
│ │ ║ ║ │ │
│ │ 📖 Perso (23) │ │
│ │ ║ ║ │ │
│ └───────────────────────────────┘ │
│ │
│ [+ Nouveau Notebook] │
└─────────────────────────────────────┘
Comportements:
- Click sur notebook → Navigue vers ce notebook
- Drag & drop des notebooks → Réorganise l'ordre
- Hover sur notebook → Affiche les labels contextuels
- [+ Nouveau label] → Crée un label dans ce notebook
- Compteurs → Montre le nombre de notes
2. Création de Note
Cas A: Depuis un Notebook
User dans "Voyage" → [Nouvelle note]
├─ Note créée avec notebookId = "voyage"
├─ Peut utiliser les labels de "Voyage"
└─ UI: Badge "Voyage" visible sur la note
Cas B: Depuis Notes Générales
User sur page d'accueil → [Nouvelle note]
├─ Note créée avec notebookId = null
├─ PAS de labels disponibles
└─ UI: Badge "À trier" visible
Cas C: Création dans un autre notebook
User dans "Voyage", veut créer pour "Travail"
├─ DOIT naviguer vers "Travail" d'abord
├─ OU utilise le raccourci clavier (ex: Ctrl+N → chooser)
└─ PAS de modal à chaque création
3. Déplacement de Notes (Option C: A + B)
Méthode A: Drag & Drop
┌─────────────────────────────────────┐
│ 📝 Note à déplacer │
│ ┌───────────────────────────────┐ │
│ │ Grip handle │ Note content... │ │ ← Drag depuis ici
│ └───────────────────────────────┘ │
│ ↓ │
│ Drop vers sidebar → │
│ ┌───────────────────────────────┐ │
│ │ ✈️ Voyage [Drop zone] │ │
│ │ 💼 Travail [Drop zone] │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Méthode B: Menu Contextuel
Sur une note → Click droit → Menu:
├─ 📋 Copier
├─ ✏️ Modifier
├─ 📚 Déplacer vers...
│ ├─ 📥 Notes générales
│ ├─ ✈️ Voyage
│ ├─ 💼 Travail
│ └─ 📖 Perso
├─ 🏷️ Ajouter un label
├─ 📌 Épingler
└─ 🗑️ Supprimer
Validation:
- ✅ Drag & drop vers notebook dans sidebar
- ✅ Menu contextuel "Déplacer vers..."
- ✅ Les deux méthodes disponibles
4. Labels Contextuels
Création de Label
Dans Notebook "Voyage":
┌─────────────────────────────────────┐
│ 🏷️ Labels │
│ • #hôtels • #vols • #restos │
│ [+ Nouveau label] │ ← Click
├─────────────────────────────────────┤
│ Modal: │
│ ┌───────────────────────────────┐ │
│ │ Nom du label: │ │
│ │ [___________] │ │
│ │ │ │
│ │ Couleur: ○ 🟡 ○ 🔴 ○ 🔵 │ │
│ │ │ │
│ │ [Annuler] [Créer] │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Assignation de Label à Note
Note dans "Voyage" → Click "Ajouter label"
├─ Seuls les labels de "Voyage" sont proposés
├─ Dropdown avec checkboxes
└─ Multi-label possible sur une note
Exemple:
📝 Note: "Hôtel Tokyo Shibuya"
├─ Notebook: ✈️ Voyage
└─ Labels: #hôtels, #réservations
Suppression de Label
Options:
├─ Supprimer le label (du notebook)
│ └─ Warning: "Ce label sera retiré de X notes. Continuer?"
└─ Retirer des notes seulement
└─ Label existe toujours, mais plus utilisé
5. Gestion des Notebooks
Création de Notebook
Click [+ Nouveau Notebook]
├─ Modal de création
│ ├─ Nom: "Voyage"
│ ├─ Icône: [Sélecteur d'emoji]
│ ├─ Couleur: [Sélecteur de couleur]
│ └─ [Créer]
└─ Notebook créé à la fin de la liste
Édition de Notebook
Click droit sur notebook → Menu:
├─ ✏️ Modifier
│ └─ Modal: Nom, Icône, Couleur
├─ 📊 Statistiques
│ ├─ Nombre de notes
│ ├─ Labels utilisés
│ └─ Dernière mise à jour
├─ 🗑️ Supprimer
│ └─ Warning: "Les notes seront déplacées vers Notes générales"
└─ ❌ Fermer
Réorganisation (Drag & Drop)
✈️ Voyage ║ ║ ← Drag handle
💼 Travail ║ ║
📖 Perso ║ ║
Drag "Travail" vers le haut → Réordonne
🤖 Intégration IA
C'est la partie CRUCIALE qui rend cette feature vraiment puissante.
IA1: Suggestion Automatique de Notebook
Scénario
User crée une note dans "Notes générales":
"Rendez-vous dermatologue mardi 15h à Paris"
IA analyse et suggère:
┌─────────────────────────────────────┐
│ 💡 Suggestion IA │
│ ┌───────────────────────────────┐ │
│ │ Cette note semble appartenir │ │
│ │ au notebook "Perso". │ │
│ │ │ │
│ │ [Ignorer] [Déplacer vers Perso]│ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Prompt IA:
"Analyse cette note et suggère le notebook le plus approprié:
Note: {content}
Notebooks disponibles: {notebook_names_with_labels}
Réponds avec:
- notebook_suggéré: string
- confiance: 0-1
- raisonnement: string"
Déclencheurs:
- Note créée dans "Notes générales"
- Note modifiée significativement
- 5+ secondes après la fin de frappe (pas en temps réel)
IA2: Suggestion de Labels Contextuels
Scénario
Note dans Notebook "Voyage":
"Hotel Shibuya Excel - 150€/nuit - Booking confirmé"
IA suggère:
┌─────────────────────────────────────┐
│ 💡 Suggestions de labels │
│ ┌───────────────────────────────┐ │
│ │ ✅ #hôtels (confiance: 95%) │ │ ← Click pour assigner
│ │ ✅ #réservations (80%) │ │
│ │ ✅ #tokyo (70%) │ │
│ │ │ │
│ │ [Tout sélectionner] [Ignorer] │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Prompt IA:
"Analyse cette note et suggère les labels appropriés:
Note: {content}
Notebook actuel: {notebook_name}
Labels disponibles dans ce notebook: {available_labels}
Réponds avec un tableau de:
- label: string (doit être dans {available_labels})
- confiance: 0-1
- raisonnement: string"
Comportement:
- ✅ Maximum 3 suggestions
- ✅ Seulement si confiance > 60%
- ✅ Labels cliquables pour assignation en 1 clic
- ✅ Ne pas déranger si l'utilisateur tape activement
IA3: Organisation Intelligente (Batch Processing)
Scénario
User a 20 notes dans "Notes générales"
Click "Organiser avec l'IA"
├─ IA analyse toutes les notes
├- Groupe par thématique
└─ Présente un plan d'organisation:
┌─────────────────────────────────────┐
│ 📋 Plan d'organisation IA │
│ ┌───────────────────────────────┐ │
│ │ Notebook: Voyage (5 notes) │ │
│ │ • Hotel Tokyo... │ │
│ │ • Vols JAL... │ │
│ │ • Restaurant Shibuya... │ │
│ │ [Tout sélectionner] │ │
│ │ │ │
│ │ Notebook: Travail (8 notes) │ │
│ │ • Réunion lundi... │ │
│ │ • Projet Alpha... │ │
│ │ ... │ │
│ │ │ │
│ │ Notebook: Perso (7 notes) │ │
│ │ • Idées livre... │ │
│ │ ... │ │
│ │ │ │
│ │ [Annuler] [Appliquer tout] │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Prompt IA:
"Analyse ces {count} notes et propose une organisation:
{notes_with_content}
Notebooks disponibles: {notebooks}
Pour chaque notebook, indique:
- notebook_cible: string
- notes: [{note_id, note_title, confidence, raison}]
Retourne un plan d'organisation optimisé."
Validation:
- ✅ User peut désélectionner des notes
- ✅ User peut ajuster les destinations
- ✅ Confirmation avant application
- ✅ Undo possible (Ctrl+Z)
IA4: Création Automatique de Labels
Scénario
Notebook "Voyage" devient peuplé de notes sur le Japon
IA détecte:
- 10+ notes mentionnant "Tokyo"
- 8+ notes mentionnant "Kyoto"
- 5+ notes mentionnant "Osaka"
IA suggère:
┌─────────────────────────────────────┐
│ 💡 Suggestions de nouveaux labels │ │
│ ┌───────────────────────────────┐ │
│ │ J'ai détecté des thèmes récurrents│
│ │ dans vos notes. Créer des labels?│
│ │ │ │
│ │ ✅ #tokyo (10 notes) │ │
│ │ ✅ #kyoto (8 notes) │ │
│ │ ✅ #osaka (5 notes) │ │
│ │ │ │
│ │ [Annuler] [Créer et assigner] │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Déclencheur:
- Notebook atteint 15+ notes
- IA détecte 3+ mots-clés récurrents (5+ fois chacun)
- Ne propose PAS si les labels existent déjà
IA5: Recherche Sémantique par Notebook
Scénario
User dans Notebook "Voyage" tape:
"endroit pour dormir pas cher"
IA comprend le contexte "Voyage" et cherche:
├─ Semantic search DANS ce notebook seulement
├- Priorise les labels #hôtels, #auberges
└- Résultats plus pertinents car contextuels
Résultats:
┌─────────────────────────────────────┐
│ 🔍 Résultats dans "Voyage" │
│ ┌───────────────────────────────┐ │
│ │ 📝 Capsule Hotel Shinjuku │ │
│ │ #hôtels #tokyo │ │
│ │ "Hotel capsule 30€/nuit..." │ │
│ │ Correspondance: 87% │ │
│ │ │ │
│ │ 📝 Airbnb Asakusa │ │
│ │ #hôtels #tokyo │ │
│ │ "Appartement 45€/nuit..." │ │
│ │ Correspondance: 82% │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Avantage:
- ✅ Recherche contextuelle au notebook
- ✅ Résultats plus pertinents
- ✅ Comprend le jargon spécifique (ex: "vol" dans Voyage vs Travail)
IA6: Synthèse par Notebook
Scénario
User clique "Résumer ce notebook" dans "Voyage"
IA génère:
┌─────────────────────────────────────┐
│ 📊 Synthèse du Notebook Voyage │
│ ┌───────────────────────────────┐ │
│ │ 🌍 Destinations │ │
│ │ • Japon (Tokyo, Kyoto) │ │
│ │ • France (Paris) │ │
│ │ │ │
│ │ 📅 Dates │ │
│ │ • 15-25 Mars 2024 │ │
│ │ │ │
│ │ 🏨 Réservations │ │
│ │ • 3 hôtels réservés │ │
│ │ • 2 vols confirmés │ │
│ │ • 5 restaurants identifiés │ │
│ │ │ │
│ │ 💰 Budget estimé: 3500€ │ │
│ │ │ │
│ │ ⚠️ Actions requises │ │
│ │ • Réserver visa japonais │ │
│ │ • Confirmer assurance voyage │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Prompt IA:
"Génère une synthèse structurée de ce notebook:
{notes_with_labels}
Inclus:
- Destinations/Thèmes principaux
- Dates importantes
- Éléments réservés vs planifiés
- Actions requises
- Statistiques (nombre de notes, labels utilisés)
Format: Markdown structuré avec emojis."
🗄️ Structure de Données (Database Schema)
Prisma Schema - Nouveaux Modèles
// Modèle Notebook
model Notebook {
id String @id @default(cuid())
name String
icon String? // Emoji: "✈️", "💼", "📖"
color String? // Hex color: "#FF6B6B"
order Int // Ordre manuel dans la sidebar
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
notes Note[]
labels Label[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId, order])
}
// Modèle Label MODIFIÉ - Ajout notebookId
model Label {
id String @id @default(cuid())
name String
color String? // Couleur du label
notebookId String // NOUVEAU: Label appartient à un notebook
notebook Notebook @relation(fields: [notebookId], references: [id], onDelete: Cascade)
notes Note[] // Relation many-to-many via NoteLabel
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([notebookId, name]) // Un label est unique dans un notebook
@@index([notebookId])
}
// Modèle Note MODIFIÉ - Ajout notebookId (optionnel)
model Note {
id String @id @default(cuid())
title String?
content String
// ... autres champs existants ...
notebookId String? // NOUVEAU: Optionnel - null = dans "Notes générales"
notebook Notebook? @relation(fields: [notebookId], references: [id], onDelete: SetNull)
// Garantir qu'une note est dans UN SEUL notebook
@@index([userId, notebookId])
}
// Table de jonction Note-Label (existante mais gardée)
model NoteLabel {
noteId String
labelId String
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
label Label @relation(fields: [labelId], references: [id], onDelete: Cascade)
@@id([noteId, labelId])
@@index([noteId])
@@index([labelId])
}
Clés de la Structure
Règles d'intégrité:
- ✅
Note.notebookIdest optionnel (null = Notes générales) - ✅
Label.notebookIdest obligatoire (labels TOUJOURS contextuels) - ✅
@@unique([notebookId, name])= Unicité des labels DANS un notebook - ✅
onDelete: SetNullsur Note→Notebook = Si notebook supprimé, notes → Notes générales
Migration Schema
-- Étape 1: Ajouter les nouveaux modèles
CREATE TABLE "Notebook" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"icon" TEXT,
"color" TEXT,
"order" INTEGER NOT NULL,
"userId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- Étape 2: Ajouter notebookId aux Notes (optionnel)
ALTER TABLE "Note" ADD COLUMN "notebookId" TEXT;
ALTER TABLE "Note" ADD FOREIGN KEY ("notebookId") REFERENCES "Notebook"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- Étape 3: Ajouter notebookId aux Labels (obligatoire)
ALTER TABLE "Label" ADD COLUMN "notebookId" TEXT NOT NULL DEFAULT 'TEMP_MIGRATION';
ALTER TABLE "Label" ADD FOREIGN KEY ("notebookId") REFERENCES "Notebook"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- Étape 4: Créer notebook par défaut pour la migration
INSERT INTO "Notebook" (id, name, icon, color, "order", "userId")
VALUES (
'migration_default',
'Labels existants',
'📦',
'#9CA3AF',
999,
{user_id}
);
-- Étape 5: Assigner tous les labels existants à ce notebook
UPDATE "Label" SET "notebookId" = 'migration_default' WHERE "notebookId" = 'TEMP_MIGRATION';
-- Étape 6: Laisser toutes les notes SANS notebook (Notes générales)
-- Rien à faire - notebookId est déjà NULL par défaut
-- Étape 7: Créer index pour performance
CREATE INDEX "Note_userId_notebookId_idx" ON "Note"("userId", "notebookId");
CREATE UNIQUE INDEX "Label_notebookId_name_key" ON "Label"("notebookId", "name");
🔄 Migration des Données Existantes
Stratégie de Migration
Phase 1: Pré-migration (Backend)
// app/actions/migration/prepare-notebooks.ts
'use server'
export async function prepareNotebookMigration() {
const session = await auth()
if (!session?.user?.id) throw new Error('Unauthorized')
// 1. Créer notebook "Import" pour les labels existants
const importNotebook = await prisma.notebook.create({
data: {
name: 'Labels existants',
icon: '📦',
color: '#9CA3AF',
order: 999,
userId: session.user.id
}
})
// 2. Assigner TOUS les labels existants à ce notebook
await prisma.label.updateMany({
where: { userId: session.user.id },
data: { notebookId: importNotebook.id }
})
// 3. Laisser les notes SANS notebook (Notes générales)
// Rien à faire - notebookId est NULL par défaut
return { success: true, importNotebookId: importNotebook.id }
}
Phase 2: Migration Interactive (User Journey)
┌─────────────────────────────────────────────────────────┐
│ 🎉 Bienvenue dans les Notebooks ! │
│ │
│ Nous avons organisé vos étiquettes existantes dans │
│ le notebook "Labels existants" pour ne rien perdre. │
│ │
│ 📊 État actuel: │
│ • 15 notes sans notebook (à organiser) │
│ • 1 notebook "Labels existants" │
│ • 12 étiquettes préservées │
│ │
│ Que voulez-vous faire ? │
│ │
│ [1] Laisser l'IA organiser mes notes │
│ [2] Explorer et créer mes propres notebooks │
│ [3] Tout déplacer vers "Notes générales" │
│ │
│ [Plus tard] Je déciderai plus tard │
└─────────────────────────────────────────────────────────┘
Phase 3: Organisation IA (Option 1)
Si user choisit "Laisser l'IA organiser":
// app/actions/migration/ai-organize.ts
'use server'
export async function organizeWithAI() {
const session = await auth()
const notesWithoutNotebook = await prisma.note.findMany({
where: {
userId: session.user.id,
notebookId: null
}
})
// IA analyse et propose des notebooks
const suggestions = await aiService.suggestNotebooks(notesWithoutNotebook)
return {
success: true,
suggestions: [
{
notebookName: 'Voyage',
icon: '✈️',
color: '#3B82F6',
notes: [/* notes suggérées */],
confidence: 0.89
},
{
notebookName: 'Travail',
icon: '💼',
color: '#10B981',
notes: [/* notes suggérées */],
confidence: 0.92
}
]
}
}
Phase 4: Validation User
┌─────────────────────────────────────────────────────────┐
│ 📋 Plan d'organisation proposé par l'IA │
│ │
│ ✈️ Voyage (5 notes) - Confiance: 89% │
│ ☑ Hotel Tokyo Shibuya │
│ ☑ Vols JAL Tokyo-Paris │
│ ☑ Restaurant Shibuya │
│ ☑ Visa japonais │
│ ☑ Itinéraire Kyoto │
│ │
│ 💼 Travail (8 notes) - Confiance: 92% │
│ ☑ Réunion lundi │
│ ☑ Projet Alpha │
│ ☑ ... │
│ │
│ 📖 Perso (2 notes) - Confiance: 76% │
│ ☑ Idées livre │
│ ☑ Objectifs 2024 │
│ │
│ [Désélectionner] [Annuler] [Appliquer] │
└─────────────────────────────────────────────────────────┘
🎯 Success Metrics
KPIs à Mesurer
Adoption:
- % d'utilisateurs créant au moins 1 notebook dans les 30 jours
- Nombre moyen de notebooks par utilisateur actif
- % de notes organisées (avec notebook) vs notes générales
Engagement:
- Temps passé par notebook (ex: Voyage plus actif avant un voyage)
- Fréquence d'utilisation des labels contextuels
- Taux d'utilisation des suggestions IA
Satisfaction:
- NPS (Net Promoter Score) sur la feature notebooks
- % d'utilisateurs gardant le système par défaut (Import) vs créant les leurs
- Taux d'abandon lors de la migration
Performance IA:
- Taux d'acceptation des suggestions IA (notebook)
- Taux d'acceptation des suggestions IA (labels)
- Précision des suggestions (feedback utilisateur)
🚀 Implementation Phases
Phase 1: MVP (Weeks 1-3)
Objectif: Structure de base sans IA
- ✅ Database schema (Notebook, Label modifié, Note modifié)
- ✅ API endpoints (CRUD notebooks)
- ✅ UI: Sidebar avec notebooks
- ✅ UI: Création/édition de notebooks
- ✅ UI: Assignation de notebook aux notes
- ✅ UI: Labels contextuels (affichage)
- ✅ UI: Drag & drop des notebooks
- ✅ Migration: Notebook "Import" par défaut
- ❌ PAS d'IA encore
Phase 2: IA Features (Weeks 4-5)
Objectif: IA pour organisation intelligente
- ✅ IA1: Suggestion automatique de notebook
- ✅ IA2: Suggestion de labels contextuels
- ✅ IA3: Organisation batch (Notes générales → Notebooks)
- ✅ UI: Modals de suggestions IA
- ✅ Feedback loop (accepter/rejeter suggestions)
Phase 3: Advanced IA (Weeks 6-7)
Objectif: Features IA avancées
- ✅ IA4: Création automatique de labels
- ✅ IA5: Recherche sémantique contextuelle
- ✅ IA6: Synthèse par notebook
- ✅ Analytics: Dashboard d'utilisation des notebooks
Phase 4: Polish & Testing (Week 8)
Objectif: Finalisation et tests
- ✅ Playwright E2E tests
- ✅ Performance optimization
- ✅ Accessibility audit
- ✅ Beta testing avec users
- ✅ Documentation
🚨 Risques & Mitigations
Risque 1: Résistance au changement
Description: Users habitués aux tags globaux pourraient rejeter les notebooks
Mitigation:
- Phase de migration douce (optionnel)
- Mode hybride temporaire (garder vue tags pendant transition)
- Tutoriels interactifs
- Onboarding progressif
Risque 2: Performance IA
Description: Suggestions IA pourraient être lentes ou inexactes
Mitigation:
- Cache des suggestions (24h)
- Seuils de confiance minimums (>60%)
- Feedback loop pour améliorer le modèle
- Fallback rapide si IA timeout
Risque 3: Migration des données
Description: Perte de données ou organisation pendant la migration
Mitigation:
- Backup automatique avant migration
- Migration par défaut (notebook "Import")
- Possibilité de revenir en arrière (rollback)
- Tests exhaustifs de migration
Risque 4: Complexité UX
Description: Trop de clics pour organiser les notes
Mitigation:
- Drag & drop intuitif
- Raccourcis clavier
- IA pour automatiser l'organisation
- Mesures d'usabilité (clics, temps)
Risque 5: Labels contextuels = perte de flexibilité
Description: Users ne peuvent plus utiliser un label global (#urgent partout)
Mitigation:
- Éduquer: "Urgent" peut être recréé dans chaque notebook
- IA suggère de recréer les labels importants
- Option: Labels "favoris" synchronisés (feature future)
📚 Glossaire
- Notebook: Collection de notes sur un thème (ex: Voyage, Travail)
- Labels Contextuels: Tags spécifiques à un notebook (ex: #hôtels dans Voyage)
- Inbox / Notes générales: Zone temporaire pour les notes non organisées
- IA: Intelligence Artificielle (OpenAI ou Ollama)
- Suggestion IA: Proposition automatique basée sur l'analyse du contenu
- Drag & Drop: Action de glisser-déposer pour déplacer des éléments
- Migration: Transition du système de tags vers les notebooks
- Notebook par défaut: Notebook créé automatiquement pour préserver les tags existants
📝 Notes pour l'Architecture Team
Points Critiques à Implémenter
-
Database:
Note.notebookIdest OPTIONNEL (null = Notes générales)Label.notebookIdest OBLIGATOIRE- Contrainte d'unicité:
@@unique([notebookId, name])
-
API:
- Nouveau endpoint:
/api/notebooks(CRUD complet) - Endpoint modifié:
/api/labels(filtre par notebook) - Endpoint modifié:
/api/notes(filtre par notebook)
- Nouveau endpoint:
-
UI Components:
SidebarNotebooks: Liste des notebooks avec drag & dropNotebookSelector: Dropdown pour choisir le notebookContextualLabels: Labels filtrés par notebook actifAISuggestions: Modals pour les suggestions IA
-
IA Services:
NotebookSuggestionService: IA pour suggérer un notebookLabelSuggestionService: IA pour suggérer des labelsBatchOrganizationService: IA pour organiser en lotAutoLabelCreationService: IA pour créer des labels
-
Performance:
- Index sur
Note.userId + Note.notebookId - Cache des suggestions IA (Redis ou in-memory)
- Virtual scrolling pour les notebooks avec 100+ notes
- Index sur
✅ Checklist de Validation
Avant de passer en développement, confirmer:
- Ramez valide l'UX décrite dans ce document
- L'Architecture Team a revu le schéma DB
- L'équipe IA a validé les prompts proposés
- Les risques sont acceptables et des mitigations sont en place
- Le plan de migration est testé sur un dataset de test
- Les mesures de succès (KPIs) sont définies et traçables
- Le wireframe UI est validé par Ramez
- L'implémentation est planifiée sur 8 semaines max
Status: ✅ PRD COMPLET - Prêt pour Architecture et Wireframes
Next Steps:
- Créer les wireframes UX (Option XW)
- Définir l'architecture technique
- Commencer Phase 1 (MVP)
Document créé par Sally (UX Designer) avec Ramez (Product Owner) Date: 2026-01-11 Version: 1.0 - Final