Problem Statement
Currently, the AI chat application stores conversations only in memory (via InMemoryConversationRepository), which means:
No persistence : All chat history is lost when the user closes the tab or refreshes the page
No conversation management : Users cannot view, switch between, or manage past conversations
Limited user value : Users must re-explain context in every new session
The application has a well-designed hexagonal architecture with domain entities and repository interfaces already in place, but lacks a persistent storage adapter and UI for conversation management.
User Value
For end users:
Never lose conversations : All chat history is automatically saved to MongoDB and persists across sessions
Easy access : View and switch between past conversations via a collapsible sidebar
Better organization : Filter conversations by status (Active/Archived), see timestamps, and manage old conversations
Improved productivity : Resume previous conversations without re-explaining context
Concrete examples:
A user researching a topic can return the next day and continue where they left off
A user can switch between multiple ongoing conversations (e.g., one for coding help, another for weather queries)
A user can archive old conversations to declutter their workspace while keeping history intact
Architecture Overview
This feature requires implementing both backend and frontend components following the existing hexagonal architecture:
Backend (src/infrastructure/adapters/database/):
MongoDBClient.ts - Singleton connection manager with pooling
MongoDBConversationRepository.ts - Repository implementation
ConversationDocumentMapper.ts - Entity-to-document mapper
Updated DependencyContainer.ts - Async initialization + repository selection
Frontend (app/features/conversation/):
New conversation sidebar component (shadcn/ui Sidebar)
Conversation list with 50-100 items, sorted by recent activity
Enhanced useConversation hook with loadConversation() method
React Query integration for list fetching, optimistic updates, cache invalidation
API Endpoints :
GET /api/conversations/list?status=active&limit=100 - List conversations
DELETE /api/conversations/:id - Hard delete conversation
GET /api/health - MongoDB connection health check (Phase 2)
Technical Decisions Already Made
All architectural decisions have been documented by specialized agents:
Backend (.claude/doc/chat_history/backend.md):
Connection pooling: MaxPoolSize=10, 60s idle timeout
Document schema: Embedded messages (not referenced)
Indexes: { _id: 1 }, { updatedAt: -1 }, { status: 1, updatedAt: -1 }
Error handling: Graceful fallback to InMemory on MongoDB failure
Pagination: Skip + limit (100 default)
Frontend (.claude/doc/chat_history/frontend-data-architecture.md):
State management: Keep existing useConversationStorage (sessionStorage)
Caching: React Query with hierarchical query keys
Optimistic updates: Delete mutations with rollback on error
No URL params syncing (initially), no Suspense (traditional loading states)
UI/UX (.claude/doc/chat_history/sidebar-ui-design.md):
Component: shadcn/ui v4 Sidebar (collapsible, responsive, accessible)
Layout: 280px desktop, full overlay mobile, hamburger menu toggle
Actions: New Chat (default button), Delete (ghost + confirmation dialog)
States: Loading (skeleton), empty, error, active highlighting
Definition of Done
Implementation Complete :
MongoDBClient singleton with connection pooling and retry logic
MongoDBConversationRepository implementing IConversationRepository interface
ConversationDocumentMapper with entity restoration via Conversation.restore()
Updated DependencyContainer with async initialization and REPOSITORY_TYPE env variable
GET /api/conversations/list endpoint with status filtering and pagination
DELETE /api/conversations/:id endpoint for hard delete
Conversation sidebar component with shadcn/ui Sidebar, ScrollArea, AlertDialog
Conversation list with title, preview, timestamp, delete button, active state
Enhanced useConversation hook with loadConversation(conversationId) method
React Query hooks: useConversationsListQuery, useDeleteConversationMutation
Responsive behavior: Overlay on mobile (<768px), collapsible on desktop
Empty state, loading state, error state with retry button
Filter by status: All, Active, Archived with localStorage persistence
Edge Cases Handled :
Unit Tests Added (>80% coverage) :
Backend unit tests:
Frontend unit tests:
useConversationsListQuery.test.tsx (fetch, error, caching, stale time)
useDeleteConversationMutation.test.tsx (optimistic updates, rollback)
Sidebar.test.tsx (rendering, collapse, filters, states, accessibility)
ConversationListItem.test.tsx (click, delete, active state, truncation)
Integration Tests :
Documentation Updated :
Code Review Approved :
CI/CD Passes :
Manual Testing Complete :
Manual Testing Checklist
Basic Flow (5 minutes):
Open app in fresh browser tab
Send first message: "What is the weather in San Francisco?"
Verify conversation appears in sidebar with title "What is the weather in San Francisco?"
Send second message: "And what about New York?"
Refresh page → Verify conversation persists and messages reload
Click "New Chat" button → Verify chat clears and input is focused
Send message in new conversation → Verify second conversation appears in sidebar
Click first conversation → Verify messages load correctly
Click delete button on second conversation → Confirm deletion → Verify removed from list
Edge Case Testing (3 minutes):
Send message with 500+ characters → Verify title truncates to 50 chars + "..."
Hover over truncated title → Verify tooltip shows full title
Rapidly click between 3 conversations → Verify last clicked loads without errors
Try to send empty message (whitespace only) → Verify validation error
Error Handling (3 minutes):
Disconnect internet → Try to load sidebar → Verify error state with retry button
Click retry → Verify loading state → Reconnect internet → Verify list loads
Kill MongoDB (set invalid MONGODB_URL) → Refresh app → Verify fallback to InMemory + console warning
Integration (2 minutes):
Open app in two browser tabs with same conversation
Send message in tab 1 → Switch to tab 2 → Refresh → Verify message appears
Delete conversation in tab 1 → Switch to tab 2 → Refresh → Verify conversation gone
Responsive Behavior (2 minutes):
Desktop (1920px): Verify sidebar is 280px wide, collapsible with hamburger icon
Resize to tablet (768px): Verify sidebar pushes content, 320px wide
Resize to mobile (375px): Verify sidebar is full overlay with backdrop
Click conversation on mobile → Verify sidebar auto-closes after selection
Test keyboard shortcut (Cmd/Ctrl+B) → Verify sidebar toggles
Acceptance Criteria Reference
Critical Path (Must Pass) :
AC-8.1.1: Zero message loss - All sent messages persisted successfully
AC-8.2.1, AC-8.2.2: No duplicate conversations (UUID uniqueness)
AC-8.3.1, AC-8.3.2: Correct message ordering (server timestamps)
AC-6.1.1, AC-6.1.2: Load time <2s for list, <1.5s for conversation
AC-4.2.2, AC-4.2.3: Hard delete with confirmation dialog
AC-5.1.1, AC-5.1.3: MongoDB connection resilience (fallback to InMemory)
Important (Should Pass) :
AC-6.2.1: Sidebar 60fps animations (300ms transition)
AC-NFR-1, AC-NFR-2, AC-NFR-3: WCAG 2.1 AA accessibility compliance
AC-5.1.3: Error auto-recovery 90% success rate
AC-7.1.1, AC-7.2.1, AC-7.3.1: Responsive design across 3 breakpoints
Complete acceptance criteria : .claude/doc/chat_history/acceptance-criteria.md (75+ criteria)
Implementation Plan
Phase 1: Backend Infrastructure (Priority: HIGH):
Install mongodb driver: yarn add mongodb
Install test dependencies: yarn add -D mongodb-memory-server
Create MongoDBClient singleton with connection pooling
Create ConversationDocumentMapper with entity restoration
Implement MongoDBConversationRepository
Update DependencyContainer for async initialization
Add GET /api/conversations/list endpoint
Add DELETE /api/conversations/:id endpoint
Write unit tests (mocked MongoDB)
Write integration tests (mongodb-memory-server)
Phase 2: Frontend Data Layer (Priority: HIGH):
Install MSW for testing: yarn add -D msw@latest
Create conversation list schema (Zod)
Enhance ConversationService with listConversations() and error handling
Create useConversationsListQuery hook
Enhance useDeleteConversationMutation with optimistic updates
Enhance useConversation hook with loadConversation() method
Create useSwitchConversation business hook
Write unit tests for hooks and service
Phase 3: UI Components (Priority: HIGH):
Install shadcn sidebar: npx shadcn-ui@latest add sidebar
Create ConversationSidebar component (basic structure)
Create ConversationListItem component (title, preview, timestamp, delete)
Create ConversationList component (ScrollArea + list mapping)
Add empty state, loading state (skeleton), error state
Add filter buttons (All, Active, Archived)
Integrate sidebar in layout.tsx with SidebarProvider
Add SidebarTrigger to Navbar
Write component tests (React Testing Library)
Phase 4: Integration & Polish (Priority: MEDIUM):
Test full user flows (create, load, delete, filter)
Test responsive behavior on 3 viewports
Test error scenarios (MongoDB down, network errors)
Verify accessibility (keyboard navigation, screen reader)
Performance testing (50+ conversations)
Write integration tests
Update documentation (README, .env.example)
Phase 5: Monitoring & Optimization (Priority: LOW - Future):
Add /api/health endpoint for MongoDB connection health
Implement query performance monitoring
Add structured logging (pino/winston)
Cursor-based pagination for >100 conversations
Real-time updates via WebSocket (multi-device sync)
Dependencies
Environment Variables Required :
MONGODB_URL=mongodb+srv://user:pass@cluster.mongodb.net/
DATABASE_NAME=ai_chat_app
REPOSITORY_TYPE=mongodb # or 'inmemory' for testing
New Packages :
mongodb - MongoDB Node.js driver
mongodb-memory-server (dev) - In-memory MongoDB for integration tests
msw (dev) - Mock Service Worker for frontend testing
Existing Dependencies (Already Installed) :
@tanstack/react-query - State management
axios - HTTP client
vitest - Test runner
@testing-library/react - Component testing
shadcn/ui - UI components
Related Documentation
All planning documents are in .claude/doc/chat_history/:
backend.md - MongoDB repository architecture (8,000+ words)
frontend-data-architecture.md - React Query integration (6,000+ words)
sidebar-ui-design.md - UI/UX specifications (5,000+ words)
backend-testing-strategy.md - Testing approach (4,000+ words)
frontend-testing-strategy.md - Frontend testing (4,500+ words)
acceptance-criteria.md - 75+ acceptance criteria (11,500+ words)
validation-checklist.md - Manual testing guide (quick reference)
test-scenario-mapping.md - 135 test scenarios mapped to ACs
Session context: .claude/sessions/context_session_chat_history.md
Notes
Architecture compliance : This feature strictly follows hexagonal architecture principles (zero domain dependencies on infrastructure)
Incremental rollout : Use REPOSITORY_TYPE=inmemory for local development, REPOSITORY_TYPE=mongodb for production
Testing strategy : Dual approach - mocked unit tests + mongodb-memory-server integration tests
MongoDB setup : MongoDB Atlas already configured at mongodb+srv://connection:***@gurusup-prod.kyw62.mongodb.net
No migration needed : Fresh start - no data to migrate from InMemory
Problem Statement
Currently, the AI chat application stores conversations only in memory (via
InMemoryConversationRepository), which means:The application has a well-designed hexagonal architecture with domain entities and repository interfaces already in place, but lacks a persistent storage adapter and UI for conversation management.
User Value
For end users:
Concrete examples:
Architecture Overview
This feature requires implementing both backend and frontend components following the existing hexagonal architecture:
Backend (src/infrastructure/adapters/database/):
MongoDBClient.ts- Singleton connection manager with poolingMongoDBConversationRepository.ts- Repository implementationConversationDocumentMapper.ts- Entity-to-document mapperDependencyContainer.ts- Async initialization + repository selectionFrontend (app/features/conversation/):
Sidebar)useConversationhook withloadConversation()methodAPI Endpoints:
GET /api/conversations/list?status=active&limit=100- List conversationsDELETE /api/conversations/:id- Hard delete conversationGET /api/health- MongoDB connection health check (Phase 2)Technical Decisions Already Made
All architectural decisions have been documented by specialized agents:
Backend (
.claude/doc/chat_history/backend.md):{ _id: 1 },{ updatedAt: -1 },{ status: 1, updatedAt: -1 }Frontend (
.claude/doc/chat_history/frontend-data-architecture.md):useConversationStorage(sessionStorage)UI/UX (
.claude/doc/chat_history/sidebar-ui-design.md):Sidebar(collapsible, responsive, accessible)Definition of Done
Implementation Complete:
MongoDBClientsingleton with connection pooling and retry logicMongoDBConversationRepositoryimplementingIConversationRepositoryinterfaceConversationDocumentMapperwith entity restoration viaConversation.restore()DependencyContainerwith async initialization andREPOSITORY_TYPEenv variableGET /api/conversations/listendpoint with status filtering and paginationDELETE /api/conversations/:idendpoint for hard deleteSidebar,ScrollArea,AlertDialoguseConversationhook withloadConversation(conversationId)methoduseConversationsListQuery,useDeleteConversationMutationEdge Cases Handled:
Unit Tests Added (>80% coverage):
MongoConversationRepository.unit.test.ts(mocked MongoDB client)ConversationDocumentMapper.test.ts(round-trip entity → document → entity)ManageConversationUseCase.test.ts(mocked repository)useConversationsListQuery.test.tsx(fetch, error, caching, stale time)useDeleteConversationMutation.test.tsx(optimistic updates, rollback)Sidebar.test.tsx(rendering, collapse, filters, states, accessibility)ConversationListItem.test.tsx(click, delete, active state, truncation)Integration Tests:
MongoConversationRepository.integration.test.ts(mongodb-memory-server)conversation-switching.test.tsx(sidebar → chat flow)delete-conversation.test.tsx(delete → refetch → UI update)filter-conversations.test.tsx(filter changes → query updates)Documentation Updated:
.env.examplewithMONGODB_URL,DATABASE_NAME,REPOSITORY_TYPEvariables.claude/doc/chat_history/(already created)Code Review Approved:
CI/CD Passes:
yarn build)Manual Testing Complete:
Manual Testing Checklist
Basic Flow (5 minutes):
Edge Case Testing (3 minutes):
Error Handling (3 minutes):
MONGODB_URL) → Refresh app → Verify fallback to InMemory + console warningIntegration (2 minutes):
Responsive Behavior (2 minutes):
Acceptance Criteria Reference
Critical Path (Must Pass):
Important (Should Pass):
Complete acceptance criteria:
.claude/doc/chat_history/acceptance-criteria.md(75+ criteria)Implementation Plan
Phase 1: Backend Infrastructure (Priority: HIGH):
mongodbdriver:yarn add mongodbyarn add -D mongodb-memory-serverMongoDBClientsingleton with connection poolingConversationDocumentMapperwith entity restorationMongoDBConversationRepositoryDependencyContainerfor async initializationGET /api/conversations/listendpointDELETE /api/conversations/:idendpointPhase 2: Frontend Data Layer (Priority: HIGH):
yarn add -D msw@latestConversationServicewithlistConversations()and error handlinguseConversationsListQueryhookuseDeleteConversationMutationwith optimistic updatesuseConversationhook withloadConversation()methoduseSwitchConversationbusiness hookPhase 3: UI Components (Priority: HIGH):
npx shadcn-ui@latest add sidebarConversationSidebarcomponent (basic structure)ConversationListItemcomponent (title, preview, timestamp, delete)ConversationListcomponent (ScrollArea + list mapping)layout.tsxwithSidebarProviderSidebarTriggerto NavbarPhase 4: Integration & Polish (Priority: MEDIUM):
Phase 5: Monitoring & Optimization (Priority: LOW - Future):
/api/healthendpoint for MongoDB connection healthDependencies
Environment Variables Required:
MONGODB_URL=mongodb+srv://user:pass@cluster.mongodb.net/ DATABASE_NAME=ai_chat_app REPOSITORY_TYPE=mongodb # or 'inmemory' for testingNew Packages:
mongodb- MongoDB Node.js drivermongodb-memory-server(dev) - In-memory MongoDB for integration testsmsw(dev) - Mock Service Worker for frontend testingExisting Dependencies (Already Installed):
@tanstack/react-query- State managementaxios- HTTP clientvitest- Test runner@testing-library/react- Component testingshadcn/ui- UI componentsRelated Documentation
All planning documents are in
.claude/doc/chat_history/:backend.md- MongoDB repository architecture (8,000+ words)frontend-data-architecture.md- React Query integration (6,000+ words)sidebar-ui-design.md- UI/UX specifications (5,000+ words)backend-testing-strategy.md- Testing approach (4,000+ words)frontend-testing-strategy.md- Frontend testing (4,500+ words)acceptance-criteria.md- 75+ acceptance criteria (11,500+ words)validation-checklist.md- Manual testing guide (quick reference)test-scenario-mapping.md- 135 test scenarios mapped to ACsSession context:
.claude/sessions/context_session_chat_history.mdNotes
REPOSITORY_TYPE=inmemoryfor local development,REPOSITORY_TYPE=mongodbfor productionmongodb+srv://connection:***@gurusup-prod.kyw62.mongodb.net