## 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>
1380 lines
38 KiB
Markdown
1380 lines
38 KiB
Markdown
# 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)*
|