# Brainstorm Canvas — Feature Spec for OpenCode ## PROJECT CONTEXT - **Stack**: Next.js 15 + Prisma + PostgreSQL (pgvector) - **Location**: ~/dev/Momento/memento-note/ - **Existing models**: User, Note, Notebook, Canvas (Excalidraw), Agent, Conversation, Workflow, etc. - **Existing API routes**: /app/api/notes, /notebooks, /ai, /canvas, /chat, /agents, etc. - **UI lib**: Radix UI + Tailwind CSS + shadcn components - **State**: @tanstack/react-query - **Auth**: NextAuth (auth.ts, auth.config.ts) ## ⚠️ CRITICAL RULES 1. **DO NOT modify existing models or API routes** — only ADD new ones 2. **DO NOT touch prisma/schema.prisma without creating a migration** — use `npx prisma migrate dev --name add_brainstorm` 3. **Study the existing code patterns** before writing new code — match the project conventions 4. **Look at how existing API routes are structured** (e.g., /app/api/notes/route.ts) and follow the same pattern 5. **Look at how existing components use React Query** and follow the same pattern 6. **Use existing UI components** from /components/ui/ (shadcn) — don't install new UI libs 7. **The project uses TypeScript** — maintain strict typing 8. **Do NOT run npm build** — only dev server if needed for testing ## FEATURE: Brainstorm Canvas (Wave Brainstorming) ### Concept A temporary workspace for brainstorming ideas using AI-generated "waves" of ideas, displayed as a radial graph. The output feeds back into the notes system. ### Data Model — ADD these 2 models to prisma/schema.prisma: ```prisma model BrainstormSession { id String @id @default(cuid()) seedIdea String sourceNoteId String? contextNoteIds String? // JSON array of note IDs exportedNoteId String? userId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt ideas BrainstormIdea[] sourceNote Note? @relation(fields: [sourceNoteId], references: [id]) exportedNote Note? @relation(fields: [exportedNoteId], references: [id]) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([userId, createdAt]) } model BrainstormIdea { id String @id @default(cuid()) sessionId String waveNumber Int // 1, 2, or 3 title String description String connectionToSeed String? noveltyScore Int? parentIdeaId String? // for "dig deeper" sub-brainstorms convertedToNoteId String? relatedNoteIds String? // JSON array status String @default("active") // active, dismissed, converted positionX Float? positionY Float? createdAt DateTime @default(now()) session BrainstormSession @relation(fields: [sessionId], references: [id], onDelete: Cascade) parentIdea BrainstormIdea? @relation("IdeaTree", fields: [parentIdeaId], references: [id]) children BrainstormIdea[] @relation("IdeaTree") convertedNote Note? @relation(fields: [convertedToNoteId], references: [id]) @@index([sessionId]) @@index([waveNumber]) @@index([status]) @@index([parentIdeaId]) } ``` Also add relations to User model: ``` brainstormSessions BrainstormSession[] ``` And to Note model — add these two relations: ``` sourceBrainstormSessions BrainstormSession[] @relation via sourceNoteId exportedBrainstormSessions BrainstormSession[] @relation via exportedNoteId convertedBrainstormIdeas BrainstormIdea[] @relation via convertedToNoteId ``` ### API Routes — Create /app/api/brainstorm/ 1. **POST /api/brainstorm/wave** — Create new brainstorm session - Input: { seedIdea, sourceNoteId?, contextNoteIds? } - Uses existing AI setup (check how /api/ai/ routes call LLM) - Generates 3 waves of ~3 ideas each (9 total) - For each idea, does an embedding search to find related notes (check how semantic search works in existing code) - Saves session + ideas to DB - Returns: { sessionId, ideas: [...] } 2. **POST /api/brainstorm/[sessionId]/expand** — Dig deeper on an idea - Input: { ideaId } - Uses the clicked idea as new seed - Generates 3 more waves, linked as children - Returns new ideas with parentIdeaId set 3. **POST /api/brainstorm/[sessionId]/dismiss** — Mark idea as not relevant - Input: { ideaId } - Sets status = "dismissed" 4. **POST /api/brainstorm/[sessionId]/convert** — Convert idea to a real Note - Input: { ideaId } - Creates a Note with pre-filled content - Auto-tags: "brainstorm", "idée" - Links to source note if exists - Sets idea.status = "converted", idea.convertedToNoteId = newNote.id - Returns the created note 5. **POST /api/brainstorm/[sessionId]/export** — Export session as summary note - Generates a Markdown summary note - Groups by waves, shows which ideas were converted - Links to all converted notes - Returns the created note 6. **GET /api/brainstorm** — List user's brainstorm sessions - Returns sessions ordered by date, with idea counts 7. **GET /api/brainstorm/[sessionId]** — Get full session with ideas - Returns session + all ideas + their status ### Frontend — Canvas Component Use **react-force-graph-2d** (install it: `npm install react-force-graph-2d`). It's a React wrapper around d3-force — declarative API, same physics engine. **Layout:** - Center node = seed idea (large, white) - Ring 1 (radius ~150px) = Wave 1 ideas (orange) - Ring 2 (radius ~300px) = Wave 2 ideas (blue) - Ring 3 (radius ~450px) = Wave 3 ideas (purple) - Use d3.forceRadial for ring constraint - Dismissed nodes = opacity 0.3, smaller - Converted nodes = green border + icon - Click node = side panel with details + 3 action buttons **Side Panel (when clicking a node):** - Show: title, description, connection to seed, related notes - 3 buttons: Dig Deeper, Create Note, Dismiss - Uses existing shadcn Sheet or Dialog component **Sidebar Integration:** - Add "Brainstorms" section in the existing sidebar - List sessions with preview (seed idea + count) - Click to reopen saved canvas state **Entry Points:** 1. From a note: Brainstorm button in note toolbar/editor 2. From sidebar: "+ New Brainstorm" button ### AI Prompt for Wave Generation The LLM prompt should generate 3 waves: - **Wave 1 — Variations**: Direct variations/expansions of the seed (sous-aspects, reformulations, variations) - **Wave 2 — Analogies**: Cross-domain analogies (autres domaines, biologie, technologie, etc.) - **Wave 3 — Disruptions**: Inversions, provocations, ideas that challenge assumptions Each idea should have: - title (short) - description (1-2 sentences) - connectionToSeed (how it relates to the seed) - noveltyScore (1-10) ### Implementation Order 1. Prisma schema + migration 2. API routes (start with /wave and /convert) 3. Brainstorm canvas component (react-force-graph-2d) 4. Sidebar integration 5. Note toolbar button 6. Export functionality