Skip to content

maitrekpatel1612/docbot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

RAG Chatbot - AI-Powered Document Assistant

A full-stack RAG (Retrieval-Augmented Generation) chatbot that allows users to upload PDF and DOCX documents and chat with an AI about their content. Built with React, Express.js, LangChain, FAISS, and Google Gemini.

RAG Chatbot Node.js React Docker

πŸš€ Features

  • πŸ“„ Document Upload: Upload one or multiple PDF and DOCX files (max 5 files, 10MB each)
  • πŸ€– AI-Powered Chat: Ask questions about uploaded documents using Google Gemini 2.0 Flash
  • πŸ”’ Session-Based: Each user session maintains its own vector store and chat history
  • 🧹 Auto-Cleanup: Documents and embeddings automatically cleared on session end
  • πŸ’… Responsive UI: Modern, clean interface built with React and Tailwind CSS
  • 🐳 Dockerized: Fully containerized with Docker Compose for easy deployment
  • ⚑ Fast Vector Search: FAISS-powered semantic search with HuggingFace embeddings
  • πŸ“ Markdown Support: Rich markdown rendering in chat responses

πŸ“‹ Prerequisites

  • Node.js 20+ (for local development)
  • Docker and Docker Compose (for containerized deployment)
  • Google Gemini API Key - Get it from Google AI Studio

πŸ—οΈ Architecture

System Architecture Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          CLIENT BROWSER                         β”‚
β”‚                     (React + Tailwind CSS)                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚ HTTP/HTTPS
                         β”‚ (Port 80/443)
                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      NGINX (Frontend)                           β”‚
β”‚              Serves React SPA + Static Assets                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚ API Calls
                         β”‚ (Port 5000)
                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   EXPRESS.JS BACKEND                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Middleware Layer                                        β”‚   β”‚
β”‚  β”‚  β€’ CORS β€’ Helmet β€’ Sessions β€’ Error Handler β€’ Multer     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Routes                                                  β”‚   β”‚
β”‚  β”‚  β€’ /api/upload  β€’ /api/chat  β€’ /api/session              β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Controllers                                             β”‚   β”‚
β”‚  β”‚  β€’ uploadController  β€’ chatController  β€’ sessionCtrl     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Services (Business Logic)                               β”‚   β”‚
β”‚  β”‚  β€’ ragService        β€’ vectorStoreService                β”‚   β”‚
β”‚  β”‚  β€’ sessionService    β€’ documentLoader                    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
└────────────────┬──────────────────────┬────────────────────────-β”˜
                 β”‚                      β”‚
                 β–Ό                      β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚     File System    β”‚  β”‚     Memory Store     β”‚
     β”‚   (uploads/)       β”‚  β”‚  β€’ Vector Stores     β”‚
     β”‚   β€’ PDF Files      β”‚  β”‚  β€’ Sessions          β”‚
     β”‚   β€’ DOCX Files     β”‚  β”‚  β€’ Chat History      β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚           External Services            β”‚
     β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
     β”‚  β”‚ Google Gemini    β”‚ β”‚ HuggingFace  β”‚ β”‚
     β”‚  β”‚ (LLM - 2.0 Flash)β”‚ β”‚ (Embeddings) β”‚ β”‚
     β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow Diagram

1. Document Upload Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User    β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
     β”‚ 1. Select/Drop Files (PDF/DOCX)
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FileUpload     β”‚
β”‚  Component      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 2. POST /api/upload (multipart/form-data)
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  uploadMiddleware       β”‚
β”‚  (Multer)               β”‚
β”‚  β€’ Validate file type   β”‚
β”‚  β€’ Check file size      β”‚
β”‚  β€’ Save to uploads/     β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 3. Files saved
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  uploadController       β”‚
β”‚  β€’ Get file paths       β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 4. Process documents
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ragService             β”‚
β”‚  processDocuments()     β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 5. Load documents
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  documentLoader         β”‚
β”‚  β€’ Parse PDF/DOCX       β”‚
β”‚  β€’ Extract text         β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 6. Document chunks
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  vectorStoreService     β”‚
β”‚  createVectorStore()    β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 7a. Split into chunks (1000 chars, 200 overlap)
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  HuggingFace            β”‚
β”‚  all-MiniLM-L6-v2       β”‚
β”‚  β€’ Generate embeddings  β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 7b. Embeddings (384-dim vectors)
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FAISS                  β”‚
β”‚  β€’ Create index         β”‚
β”‚  β€’ Store vectors        β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 8. Vector store created
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  sessionService         β”‚
β”‚  β€’ Store vectorStore    β”‚
β”‚  β€’ Link to session      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 9. Success response
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Frontend       β”‚
β”‚  β€’ Show success β”‚
β”‚  β€’ Display filesβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Chat/Query Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User    β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
     β”‚ 1. Type question
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  MessageInput   β”‚
β”‚  Component      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 2. POST /api/chat { question }
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  chatController         β”‚
β”‚  β€’ Get session ID       β”‚
β”‚  β€’ Extract question     β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 3. Process query
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ragService             β”‚
β”‚  chat()                 β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 4. Get session data
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  sessionService         β”‚
β”‚  β€’ Retrieve vectorStore β”‚
β”‚  β€’ Get chat history     β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 5a. Embed question
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  HuggingFace            β”‚
β”‚  all-MiniLM-L6-v2       β”‚
β”‚  β€’ Convert to vector    β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 5b. Question vector
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FAISS VectorStore      β”‚
β”‚  similaritySearch()     β”‚
β”‚  β€’ Find top 3 matches   β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 6. Retrieved chunks
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ragService             β”‚
β”‚  β€’ Format context       β”‚
β”‚  β€’ Build prompt         β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 7. Prompt with context
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Google Gemini          β”‚
β”‚  gemini-2.0-flash       β”‚
β”‚  β€’ Generate answer      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 8. AI response
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ragService             β”‚
β”‚  β€’ Save to history      β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚ 9. Return answer
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ChatInterface  β”‚
β”‚  β€’ Display msg  β”‚
β”‚  β€’ Render MD    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Interaction Diagram

Frontend (React)                Backend (Express.js)
═══════════════════            ═══════════════════════

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   App.jsx   │────────────────│  Session Mgmt    β”‚
β”‚             β”‚  Session Cookieβ”‚  Middleware      β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚     β”‚         β”‚            β”‚
       β–Ό     β–Ό         β–Ό            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚FileUploadβ”‚ β”‚Chat β”‚ β”‚Msg   β”‚ β”‚Session   β”‚
β”‚Component β”‚ β”‚Intf β”‚ β”‚Input β”‚ β”‚Controls  β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
     β”‚          β”‚        β”‚         β”‚
     β”‚          β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                   β”‚
     β–Ό                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     api.js (Axios)              β”‚
β”‚  β€’ uploadFiles()                β”‚
β”‚  β€’ sendChatMessage()            β”‚
β”‚  β€’ getChatHistory()             β”‚
β”‚  β€’ clearSession()               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ HTTP Requests
             β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚   Routes          β”‚
     β”‚  /api/upload      │◄──── uploadMiddleware (Multer)
     β”‚  /api/chat        β”‚
     β”‚  /api/session     β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚   Controllers     β”‚
     β”‚  uploadController β”‚
     β”‚  chatController   β”‚
     β”‚  sessionCtrl      β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚    Services       β”‚
     β”‚  ragService       │◄─── Google Gemini API
     β”‚  vectorStoreService│◄─── HuggingFace
     β”‚  sessionService   β”‚
     β”‚  documentLoader   β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RAG Pipeline Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    RAG PROCESSING PIPELINE                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 1: DOCUMENT INGESTION
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Upload  β”‚
β”‚ PDF/DOCX     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Document Loaders    β”‚
β”‚ β€’ PDFLoader         β”‚
β”‚ β€’ DocxLoader        β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Raw Text
       β–Ό

Step 2: TEXT CHUNKING
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ RecursiveCharacterSplitter  β”‚
β”‚ β€’ Chunk Size: 1000 chars    β”‚
β”‚ β€’ Overlap: 200 chars        β”‚
β”‚ β€’ Preserves context         β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Text Chunks
       β–Ό

Step 3: EMBEDDING GENERATION
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ HuggingFace Embeddings      β”‚
β”‚ Model: all-MiniLM-L6-v2     β”‚
β”‚ β€’ Input: Text chunks        β”‚
β”‚ β€’ Output: 384-dim vectors   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Vector Embeddings
       β–Ό

Step 4: VECTOR STORAGE
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FAISS Vector Store          β”‚
β”‚ β€’ Index Type: Flat (L2)     β”‚
β”‚ β€’ In-Memory Storage         β”‚
β”‚ β€’ Per-Session Isolation     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Vector Store Ready
       β–Ό

Step 5: QUERY PROCESSING
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Query   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Embed Query                 β”‚
β”‚ (same embedding model)      β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Query Vector
       β–Ό

Step 6: SIMILARITY SEARCH
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FAISS Similarity Search     β”‚
β”‚ β€’ Algorithm: Cosine Sim     β”‚
β”‚ β€’ Retrieve Top K=3          β”‚
β”‚ β€’ Return relevant chunks    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Relevant Context
       β–Ό

Step 7: PROMPT CONSTRUCTION
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LangChain Prompt Template   β”‚
β”‚ β€’ System Instructions       β”‚
β”‚ β€’ Context: Retrieved chunks β”‚
β”‚ β€’ User Question             β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Formatted Prompt
       β–Ό

Step 8: GENERATION
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Google Gemini 2.0 Flash     β”‚
β”‚ β€’ Temperature: Default      β”‚
β”‚ β€’ Max Tokens: Auto          β”‚
β”‚ β€’ Response: Text            β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Generated Answer
       β–Ό

Step 9: POST-PROCESSING
────────────────────────────
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β€’ Save to chat history      β”‚
β”‚ β€’ Format response           β”‚
β”‚ β€’ Return to user            β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Sees    β”‚
β”‚ AI Response  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Session Lifecycle Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SESSION LIFECYCLE                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Opens   β”‚
β”‚ Application  β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Session Middleware      β”‚
β”‚ β€’ Check session cookie  β”‚
β”‚ β€’ No session exists?    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ YES - Create New
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ sessionService.createSession()  β”‚
β”‚ β€’ Generate unique ID (UUID)     β”‚
β”‚ β€’ Initialize empty state:       β”‚
β”‚   - vectorStore: null           β”‚
β”‚   - chatHistory: []             β”‚
β”‚   - uploadedFiles: []           β”‚
β”‚   - createdAt: timestamp        β”‚
β”‚   - lastAccessedAt: timestamp   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Session Created
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Store in Express Session        β”‚
β”‚ β€’ Set cookie: connect.sid       β”‚
β”‚ β€’ Save ragSessionId             β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Uploads Documents          β”‚
β”‚ β€’ Files saved to uploads/       β”‚
β”‚ β€’ Vector store created          β”‚
β”‚ β€’ Linked to session             β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Chats (Multiple Times)     β”‚
β”‚ β€’ Each message saved            β”‚
β”‚ β€’ Chat history maintained       β”‚
β”‚ β€’ lastAccessedAt updated        β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚             β”‚                      β”‚
       β–Ό             β–Ό                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Clears  β”‚ β”‚ User Closes  β”‚  β”‚ Session Timeout  β”‚
β”‚ Session      β”‚ β”‚ Browser      β”‚  β”‚ (30 min idle)    β”‚
β”‚ (Manual)     β”‚ β”‚ (Cookie exp) β”‚  β”‚ (Auto cleanup)   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                β”‚                  β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                        β–Ό
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ sessionService.clearSession()  β”‚
       β”‚ β€’ Delete uploaded files        β”‚
       β”‚ β€’ Clear vector store (memory)  β”‚
       β”‚ β€’ Clear chat history           β”‚
       β”‚ β€’ Remove from sessions map     β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                        β–Ό
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ Session Destroyed              β”‚
       β”‚ Resources freed                β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Background Process:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Cleanup Service (runs every 10 min)    β”‚
β”‚ β€’ Check all sessions                    β”‚
β”‚ β€’ Find inactive > SESSION_TTL (30 min) β”‚
β”‚ β€’ Auto-clear expired sessions           β”‚
β”‚ β€’ Free memory resources                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Deployment Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     DOCKER COMPOSE                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  Docker Network  β”‚
                    β”‚  rag-chatbot-net β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚                                 β”‚
            β–Ό                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Frontend Container    β”‚        β”‚  Backend Container     β”‚
β”‚  ────────────────────  β”‚        β”‚  ───────────────────   β”‚
β”‚  β€’ Node:20-alpine      β”‚        β”‚  β€’ Node:20-alpine      β”‚
β”‚  β€’ Build: Vite         β”‚        β”‚  β€’ Runtime: Node.js    β”‚
β”‚  β€’ Serve: Nginx        β”‚        β”‚  β€’ Express.js app      β”‚
β”‚  β€’ Port: 80            │◄───────│  β€’ Port: 5000          β”‚
β”‚  β€’ Health: /health     β”‚  API   β”‚  β€’ Health: /api/health β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Calls  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                  β”‚
         β”‚                                  β”‚
    Serves Static                    β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
    React App                        β”‚            β”‚
         β”‚                           β–Ό            β–Ό
         β”‚                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    User Browser            β”‚ Volume:     β”‚ β”‚ Volume:     β”‚
         β”‚                  β”‚ uploads/    β”‚ β”‚ cache/      β”‚
         β”‚                  β”‚ (Persist)   β”‚ β”‚ (Models)    β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              Port 80
                                     β”‚
                              External APIs
                                     β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                                 β”‚
                    β–Ό                                 β–Ό
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚ Google Gemini    β”‚          β”‚ HuggingFace      β”‚
           β”‚ API (LLM)        β”‚          β”‚ Transformers     β”‚
           β”‚ gemini-2.0-flash β”‚          β”‚ all-MiniLM-L6-v2 β”‚
           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technology Stack

Backend:

  • Express.js - Web framework
  • LangChain - RAG orchestration
  • FAISS - Vector store
  • HuggingFace Transformers - Text embeddings (all-MiniLM-L6-v2)
  • Google Gemini 2.0 Flash - LLM
  • Multer - File upload handling
  • Express Session - Session management

Frontend:

  • React 18 - UI framework
  • Vite - Build tool
  • Tailwind CSS - Styling
  • React Dropzone - File upload interface
  • React Markdown - Markdown rendering
  • Axios - HTTP client

Project Structure

rag-chatbot/
β”œβ”€β”€ backend/                 # Express.js backend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ controllers/     # Request handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ uploadController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ chatController.js
β”‚   β”‚   β”‚   └── sessionController.js
β”‚   β”‚   β”œβ”€β”€ services/        # Business logic
β”‚   β”‚   β”‚   β”œβ”€β”€ ragService.js          # RAG implementation
β”‚   β”‚   β”‚   β”œβ”€β”€ vectorStoreService.js  # FAISS operations
β”‚   β”‚   β”‚   └── sessionService.js      # Session management
β”‚   β”‚   β”œβ”€β”€ routes/          # API routes
β”‚   β”‚   β”‚   β”œβ”€β”€ uploadRoutes.js
β”‚   β”‚   β”‚   β”œβ”€β”€ chatRoutes.js
β”‚   β”‚   β”‚   └── sessionRoutes.js
β”‚   β”‚   β”œβ”€β”€ middleware/      # Express middleware
β”‚   β”‚   β”‚   β”œβ”€β”€ uploadMiddleware.js    # Multer config
β”‚   β”‚   β”‚   β”œβ”€β”€ sessionMiddleware.js
β”‚   β”‚   β”‚   └── errorHandler.js
β”‚   β”‚   β”œβ”€β”€ utils/           # Utility functions
β”‚   β”‚   β”‚   └── documentLoader.js      # PDF/DOCX loaders
β”‚   β”‚   └── app.js           # Express app entry point
β”‚   β”œβ”€β”€ uploads/             # Uploaded files storage
β”‚   β”œβ”€β”€ .env                 # Environment variables
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── package.json
β”‚
β”œβ”€β”€ frontend/                # React + Vite frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/      # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ ChatInterface.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ FileUpload.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ MessageInput.jsx
β”‚   β”‚   β”‚   └── ErrorBoundary.jsx
β”‚   β”‚   β”œβ”€β”€ hooks/           # Custom hooks
β”‚   β”‚   β”‚   β”œβ”€β”€ useChat.js
β”‚   β”‚   β”‚   └── useSession.js
β”‚   β”‚   β”œβ”€β”€ services/        # API service
β”‚   β”‚   β”‚   └── api.js
β”‚   β”‚   β”œβ”€β”€ App.jsx          # Main app component
β”‚   β”‚   └── main.jsx         # Entry point
β”‚   β”œβ”€β”€ Dockerfile
β”‚   β”œβ”€β”€ nginx.conf           # Nginx configuration
β”‚   └── package.json
β”‚
β”œβ”€β”€ docker-compose.yml       # Docker orchestration
└── README.md                # This file

πŸš€ Quick Start with Docker (Recommended)

1. Clone and Setup

# Create .env file in root directory
cat > .env << EOF
GOOGLE_API_KEY=your_google_gemini_api_key_here
SESSION_SECRET=your_random_secret_string_here
EOF

2. Start with Docker Compose

docker-compose up -d

3. Access the Application

4. Stop the Application

docker-compose down

πŸ› οΈ Local Development Setup

Backend Setup

  1. Navigate to backend directory:
cd backend
  1. Install dependencies:
npm install
  1. Create .env file:
# Copy your Google Gemini API Key from: https://makersuite.google.com/app/apikey
GOOGLE_API_KEY=your_api_key_here

# Server Configuration
PORT=5000
NODE_ENV=development

# Session Configuration
SESSION_SECRET=your_random_secret_key_here

# Upload Limits
MAX_FILE_SIZE=10485760  # 10MB
MAX_FILES=5

# Session TTL (milliseconds) - 30 minutes
SESSION_TTL=1800000
  1. Start the backend:
npm run dev

Backend will run on http://localhost:5000

Frontend Setup

  1. Navigate to frontend directory:
cd frontend
  1. Install dependencies:
npm install
  1. Create .env file (optional):
VITE_API_URL=http://localhost:5000
  1. Start the frontend:
npm run dev

Frontend will run on http://localhost:5173

πŸ“‘ API Endpoints

Upload

  • POST /api/upload - Upload PDF/DOCX files
    • Body: multipart/form-data with files field
    • Response: Upload confirmation with file count and document count

Chat

  • POST /api/chat - Send a chat message

    • Body: { "question": "Your question here" }
    • Response: { "success": true, "data": { "answer": "AI response" } }
  • GET /api/chat/history - Get chat history

    • Response: Array of chat messages with roles and timestamps

Session

  • GET /api/session - Get session information

    • Response: Session details, uploaded files count, document count
  • DELETE /api/session - Clear current session

    • Response: Confirmation and new session ID

Health

  • GET /api/health - Health check
    • Response: Server status and active session count

🎯 Usage Guide

1. Upload Documents

  • Click or drag-and-drop PDF/DOCX files into the upload area
  • Wait for the success notification
  • Supported formats: .pdf, .docx
  • Limits: Max 5 files, 10MB each

2. Chat with Your Documents

  • Type your question in the input field at the bottom
  • Press Enter or click Send
  • AI will respond based on document content
  • Chat history is maintained during your session

3. Clear Session

  • Click the "Clear Session" button in the header to reset
  • This deletes all uploaded files and chat history
  • Session also clears automatically when you close the browser

βš™οΈ Configuration

Backend Environment Variables

Variable Default Description
GOOGLE_API_KEY - Required: Google Gemini API key
PORT 5000 Backend server port
SESSION_SECRET - Required: Secret for session encryption
MAX_FILE_SIZE 10485760 Max file size in bytes (10MB)
MAX_FILES 5 Max number of files per upload
SESSION_TTL 1800000 Session timeout in ms (30 minutes)
NODE_ENV development Environment mode
FRONTEND_URL http://localhost:5173 Frontend URL for CORS

Frontend Environment Variables

Variable Default Description
VITE_API_URL http://localhost:5000 Backend API URL

πŸ” How It Works (RAG Pipeline)

1. Document Upload & Processing

User uploads PDF/DOCX β†’ Backend receives files β†’ 
Parse documents to text β†’ Split into chunks (1000 chars, 200 overlap) β†’
Generate embeddings using HuggingFace (all-MiniLM-L6-v2) β†’
Store in FAISS vector store (in-memory, per session)

2. Question Answering

User asks question β†’ Embed question using same model β†’
Search FAISS for top 3 most relevant chunks β†’
Combine chunks as context β†’
Send context + question to Google Gemini 2.0 Flash β†’
Generate answer based only on provided context β†’
Return answer to user

3. Session Management

  • Each user gets a unique session ID (stored in cookies)
  • Sessions store: vector store, uploaded files, chat history
  • Auto-cleanup runs every 10 minutes to remove inactive sessions
  • Sessions expire after 30 minutes of inactivity

πŸ› οΈ Troubleshooting

Common Issues

1. Upload fails with "Network Error"

  • Check if backend is running on port 5000
  • Verify CORS settings in backend/src/app.js
  • Ensure frontend is accessing correct API URL

2. "No documents uploaded" error when chatting

  • Upload documents first before asking questions
  • Check if upload was successful (green notification)
  • Try clearing session and re-uploading

3. Docker container fails to start

  • Verify .env file exists with required variables
  • Check if ports 80 and 5000 are available
  • Run docker-compose logs to see error details

4. Slow response times

  • First request is slow due to model loading
  • Subsequent requests should be faster
  • Consider increasing memory allocation for Docker

5. "Invalid file type" error

  • Only PDF and DOCX files are supported
  • Check file extension is exactly .pdf or .docx
  • Ensure file is not corrupted

πŸ“ Development Notes

Adding New Document Types

To support additional file formats, modify:

  1. backend/src/utils/documentLoader.js - Add new loader
  2. backend/src/middleware/uploadMiddleware.js - Update file filter
  3. frontend/src/components/FileUpload.jsx - Update accepted types

Changing the LLM

To use a different model, modify backend/src/services/ragService.js:

  • Update initializeGemini() method
  • Change model configuration
  • Adjust prompt template if needed

Customizing Embeddings

To use different embeddings, modify backend/src/services/vectorStoreService.js:

  • Change the modelName in getEmbeddings()
  • Options: any HuggingFace transformers model

πŸš€ Production Deployment

Docker Deployment (Recommended)

  1. Set production environment variables
  2. Build and run with Docker Compose:
docker-compose up -d --build
  1. Use a reverse proxy (nginx/traefik) for HTTPS
  2. Set NODE_ENV=production in backend
  3. Configure proper session secrets

Manual Deployment

Backend:

cd backend
npm install --production
NODE_ENV=production node src/app.js

Frontend:

cd frontend
npm install
npm run build
# Serve dist/ folder with nginx or similar

πŸ“„ License

MIT License - feel free to use this project for personal or commercial purposes.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“§ Support

If you have any questions or run into issues:

  1. Check the troubleshooting section above
  2. Review the console logs for error details
  3. Open an issue on GitHub

πŸ”— Links


Built with ❀️ using React, Express.js, LangChain, and Google Gemini

  1. Session Management:
    • Each user gets a unique session ID
    • Vector store and chat history tied to session
    • Inactive sessions cleaned up after 30 minutes
    • Page refresh triggers session cleanup

πŸ› Troubleshooting

Backend Issues

Error: "GOOGLE_API_KEY not found"

  • Ensure .env file exists in backend directory
  • Check that GOOGLE_API_KEY is set correctly

Error: "Failed to load documents"

  • Verify file format is PDF or DOCX
  • Check file size is under 10MB
  • Ensure backend has write permissions for uploads/ folder

Error: "Model download timeout"

  • First run downloads HuggingFace model (~50MB)
  • Wait a few minutes or check internet connection
  • Docker: Model cached in huggingface-cache volume

Frontend Issues

Files not uploading

  • Check backend is running on port 5000
  • Verify CORS settings in backend
  • Check browser console for errors

Chat not working

  • Ensure documents are uploaded first
  • Check backend logs for errors
  • Verify Gemini API key is valid

Docker Issues

Port already in use

  • Change ports in docker-compose.yml
  • Or stop conflicting services

Container fails to start

  • Check logs: docker-compose logs
  • Ensure .env file exists with API key
  • Try rebuilding: docker-compose up --build

πŸ“ Development Notes

  • Vector Store: In-memory only, not persisted to disk
  • Embeddings: Cached in Docker volume for faster restarts
  • Session Storage: Express-session with memory store (use Redis for production scale)
  • File Cleanup: Uploaded files cleared with session (automatic)

πŸš€ Production Recommendations

  1. Use Redis for session storage (scalability)
  2. Implement rate limiting on API endpoints
  3. Add authentication for multi-user support
  4. Set up monitoring (health checks, logging)
  5. Use HTTPS with valid SSL certificates
  6. Configure nginx reverse proxy
  7. Set resource limits in Docker (memory, CPU)
  8. Implement file scanning for security

πŸ“„ License

MIT License - Feel free to use this project for personal or commercial purposes.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“§ Support

For issues and questions:

  • Create an issue on GitHub
  • Check existing issues for solutions

Built with ❀️ by Maitrek Patel

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published