Keep/_bmad-output/planning-artifacts/notebooks-epics-stories.md
sepehr 7fb486c9a4 feat: Complete internationalization and code cleanup
## 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>
2026-01-11 22:26:13 +01:00

1380 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)*