# Epics & User Stories - Notebooks & Labels Contextuels

**Project:** Keep - Notebooks & Labels Contextuels
**Date:** 2026-01-11
**Status:** READY FOR DEVELOPMENT
**Based on:** PRD, Architecture (validated), Tech Specs (complete)

---

## Table of Contents

1. [Epic 1: Database Migration & Schema](#epic-1-database-migration--schema)
2. [Epic 2: State Management & Server Actions](#epic-2-state-management--server-actions)
3. [Epic 3: Notebooks Sidebar UI](#epic-3-notebooks-sidebar-ui)
4. [Epic 4: Advanced Drag & Drop](#epic-4-advanced-drag--drop)
5. [Epic 5: Contextual AI Features](#epic-5-contextual-ai-features)
6. [Epic 6: Undo/Redo System](#epic-6-undoredo-system)

---

## Epic 1: Database Migration & Schema

**ID:** EPIC-1
**Priority:** CRITICAL (Blocker)
**Phase:** Foundation (Week 1)
**Story Points:** 13
**Dependencies:** None

### Description
Migrate the existing flat tags system to a contextual notebooks model without breaking changes. This epic creates the foundation for the entire feature.

### User Stories

#### Story 1.1: Create Prisma Schema Migration
**ID:** US-1.1
**Points:** 3
**Priority:** Critical

**As a** Developer
**I want** to extend the Prisma schema with Notebook and Label models
**So that** the database supports the new notebooks feature

**Acceptance Criteria:**
- [ ] `Notebook` model created with fields: id, name, icon, color, order, userId
- [ ] `Label` model updated with required `notebookId` field
- [ ] `Note` model updated with optional `notebookId` field (null = Inbox)
- [ ] Many-to-many relation between Note and Label via junction table
- [ ] Cascade delete configured: Notebook → Labels (deleted), Notes (become general)
- [ ] Unique constraint on `Label.notebookId + name`
- [ ] Indexes created for performance: `Note(userId, notebookId)`, `Notebook(userId, order)`
- [ ] Migration script runs successfully: `npx prisma migrate dev`
- [ ] Zero data loss (all existing notes preserved)

**Technical Notes:**
- See tech specs section 5.1 for complete schema
- Use `onDelete: SetNull` for Note.notebookId to preserve data
- Use `onDelete: Cascade` for Label.notebookId to clean up orphaned labels

**Definition of Done:**
- Migration tested locally
- Migration file committed to Git
- No breaking changes to existing queries

---

#### Story 1.2: Create Data Migration Script
**ID:** US-1.2
**Points:** 5
**Priority:** Critical

**As a** Developer
**I want** to migrate existing labels to a default "Labels Migrés" notebook
**So that** users don't lose any existing data

**Acceptance Criteria:**
- [ ] Migration script created: `scripts/migrate-to-notebooks.ts`
- [ ] Creates "Labels Migrés" notebook for each user
- [ ] Assigns all existing labels to this notebook
- [ ] Leaves all notes without notebook (they go to Inbox)
- [ ] Script logs progress and statistics
- [ ] Script can be run multiple times safely (idempotent)
- [ ] Rollback script created: `scripts/rollback-notebooks.ts`
- [ ] Tested with sample data (100+ notes, 20+ labels)
- [ ] Execution time < 5s for 1000 notes

**Technical Notes:**
- See tech specs section 5.2, 5.3
- Use transactions to prevent partial migration
- Add console.log for progress monitoring

**Definition of Done:**
- Migration runs successfully in development
- Rollback tested and working
- Documentation written for running migration

---

#### Story 1.3: Create Migration Tests
**ID:** US-1.3
**Points:** 2
**Priority:** High

**As a** Developer
**I want** to test the migration script thoroughly
**So that** I'm confident no data is lost in production

**Acceptance Criteria:**
- [ ] Test suite created: `__tests__/migration.test.ts`
- [ ] Test: Migration notebook created for each user
- [ ] Test: All labels migrated to migration notebook
- [ ] Test: No notes moved to notebooks (stay in Inbox)
- [ ] Test: Rollback restores original state
- [ ] Test: Migration is idempotent (can run twice)
- [ ] Test: Handles edge case (user with no labels)
- [ ] All tests passing

**Definition of Done:**
- Test coverage > 90% for migration code
- All tests passing consistently
- Tests run in CI/CD pipeline

---

#### Story 1.4: Document Migration Process
**ID:** US-1.4
**Points:** 1
**Priority:** Medium

**As a** Developer/Ops
**I want** clear documentation for running the migration
**So that** anyone can safely deploy the migration

**Acceptance Criteria:**
- [ ] Migration checklist created (pre-migration steps)
- [ ] Migration checklist created (post-migration verification)
- [ ] Rollback procedure documented
- [ ] Estimated downtime documented (should be < 1min)
- [ ] Backup requirements documented
- [ ] Troubleshooting guide for common issues

**Definition of Done:**
- Documentation reviewed by another developer
- Documentation tested in staging environment

---

### Epic 1 Summary

**Total Stories:** 4
**Total Points:** 13
**Estimated Time:** 1-2 days

**Risks:**
- Data loss if migration fails (mitigated by rollback)
- Performance issues with large datasets (mitigated by batch processing)

**Success Metrics:**
- Zero data loss
- Migration time < 5s for 1000 notes
- All existing functionality still works

---

## Epic 2: State Management & Server Actions

**ID:** EPIC-2
**Priority:** CRITICAL (Blocker)
**Phase:** Foundation (Week 1-2)
**Story Points:** 21
**Dependencies:** EPIC-1 (Database schema must exist)

### Description
Implement the global state management layer using React Context and create all server actions for notebooks, labels, and note operations.

### User Stories

#### Story 2.1: Create NotebooksContext
**ID:** US-2.1
**Points:** 5
**Priority:** Critical

**As a** Developer
**I want** a global context for managing notebooks state
**So that** all components can access and update notebooks data

**Acceptance Criteria:**
- [ ] `NotebooksContext` created with TypeScript interface
- [ ] `NotebooksProvider` wraps the application
- [ ] Context provides: notebooks, currentNotebook, currentLabels, error, isLoading
- [ ] Context provides actions: createNotebook, updateNotebook, deleteNotebook
- [ ] Context provides actions: setCurrentNotebook, updateNotebookOrder
- [ ] Uses `useOptimistic` for instant UI feedback on create/delete
- [ ] Loads initial notebooks data on mount
- [ ] Handles errors gracefully with error state
- [ ] Context TypeScript types exported for reuse

**Technical Notes:**
- See tech specs section 1.2 for complete implementation
- File location: `app/context/notebooks-context.tsx`
- Use `useMemo` and `useCallback` for performance

**Definition of Done:**
- TypeScript compilation with no errors
- Context works with test data
- Provider integrated in `app/providers.tsx`

---

#### Story 2.2: Create Notebook Server Actions
**ID:** US-2.2
**Points:** 5
**Priority:** Critical

**As a** Developer
**I want** server actions for notebook CRUD operations
**So that** the UI can create, update, delete notebooks

**Acceptance Criteria:**
- [ ] `createNotebook(data)` action created
  - [ ] Validates user is authenticated
  - [ ] Calculates next order value automatically
  - [ ] Returns created notebook
  - [ ] Calls `revalidatePath('/')`
- [ ] `updateNotebook(id, data)` action created
  - [ ] Validates ownership before updating
  - [ ] Updates name, icon, or color
  - [ ] Returns updated notebook
- [ ] `deleteNotebook(id)` action created
  - [ ] Validates ownership before deleting
  - [ ] Registers undo action before deleting
  - [ ] Deletes notebook (notes become general)
  - [ ] Calls `revalidatePath('/')`
- [ ] `updateNotebookOrder(ids)` action created
  - [ ] Updates order for all notebooks in transaction
  - [ ] Optimized for performance (bulk update)
- [ ] All actions have error handling with try/catch
- [ ] All actions validate input with Zod schemas

**Technical Notes:**
- See tech specs section 6.1
- File location: `app/actions/notebooks.ts`
- Use Prisma transactions for order update

**Definition of Done:**
- All actions tested manually with Postman/curl
- Error cases tested (unauthorized, not found)
- TypeScript types exported for client usage

---

#### Story 2.3: Create Label Server Actions
**ID:** US-2.3
**Points:** 3
**Priority:** High

**As a** Developer
**I want** server actions for label CRUD operations
**So that** the UI can manage labels within notebooks

**Acceptance Criteria:**
- [ ] `createLabel(data)` action created
  - [ ] Validates notebook ownership
  - [ ] Enforces unique constraint (name + notebookId)
  - [ ] Returns created label
- [ ] `updateLabel(id, data)` action created
  - [ ] Validates ownership via notebook
  - [ ] Returns updated label
- [ ] `deleteLabel(id)` action created
  - [ ] Validates ownership before deleting
  - [ ] Cascade delete removes label from all notes
  - [ ] Returns success
- [ ] All actions validate with Zod schemas
- [ ] All actions call `revalidatePath('/')`

**Technical Notes:**
- Labels belong to notebooks (contextual)
- Must verify notebook ownership before operations

**Definition of Done:**
- All actions tested
- Unique constraint enforced (duplicate names rejected)

---

#### Story 2.4: Create Note-Notebook Server Actions
**ID:** US-2.4
**Points:** 3
**Priority:** High

**As a** Developer
**I want** server actions to move notes between notebooks
**So that** users can organize their notes

**Acceptance Criteria:**
- [ ] `moveNoteToNotebook(noteId, notebookId)` action created
  - [ ] Validates note ownership
  - [ ] Accepts `null` for notebookId (move to Inbox)
  - [ ] Registers undo action before moving
  - [ ] Returns updated note
- [ ] `attachLabel(noteId, labelId)` action created
  - [ ] Validates note and label exist
  - [ ] Creates many-to-many relation
  - [ ] Prevents duplicate attachments
- [ ] `detachLabel(noteId, labelId)` action created
  - [ ] Validates relation exists
  - [ ] Removes relation
- [ ] All actions call `revalidatePath('/')`

**Technical Notes:**
- Use Prisma's `connect`/`disconnect` for many-to-many
- See tech specs section 6.1

**Definition of Done:**
- Tested moving notes between notebooks
- Tested attaching/detaching labels
- Undo/redo registered correctly

---

#### Story 2.5: Create AI Server Actions (Stub)
**ID:** US-2.5
**Points:** 2
**Priority:** Medium

**As a** Developer
**I want** placeholder server actions for AI features
**So that** the UI can integrate AI later (Epic 5)

**Acceptance Criteria:**
- [ ] `suggestNotebook(noteContent)` action created (returns null for now)
- [ ] `suggestLabels(noteContent, notebookId)` action created (returns [] for now)
- [ ] `organizeInbox(noteIds)` action created (returns empty map for now)
- [ ] Actions accept correct parameters
- [ ] Actions have correct return types
- [ ] Actions marked with TODO comments for Epic 5

**Definition of Done:**
- Actions callable from UI
- TypeScript types correct
- No runtime errors

---

#### Story 2.6: Write Tests for Context & Actions
**ID:** US-2.6
**Points:** 3
**Priority:** High

**As a** Developer
**I want** tests for state management and server actions
**So that** I'm confident the core logic works

**Acceptance Criteria:**
- [ ] Context tests created: `__tests__/notebooks-context.test.tsx`
  - [ ] Test: Loads notebooks on mount
  - [ ] Test: Creates notebook optimistically
  - [ ] Test: Updates current notebook
  - [ ] Test: Derives current labels correctly
- [ ] Action tests created: `__tests__/notebooks-actions.test.ts`
  - [ ] Test: Creates notebook successfully
  - [ ] Test: Rejects unauthorized access
  - [ ] Test: Validates input with Zod
  - [ ] Test: Handles errors gracefully
- [ ] Test coverage > 80%
- [ ] All tests passing

**Definition of Done:**
- Tests run in CI/CD
- Tests run locally with `npm test`
- No flaky tests

---

### Epic 2 Summary

**Total Stories:** 6
**Total Points:** 21
**Estimated Time:** 2-3 days

**Risks:**
- Context performance issues with many notebooks (mitigated by useMemo)
- Server action rate limiting (not an issue for single-user)

**Success Metrics:**
- All CRUD operations working
- Optimistic UI feels instant
- No TypeScript errors

---

## Epic 3: Notebooks Sidebar UI

**ID:** EPIC-3
**Priority:** HIGH
**Phase:** Core UI (Week 2-3)
**Story Points:** 21
**Dependencies:** EPIC-1, EPIC-2

### Description
Create the sidebar UI for displaying and managing notebooks. This includes the notebook list, labels display, and basic navigation.

### User Stories

#### Story 3.1: Create NotebooksSidebar Component
**ID:** US-3.1
**Points:** 5
**Priority:** High

**As a** User
**I want** to see all my notebooks in a sidebar
**So that** I can navigate between them

**Acceptance Criteria:**
- [ ] Sidebar component created: `components/notebooks-sidebar.tsx`
- [ ] Displays "Notes générales" (Inbox) at the top
- [ ] Displays all notebooks in list
- [ ] Shows notebook icon and name
- [ ] Shows note count for each notebook
- [ ] Highlights currently selected notebook
- [ ] Clicking notebook switches current notebook
- [ ] Loading state shown while fetching notebooks
- [ ] Error state shown if fetch fails
- [ ] Empty state shown if no notebooks exist
- [ ] Responsive sidebar width (desktop: 256px, mobile: collapsible)

**Technical Notes:**
- See tech specs section 2.2
- Uses `useNotebooks()` hook
- CSS modules for styling

**Definition of Done:**
- Sidebar displays correctly with test data
- Navigation works (clicking notebook updates grid)
- Styled to match existing Keep design

---

#### Story 3.2: Add Notebook Creation UI
**ID:** US-3.2
**Points:** 3
**Priority:** High

**As a** User
**I want** to create new notebooks from the sidebar
**So that** I can organize my notes

**Acceptance Criteria:**
- [ ] "+ New" button in sidebar header
- [ ] Clicking opens modal/dialog
- [ ] Modal contains: Name input, Icon picker, Color picker
- [ ] Icon picker shows common emojis (📚, 📝, 💼, 🏠, etc.)
- [ ] Color picker shows preset colors
- [ ] Name required, icon/color optional
- [ ] "Create" button creates notebook
- [ ] "Cancel" button closes modal
- [ ] Modal closes on successful creation
- [ ] New notebook appears in sidebar immediately (optimistic)
- [ ] Form validation (max 50 chars for name)

**Technical Notes:**
- Modal component: `components/create-notebook-modal.tsx`
- Uses `createNotebookOptimistic` action
- Zod validation on client and server

**Definition of Done:**
- Can create notebook
- Notebook appears instantly in sidebar
- Modal accessible (keyboard navigation)

---

#### Story 3.3: Add Notebook Management Actions
**ID:** US-3.3
**Points:** 3
**Priority:** Medium

**As a** User
**I want** to edit and delete notebooks
**So that** I can manage my organization

**Acceptance Criteria:**
- [ ] Hovering notebook shows "⋯" menu button
- [ ] Clicking menu shows: Edit, Delete options
- [ ] "Edit" opens modal with current values
- [ ] "Edit" modal allows changing name, icon, color
- [ ] "Delete" shows confirmation dialog
- [ ] Delete dialog explains: "Notes will become general"
- [ ] Confirming deletes notebook
- [ ] Notes from deleted notebook become general (Inbox)
- [ ] Can cancel both edit and delete operations

**Technical Notes:**
- Context menu or dropdown menu component
- Uses `updateNotebook` and `deleteNotebook` actions
- Undo toast appears after delete (Epic 6)

**Definition of Done:**
- Can rename notebook
- Can delete notebook (with confirmation)
- Notes preserved after deletion

---

#### Story 3.4: Display Labels in Sidebar
**ID:** US-3.4
**Points:** 3
**Priority:** Medium

**As a** User
**I want** to see labels for the current notebook
**So that** I know what labels are available

**Acceptance Criteria:**
- [ ] Labels shown under selected notebook in sidebar
- [ ] Labels appear when notebook is selected
- [ ] Labels appear when hovering notebook
- [ ] Each label shown as chip with name and color
- [ ] Label count shown (if > 0 notes have label)
- [ ] Labels hidden when switching to another notebook
- [ ] Animation when showing/hiding labels (slide down)
- [ ] Max 10 labels shown (scrollable if more)
- [ ] Empty state: "No labels yet" message

**Technical Notes:**
- Labels derived from `currentLabels` in context
- Sub-component: `components/label-chip.tsx`
- CSS animation for show/hide

**Definition of Done:**
- Labels display correctly
- Animation smooth
- Performance OK with 50+ labels

---

#### Story 3.5: Add Label Creation UI
**ID:** US-3.5
**Points:** 3
**Priority:** Medium

**As a** User
**I want** to create labels for my notebook
**So that** I can categorize notes within the notebook

**Acceptance Criteria:**
- [ ] "+ Label" button shown when notebook selected
- [ ] Clicking opens compact inline form or modal
- [ ] Form contains: Name input, Color picker
- [ ] Name required (max 30 chars)
- [ ] Color optional (random if not selected)
- [ ] "Create" button creates label
- [ ] New label appears immediately in sidebar
- [ ] Duplicate names rejected (within notebook)
- [ ] Form clears after creation

**Technical Notes:**
- Uses `createLabel` action
- Validation: unique constraint on notebookId + name

**Definition of Done:**
- Can create label
- Label appears instantly
- Duplicates prevented

---

#### Story 3.6: Add Label Management Actions
**ID:** US-3.6
**Points:** 2
**Priority:** Low

**As a** User
**I want** to edit and delete labels
**So that** I can fix mistakes or remove unused labels

**Acceptance Criteria:**
- [ ] Right-click label shows context menu
- [ ] Menu options: Edit name, Change color, Delete
- [ ] "Edit" opens inline edit or modal
- [ ] "Delete" shows confirmation (if label used on notes)
- [ ] Delete confirmation shows note count
- [ ] Confirming removes label from all notes
- [ ] Can cancel operations

**Technical Notes:**
- Context menu component
- Uses `updateLabel` and `deleteLabel` actions
- Cascade delete handled by Prisma

**Definition of Done:**
- Can rename label
- Can delete label (with confirmation)
- Notes no longer have deleted label

---

#### Story 3.7: Implement Note Filtering by Notebook
**ID:** US-3.7
**Points:** 5
**Priority:** Critical

**As a** User
**I want** to see only notes from the selected notebook
**So that** I can focus on one topic at a time

**Acceptance Criteria:**
- [ ] Selecting notebook filters notes in main grid
- [ ] Selecting "Notes générales" shows notes without notebook
- [ ] Note count updates correctly in sidebar
- [ ] Grid updates instantly when switching notebooks
- [ ] URL updates with notebook ID (optional, for sharing)
- [ ] Page title updates with notebook name
- [ ] Breadcrumb shows: Home > Notebook Name
- [ ] Can navigate back to "All notes" view
- [ ] Pagination works correctly (if implemented)
- [ ] Search works within filtered notes

**Technical Notes:**
- Modify `app/page.tsx` to filter notes by `currentNotebook`
- Pass `notebookId` to note query
- Update document title

**Definition of Done:**
- Switching notebooks works smoothly
- Note counts accurate
- Search respects notebook filter

---

#### Story 3.8: Style Sidebar to Match Keep Design
**ID:** US-3.8
**Points:** 2
**Priority:** Medium

**As a** User
**I want** the sidebar to look consistent with Keep's design
**So that** the UI feels polished

**Acceptance Criteria:**
- [ ] Sidebar uses Keep color scheme (grays, blues)
- [ ] Fonts match existing UI
- [ ] Spacing consistent (8px grid)
- [ ] Hover states smooth (150ms transition)
- [ ] Active state clearly visible
- [ ] Icons align correctly
- [ ] Scrollbar styled (custom webkit scrollbar)
- [ ] Dark mode supported (if Keep has dark mode)
- [ ] Mobile responsive (sidebar collapses)
- [ ] Accessibility: ARIA labels, keyboard nav

**Definition of Done:**
- Design approved by UX review
- Matches Keep design system
- Accessibility audit passed

---

### Epic 3 Summary

**Total Stories:** 8
**Total Points:** 21
**Estimated Time:** 3-4 days

**Risks:**
- Sidebar performance with many notebooks (mitigated by virtual scrolling if needed)
- Mobile UX challenges (sidebar takes too much space)

**Success Metrics:**
- Sidebar navigation feels smooth
- Users can create and manage notebooks
- Design consistent with Keep

---

## Epic 4: Advanced Drag & Drop

**ID:** EPIC-4
**Priority:** HIGH
**Phase:** Drag & Drop (Week 3-4)
**Story Points:** 13
**Dependencies:** EPIC-1, EPIC-2, EPIC-3

### Description
Implement Muuri-based drag & drop for reordering notebooks and moving notes between notebooks. This provides the core interaction model for organizing content.

### User Stories

#### Story 4.1: Implement Notebook Reordering
**ID:** US-4.1
**Points:** 5
**Priority:** High

**As a** User
**I want** to drag notebooks to reorder them
**So that** I can organize my sidebar the way I want

**Acceptance Criteria:**
- [ ] Notebooks can be dragged in sidebar
- [ ] Drag handle appears on hover (visual indicator)
- [ ] Other notebooks shift smoothly while dragging
- [ ] Placeholder shows where notebook will drop
- [ ] Drop updates order immediately (optimistic)
- [ ] Order saved to database via `updateNotebookOrder`
- [ ] Works on touch devices (mobile)
- [ ] Dragging disabled while "Notes générales" (always first)
- [ ] Drag feels smooth (60fps)
- [ ] Can't drag into invalid positions

**Technical Notes:**
- See tech specs section 2.2
- Uses Muuri library (same as masonry-grid)
- Configuration synced with masonry-grid for consistency
- Touch support via `dragHandle` option

**Definition of Done:**
- Can reorder notebooks smoothly
- Order persists after page refresh
- Works on mobile

---

#### Story 4.2: Add Visual Drag Feedback
**ID:** US-4.2
**Points:** 2
**Priority:** Medium

**As a** User
**I want** visual feedback while dragging
**So that** I know what's happening

**Acceptance Criteria:**
- [ ] Dragged item shows shadow
- [ ] Dragged item slightly transparent (0.5 opacity)
- [ ] Other items shift smoothly with animation
- [ ] Placeholder shows drop target clearly
- [ ] Cursor changes to "grabbing"
- [ ] Drop target highlighted on hover
- [ ] Animation duration: 150-200ms
- [ ] No jank or stuttering

**Technical Notes:**
- Muuri's `dragPlaceholder` config
- CSS transitions for smooth animations

**Definition of Done:**
- Drag feels polished
- Animations smooth at 60fps

---

#### Story 4.3: Implement Drag Notes to Sidebar
**ID:** US-4.3
**Points:** 5
**Priority:** High

**As a** User
**I want** to drag notes from the grid to notebooks in sidebar
**So that** I can quickly organize notes

**Acceptance Criteria:**
- [ ] Can drag note from masonry grid
- [ ] Can drop note onto notebook in sidebar
- [ ] Notebook highlights when note dragged over it
- [ ] "Notes générales" accepts dropped notes
- [ ] Drop moves note to target notebook
- [ ] Note disappears from current view (if filtered)
- [ ] Success animation/toast confirms move
- [ ] Works with multiple selected notes (if selection implemented)
- [ ] Drag cancelled if dropped outside valid target
- [ ] Undo button appears after move (Epic 6)

**Technical Notes:**
- Cross-container drag & drop
- Detect drop target via `elementFromPoint`
- Calls `moveNoteToNotebook` action
- See tech specs section 2.2

**Definition of Done:**
- Can drag notes to notebooks
- Notes move correctly
- Visual feedback clear

---

#### Story 4.4: Add Context Menu Move Alternative
**ID:** US-4.4
**Points:** 3
**Priority:** Medium

**As a** User
**I want** to move notes via right-click menu
**So that** I have an alternative to drag & drop

**Acceptance Criteria:**
- [ ] Right-clicking note shows context menu
- [ ] Menu has "Move to" submenu
- [ ] Submenu lists all notebooks
- [ ] Submenu has "Notes générales" option
- [ ] Clicking notebook moves note there
- [ ] Menu closes after selection
- [ ] Note disappears from current view
- [ ] Works with keyboard (accessibility)
- [ ] Menu positioned correctly (no overflow)

**Technical Notes:**
- Context menu component or native browser menu
- Fallback for users who can't use drag & drop

**Definition of Done:**
- Context menu works
- Keyboard accessible
- Alternative to drag & drop

---

#### Story 4.5: Add Drag Performance Optimizations
**ID:** US-4.5
**Points:** 2
**Priority**: Low

**As a** Developer
**I want** drag & drop to perform well
**So that** the UI feels smooth even with many items

**Acceptance Criteria:**
- [ ] Drag operations run at 60fps
- [ ] No layout thrashing during drag
- [ ] Uses `requestAnimationFrame` for updates
- [ ] Debounces rapid drag events
- [ ] Lazy loads heavy components during drag
- [ ] Profiled with 100+ notebooks/notes
- [ ] No memory leaks after drag operations

**Technical Notes:**
- Use React.memo for notebook items
- Avoid expensive computations during drag
- Clean up event listeners

**Definition of Done:**
- Performance test passed (100 items)
- No jank in profiler
- Memory stable after extended use

---

### Epic 4 Summary

**Total Stories:** 5
**Total Points:** 13
**Estimated Time:** 2-3 days

**Risks:**
- Cross-container drag & drop complexity (mitigated by existing Muuri knowledge)
- Touch device support (mitigated by Muuri's built-in touch support)

**Success Metrics:**
- Drag & drop feels intuitive
- Users can organize notes easily
- Performance smooth (60fps)

---

## Epic 5: Contextual AI Features

**ID:** EPIC-5
**Priority:** MEDIUM
**Phase:** AI Integration (Week 4-5)
**Story Points:** 21
**Dependencies:** EPIC-1, EPIC-2, EPIC-3

### Description
Implement the 6 AI features that make notebooks intelligent. All AI features are contextual to the current notebook.

### User Stories

#### Story 5.1: Implement Notebook Suggestion (IA1)
**ID:** US-5.1
**Points:** 3
**Priority:** High

**As a** User
**I want** AI to suggest which notebook a note belongs to
**So that** I can quickly file notes from my Inbox

**Acceptance Criteria:**
- [ ] When note created in Inbox, suggestion appears
- [ ] Suggestion shown as: "Move to [Notebook Name]?"
- [ ] Clicking suggestion moves note immediately
- [ ] Dismissing suggestion hides it
- [ ] Only suggests when confident (>70%)
- [ ] No suggestion if no good match
- [ ] Suggestion disappears after 30 seconds
- [ ] Works for notes with > 20 words of content
- [ ] Can manually trigger via button

**Technical Notes:**
- Implements `NotebookSuggestionService` (tech specs 4.1)
- Uses OpenAI API with optimized prompt
- Server action: `suggestNotebookForNote`
- Confidence threshold configurable

**Definition of Done:**
- Suggestions accurate (>70% user acceptance rate)
- Performance: < 2s for suggestion
- No annoying false positives

---

#### Story 5.2: Implement Label Suggestions (IA2)
**ID:** US-5.2
**Points:** 3
**Priority:** High

**As a** User
**I want** AI to suggest labels from my current notebook
**So that** I can quickly tag my notes

**Acceptance Criteria:**
- [ ] When editing note, label suggestions appear
- [ ] Suggestions filtered to current notebook's labels
- [ ] Shows top 3 suggested labels
- [ ] Clicking suggestion adds label to note
- [ ] Label appears in note's label list
- [ ] Can dismiss suggestions
- [ ] Only suggests if notebook has labels
- [ ] No suggestions if note too short (< 10 words)
- [ ] Suggestions update as note content changes

**Technical Notes:**
- Implements `ContextualAutoTagService` (tech specs 3.1)
- Uses existing auto-tagging infrastructure
- Filters suggestions by `notebookId`
- Server action: `suggestContextualLabels`

**Definition of Done:**
- Suggestions relevant (>60% user acceptance)
- Performance: < 1s for suggestions
- Doesn't annoy users

---

#### Story 5.3: Implement Batch Inbox Organization (IA3)
**ID:** US-5.3
**Points:** 5
**Priority:** Medium

**As a** User
**I want** AI to organize multiple notes from my Inbox
**So that** I can quickly clean up my Inbox

**Acceptance Criteria:**
- [ ] "Organize Inbox" button in Inbox view
- [ ] Button shows count of notes to organize
- [ ] Clicking opens confirmation dialog
- [ ] Dialog shows preview of planned organization
- [ ] Each note shows suggested notebook
- [ ] Can review/edit suggestions before confirming
- [ ] Confirming moves all notes in batch
- [ ] Progress bar shows organization progress
- [ ] Success message shows X notes moved
- [ ] Can undo batch operation (Epic 6)

**Technical Notes:**
- Server action: `organizeInbox`
- Batch AI calls (optimized)
- Updates all notes in transaction
- Uses `NotebookSuggestionService`

**Definition of Done:**
- Can organize 50 notes in < 30s
- Suggestions reasonable (>50% accuracy)
- Clear UI for review/edit

---

#### Story 5.4: Implement Auto Label Creation (IA4)
**ID:** US-5.4
**Points:** 3
**Priority:** Low

**As a** User
**I want** AI to automatically create labels for recurring themes
**So that** I don't have to manually create them

**Acceptance Criteria:**
- [ ] Background job detects recurring themes
- [ ] Creates label if theme appears in 3+ notes
- [ ] New label shown in sidebar
- [ ] Notification: "Created label: [Name]"
- [ ] Can delete auto-created labels
- [ ] Only runs if notebook has < 50 labels
- [ ] Runs once per day (not real-time)
- [ ] Respects unique constraint
- [ ] Uses random color for new label

**Technical Notes:**
- Implements `createLabelIfRecurring` (tech specs 3.1)
- Could be cron job or triggered action
- Threshold configurable (default: 3 occurrences)

**Definition of Done:**
- Creates useful labels (>50% kept by users)
- Doesn't create spam
- Performance: < 10s for 100 notes

---

#### Story 5.5: Implement Contextual Semantic Search (IA5)
**ID:** US-5.5
**Points:** 5
**Priority:** High

**As a** User
**I want** semantic search limited to my current notebook
**So that** I find relevant notes without noise

**Acceptance Criteria:**
- [ ] Search box shows notebook context
- [ ] Placeholder: "Search in [Notebook Name]"
- [ ] Search only returns notes from current notebook
- [ ] Search in "Notes générales" searches only Inbox
- [ ] Results ranked by semantic similarity
- [ ] Shows top 20 results
- [ ] Results highlight matching terms
- [ ] Search < 300ms for 1000 notes
- [ ] Can opt-out to "Search All Notebooks"
- [ ] Search respects label filters (if implemented)

**Technical Notes:**
- Server action: `contextualSemanticSearch`
- Filters Prisma query by `notebookId`
- Uses existing embedding search
- Tech specs section 7 (architecture decision 7)

**Definition of Done:**
- Search results relevant
- Performance acceptable
- Context clear in UI

---

#### Story 5.6: Implement Notebook Summary (IA6)
**ID:** US-5.6
**Points:** 4
**Priority:** Low

**As a** User
**I want** an AI summary of my notebook
**So that** I can quickly understand what's in it

**Acceptance Criteria:**
- [ ] "Summarize" button in notebook menu
- [ ] Clicking generates summary of all notes
- [ ] Summary shows key themes (5-10 bullets)
- [ ] Summary lists top labels by usage
- [ ] Summary shows note count
- [ ] Summary generation takes < 5s
- [ ] Can copy summary to clipboard
- [ ] Summary cached for 1 hour
- [ ] Shows loading state while generating
- [ ] Error message if generation fails

**Technical Notes:**
- New service: `NotebookSummaryService`
- Aggregates all note content
- Uses OpenAI summarization
- Could use map-reduce for large notebooks

**Definition of Done:**
- Summaries useful (>70% satisfaction)
- Performance acceptable
- Works with notebooks up to 500 notes

---

#### Story 5.7: Add AI Settings and Controls
**ID:** US-5.7
**Points:** 2
**Priority:** Medium

**As a** User
**I want** to control AI features
**So that** they don't annoy me

**Acceptance Criteria:**
- [ ] Settings page for AI features
- [ ] Toggle for each IA feature (IA1-IA6)
- [ ] Toggle for all AI features
- [ ] Sensitivity slider (how aggressive suggestions are)
- [ ] "Never suggest for this notebook" option
- [ ] Clear explanation of each feature
- [ ] Privacy note: "AI runs on your content"

**Definition of Done:**
- Users can disable annoying features
- Settings easy to understand
- Privacy addressed

---

#### Story 5.8: Add AI Performance Monitoring
**ID:** US-5.8
**Points:** 2
**Priority:** Low

**As a** Developer
**I want** to monitor AI feature performance
**So that** I can improve them

**Acceptance Criteria:**
- [ ] Track suggestion acceptance rate
- [ ] Track suggestion rejection rate
- [ ] Track AI API costs
- [ ] Track average response time
- [ ] Dashboard shows metrics
- [ ] Alerts for unusual patterns
- [ ] Export logs for analysis

**Definition of Done:**
- Metrics collected
- Dashboard usable
- Costs tracked

---

### Epic 5 Summary

**Total Stories:** 8
**Total Points:** 21
**Estimated Time:** 3-4 days

**Risks:**
- OpenAI API costs (mitigated by caching, limits)
- Poor suggestions annoy users (mitigated by confidence thresholds)
- Performance issues with large notebooks (mitigated by batching)

**Success Metrics:**
- >60% user acceptance of suggestions
- < 2s average response time
- AI features helpful, not annoying

---

## Epic 6: Undo/Redo System

**ID:** EPIC-6
**Priority:** MEDIUM
**Phase:** Polish (Week 5)
**Story Points:** 8
**Dependencies:** EPIC-2, EPIC-3, EPIC-4

### Description
Implement an undo/redo system for destructive actions so users can explore without fear.

### User Stories

#### Story 6.1: Implement Undo History
**ID:** US-6.1
**Points:** 3
**Priority:** High

**As a** Developer
**I want** an undo history system
**So that** users can undo their actions

**Acceptance Criteria:**
- [ ] `UndoHistory` class created (tech specs 8.1)
- [ ] Stores last 20 actions
- [ ] Actions: MOVE_NOTE, DELETE_NOTEBOOK, DELETE_LABEL, REORDER
- [ ] Each action has: type, timestamp, undo function, description
- [ ] `add(action)` adds to history
- [ ] `undo()` executes last action's undo function
- [ ] `getLastAction()` returns most recent action
- [ ] History persists in memory (session only)
- [ ] History cleared on page refresh

**Technical Notes:**
- Tech specs section 8 (architecture decision 8)
- File: `lib/undo-history.ts`
- In-memory storage (not persistent)

**Definition of Done:**
- History class working
- Unit tests passing
- Integrated with server actions

---

#### Story 6.2: Register Undo Actions
**ID:** US-6.2
**Points:** 2
**Priority:** High

**As a** Developer
**I want** destructive actions to register undo
**So that** users can undo them

**Acceptance Criteria:**
- [ ] `moveNoteToNotebook` registers undo
- [ ] `deleteNotebook` registers undo
- [ ] `deleteLabel` registers undo
- [ ] `updateNotebookOrder` registers undo
- [ ] Undo function restores previous state
- [ ] Undo function calls `revalidatePath('/')`
- [ ] Error handling if undo fails
- [ ] Only one undo level deep (no redo for MVP)

**Technical Notes:**
- Modify actions from Epic 2
- Add `undoHistory.add()` calls
- Store previous state for rollback

**Definition of Done:**
- All destructive actions register undo
- Undo works correctly
- Tested manually

---

#### Story 6.3: Create Undo Toast UI
**ID:** US-6.3
**Points:** 2
**Priority:** Medium

**As a** User
**I want** to see an undo notification after actions
**So that** I can undo if I made a mistake

**Acceptance Criteria:**
- [ ] Toast appears after destructive action
- [ ] Toast shows action description
- [ ] Toast has "Undo" button
- [ ] Clicking "Undo" reverts action
- [ ] Toast auto-dismisses after 10 seconds
- [ ] Hovering toast keeps it visible
- [ ] Can manually dismiss toast (× button)
- [ ] Toast positioned bottom-right
- [ ] Animation smooth (slide in/fade out)
- [ ] Only one toast at a time

**Technical Notes:**
- Component: `components/undo-toast.tsx`
- Tech specs section 8.1
- Uses `getLastAction()` from history

**Definition of Done:**
- Toast appears after actions
- Undo button works
- UX polished

---

#### Story 6.4: Add Undo Keyboard Shortcut
**ID:** US-6.4
**Points:** 1
**Priority:** Low

**As a** User
**I want** to undo with keyboard shortcut
**So that** I can quickly fix mistakes

**Acceptance Criteria:**
- [ ] Ctrl+Z (or Cmd+Z on Mac) triggers undo
- [ ] Works globally (not just when toast visible)
- [ ] Shows feedback: "Undo: [action description]"
- [ ] Does nothing if no history
- [ ] Does not interfere with browser undo
- [ ] Documented in help

**Definition of Done:**
- Keyboard shortcut works
- Doesn't conflict with browser
- Feedback clear

---

### Epic 6 Summary

**Total Stories:** 4
**Total Points:** 8
**Estimated Time:** 1-2 days

**Risks:**
- Undo state management complexity (mitigated by simple in-memory history)
- Undo conflicts with concurrent updates (rare in single-user)

**Success Metrics:**
- Users can undo actions
- Undo works correctly
- UX feels safe

---

## Overall Summary

### All Epics

| Epic | Points | Phase | Dependencies |
|------|--------|-------|--------------|
| EPIC-1: Database Migration | 13 | Week 1 | None |
| EPIC-2: State Management | 21 | Week 1-2 | EPIC-1 |
| EPIC-3: Sidebar UI | 21 | Week 2-3 | EPIC-1, EPIC-2 |
| EPIC-4: Drag & Drop | 13 | Week 3-4 | EPIC-1, EPIC-2, EPIC-3 |
| EPIC-5: AI Features | 21 | Week 4-5 | EPIC-1, EPIC-2, EPIC-3 |
| EPIC-6: Undo/Redo | 8 | Week 5 | EPIC-2, EPIC-3, EPIC-4 |

**Total Story Points:** 97
**Estimated Time:** 5-6 weeks
**Total Stories:** 34

### Implementation Priority

**Must Have (MVP):**
- EPIC-1: Database Migration
- EPIC-2: State Management & Actions
- EPIC-3: Sidebar UI (stories 3.1, 3.2, 3.7)
- EPIC-4: Drag & Drop (stories 4.1, 4.3)

**Should Have:**
- EPIC-3: Remaining stories
- EPIC-4: Remaining stories
- EPIC-5: AI features (stories 5.1, 5.2, 5.5)
- EPIC-6: Undo/Redo (stories 6.1, 6.2, 6.3)

**Could Have:**
- EPIC-5: Advanced AI (stories 5.3, 5.4, 5.6)
- EPIC-6: Keyboard undo

**Won't Have (Future):**
- Multi-notebook search
- Notebook sharing
- Note templates

### Risk Register

| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| Data loss during migration | CRITICAL | LOW | Backup, rollback, testing |
| Poor AI suggestions | MEDIUM | MEDIUM | Confidence thresholds, user feedback |
| Performance with 1000+ notes | HIGH | MEDIUM | Indexes, pagination, profiling |
| Drag & drop bugs | MEDIUM | LOW | Extensive testing, fallback menus |
| OpenAI API costs | MEDIUM | LOW | Caching, rate limits |

### Success Criteria

**Technical:**
- [ ] All 34 stories completed
- [ ] Zero data loss
- [ ] < 2s AI response time
- [ ] < 300ms search time
- [ ] 60fps drag & drop
- [ ] 80%+ test coverage

**User:**
- [ ] Users can create notebooks
- [ ] Users can organize notes
- [ ] AI suggestions helpful (>60% acceptance)
- [ ] Undo works reliably
- [ ] Performance acceptable

**Business:**
- [ ] Migration successful
- [ ] No breaking changes
- [ ] User adoption > 70%
- [ ] Support tickets decreased

---

**Document Status:** ✅ COMPLETE
**Ready for Sprint Planning:** YES
**Total Epics:** 6
**Total Stories:** 34
**Total Story Points:** 97

---

*This Epic & User Story document was created based on validated Architecture and complete Tech Specs.*
*Date: 2026-01-11*
*Author: Winston (Architect AI Agent)*
