GitHub - prk2007/Dynamic-Rag

๐Ÿš€ Dynamic RAG - Multi-Tenant RAG System

A production-ready multi-tenant SaaS platform providing Retrieval-Augmented Generation (RAG) pipelines for multiple customers. Built with enterprise-grade authentication, document processing, vector search, and comprehensive usage tracking.

Node.js 18+ TypeScript PostgreSQL Docker License: MIT

๐Ÿ“‹ Table of Contents

โœจ Features

๐Ÿ” Enterprise Authentication

  • Per-customer JWT secrets with AES-256-CBC encryption
  • Email verification with SendGrid integration and customizable templates
  • Token management with refresh token rotation and automatic revocation
  • Secure password hashing with bcrypt
  • Session management with logout and logout-all functionality
  • Forward-compatible with OAuth/SSO (Google, Microsoft, GitHub) - In roadmap
  • MFA/2FA ready infrastructure - In roadmap

๐Ÿ“„ Document Processing

  • Multi-format support: PDF, TXT, HTML, Markdown
  • Async processing pipeline with BullMQ for scalable job processing
  • Intelligent chunking with configurable size and overlap
  • OpenAI embeddings (text-embedding-3-small/large) - customer-configurable
  • S3-compatible storage (MinIO for local dev, AWS S3 for production)
  • URL ingestion for web content processing
  • Progress tracking with real-time status updates
  • Automatic retry on processing failures
  • Cost tracking per document with token usage metrics

๐Ÿ” Vector Search & RAG

  • PostgreSQL with pgvector for high-performance vector storage with customer isolation
  • Semantic search with cosine similarity using pgvector
  • HNSW indexes for fast approximate nearest neighbor search
  • Multiple search strategies: chunks search, broad chunks search, catalog search
  • Advanced reranking with RRF (Reciprocal Rank Fusion) and ML cross-encoders
  • Hybrid search with intelligent fallback mechanisms
  • Context-aware retrieval for improved answer quality
  • MCP Protocol integration for Claude Desktop

๐Ÿข Multi-Tenant Architecture

  • Complete customer isolation with row-level security
  • Per-customer vector isolation using customer_id filtering in pgvector tables
  • Per-customer rate limiting and quotas (configurable)
  • Usage tracking and billing metrics (requests, tokens, costs)
  • Customer-specific configuration (API keys, model selection, limits)
  • Encrypted API key storage for customer OpenAI keys
  • Admin endpoints for global usage monitoring (optional)

๐ŸŽจ Modern Frontend

  • React 18 + TypeScript with Vite for fast development
  • Tailwind CSS for beautiful, responsive UI
  • User dashboard with document management
  • Document upload with drag-and-drop support
  • Search interface for querying documents
  • Profile management with OpenAI API key configuration
  • Usage statistics and metrics visualization
  • Mobile-first responsive design
  • Real-time status updates for document processing

๐Ÿ“Š Production Ready

  • Docker Compose for easy deployment and development
  • Health checks and monitoring endpoints
  • Comprehensive error handling with structured logging
  • Graceful shutdown support for zero-downtime deployments
  • Rate limiting middleware with Redis
  • Usage tracking middleware for all API calls
  • CORS configuration for secure cross-origin requests
  • Environment-based configuration for dev/staging/prod

๐Ÿ—๏ธ Architecture

System Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Frontend (React + Vite)                   โ”‚
โ”‚              http://localhost:3000 (nginx)                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  Login   โ”‚  โ”‚Dashboard โ”‚  โ”‚Documents โ”‚  โ”‚ Profile  โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚ HTTP/REST API
                           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              API Server (Express + TypeScript)               โ”‚
โ”‚                  http://localhost:3001                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚   Auth   โ”‚  โ”‚Documents โ”‚  โ”‚ Profile  โ”‚  โ”‚   MCP    โ”‚   โ”‚
โ”‚  โ”‚  Routes  โ”‚  โ”‚  Routes  โ”‚  โ”‚  Routes  โ”‚  โ”‚  Routes  โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  Middleware: Auth, Rate Limit, Usage Tracking        โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚        โ”‚        โ”‚        โ”‚        โ”‚
    โ–ผ        โ–ผ        โ–ผ        โ–ผ        โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚Postgresโ”‚โ”‚Redis โ”‚โ”‚ MinIO/ โ”‚โ”‚   Worker         โ”‚
โ”‚+pgvector(Cacheโ”‚โ”‚   S3   โ”‚โ”‚  (BullMQ)        โ”‚
โ”‚ (DB)   โ”‚โ”‚Queue)โ”‚โ”‚        โ”‚โ”‚                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚                  โ”‚         โ”‚              โ”‚
    โ”‚                  โ”‚         โ”‚              โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              Document Processing Pipeline

Tech Stack

Backend:

  • Runtime: Node.js 18+ with TypeScript 5.7
  • Framework: Express.js with async/await
  • Database: PostgreSQL 15+ with pgvector extension (metadata, customers, vector embeddings)
  • Vector Storage: pgvector with HNSW indexes for fast similarity search
  • Cache/Queue: Redis 7+ with BullMQ for async jobs
  • Storage: MinIO (S3-compatible, AWS S3 for production)
  • Auth: JWT with per-customer secrets, AES-256 encryption
  • Email: SendGrid for email verification
  • Embeddings: OpenAI (customer-configurable API keys)
  • Reranking: RRF + transformers.js (ML cross-encoder)

Frontend:

  • Framework: React 18 with TypeScript
  • Build Tool: Vite for fast HMR
  • Styling: Tailwind CSS 3+
  • State Management: Zustand
  • Forms: React Hook Form + Zod validation
  • Routing: React Router v6
  • HTTP Client: Axios with interceptors
  • Notifications: React Hot Toast

Infrastructure:

  • Containerization: Docker + Docker Compose
  • Web Server: nginx (frontend production)
  • Process Manager: Node.js native (with graceful shutdown)
  • Monitoring: Health checks + usage metrics

๐Ÿš€ Quick Start

Prerequisites

  • Docker & Docker Compose (recommended for easiest setup)
  • Node.js 18+ (for local development)
  • OpenAI API Key (optional - customers can use their own)
  • SendGrid API Key (optional - for email verification)

โšก One-Command Setup (Recommended)

Get everything running in under 5 minutes with full automation!

# 1. Clone the repository
git clone https://github.com/prk2007/dynamic-rag.git
cd dynamic-rag

# 2. Run the automated setup script
chmod +x setup.sh && ./setup.sh

That's it! The script automatically:

  • โœ… Creates .env files from templates
  • โœ… Generates secure ENCRYPTION_KEY and database password
  • โœ… Builds and starts all Docker containers
  • โœ… Runs database migrations
  • โœ… Installs pgvector extension
  • โœ… Creates MinIO bucket
  • โœ… Verifies all services are healthy

After setup completes, verify your deployment:

๐Ÿ“– For detailed instructions, see QUICKSTART.md

Option 1: Manual Docker Setup

If you prefer manual control or the automated script fails:

# 1. Clone the repository
git clone https://github.com/prk2007/dynamic-rag.git
cd dynamic-rag

# 2. Set up backend environment
cp .env.example .env

# 3. Generate encryption key and update .env
openssl rand -hex 32
# Copy the output and set ENCRYPTION_KEY in .env

# 4. Set up frontend environment
cp frontend/.env.example frontend/.env

# 5. Start all services (migrations run automatically)
docker-compose up -d

# 6. Check service health
docker-compose ps
# All services should show "Up" status

# 7. Verify deployment (optional)
./verify-deployment.sh

Access the application:

Create your first account:

  1. Visit http://localhost:3000
  2. Click "Sign Up"
  3. Enter email and password
  4. Check email for verification link (or check logs if SendGrid not configured)
  5. Verify email and log in
  6. Start uploading documents!

Option 2: Local Development Setup

For active development work:

# 1. Clone and install dependencies
git clone https://github.com/prk2007/dynamic-rag.git
cd dynamic-rag
npm install

# 2. Start PostgreSQL and Redis (via Docker)
docker-compose up -d postgres redis minio

# 3. Set up environment
cp .env.example .env
# Edit .env with your settings
openssl rand -hex 32  # Use this for ENCRYPTION_KEY

# 4. Initialize database
npm run migrate
# or for fresh setup:
npm run db:setup

# 5. Start backend API (terminal 1)
npm run dev

# 6. Start worker (terminal 2)
npm run worker

# 7. Start frontend (terminal 3)
cd frontend
npm install
npm run dev

Services will be available at:

Option 3: Production Deployment

For production environments:

# 1. Clone the repository
git clone https://github.com/prk2007/dynamic-rag.git
cd dynamic-rag

# 2. Update environment variables for production
# - Use strong passwords
# - Set NODE_ENV=production
# - Configure ALLOWED_ORIGINS
# - Use managed services (RDS, ElastiCache, S3)

# 3. Build images
docker-compose build

# 4. Start services
docker-compose up -d

# 5. Set up SSL/TLS (use nginx/Traefik reverse proxy)
# 6. Configure domain names
# 7. Set up monitoring and backups

Quick Verification

Test the API:

# Health check
curl http://localhost:3001/health

# Should return: {"status":"ok","timestamp":"..."}

Test document upload:

  1. Log in to http://localhost:3000
  2. Navigate to "Upload" page
  3. Upload a PDF or text file
  4. Check processing status in "Documents" page
  5. Try searching your documents

View logs:

# All services
docker-compose logs -f

# Specific service
docker-compose logs -f api
docker-compose logs -f worker
docker-compose logs -f frontend

๐Ÿ“š API Documentation

Base URL

  • Local Development: http://localhost:3001/api
  • Production: https://yourdomain.com/api

Authentication

All endpoints except signup, login, and email verification require a Bearer token in the Authorization header:

Authorization: Bearer <access-token>

Endpoints

Sign Up

POST /api/auth/signup
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

# Response: 201 Created
{
  "success": true,
  "data": {
    "customerId": "uuid",
    "email": "user@example.com",
    "status": "pending_verification"
  },
  "message": "Signup successful. Please check your email to verify your account."
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

# Response: 200 OK
{
  "success": true,
  "data": {
    "accessToken": "eyJhbGc...",
    "refreshToken": "eyJhbGc...",
    "expiresIn": 86400,
    "customer": {
      "id": "uuid",
      "email": "user@example.com",
      "status": "active"
    }
  }
}

Verify Email

GET /api/auth/verify-email?token=<verification-token>

# Response: 200 OK (redirects to frontend)

Refresh Token

POST /api/auth/refresh
Content-Type: application/json

{
  "refreshToken": "eyJhbGc..."
}

# Response: 200 OK
{
  "success": true,
  "data": {
    "accessToken": "new-access-token",
    "refreshToken": "new-refresh-token",
    "expiresIn": 86400
  }
}

Get Current User

GET /api/auth/me
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "status": "active",
    "createdAt": "2024-01-01T00:00:00Z"
  }
}

Logout

POST /api/auth/logout
Authorization: Bearer <access-token>

# Response: 200 OK

Logout All Devices

POST /api/auth/logout-all
Authorization: Bearer <access-token>

# Response: 200 OK

Resend Verification Email

POST /api/auth/resend-verification
Content-Type: application/json

{
  "email": "user@example.com"
}

# Response: 200 OK

Documents

Upload Document

POST /api/documents/upload
Authorization: Bearer <access-token>
Content-Type: multipart/form-data

# Form Data:
# file: <file> (PDF, TXT, HTML, MD)

# Response: 201 Created
{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "document.pdf",
    "status": "queued",
    "mimeType": "application/pdf",
    "fileSize": 123456,
    "s3Key": "customers/uuid/documents/uuid/document.pdf"
  }
}

Upload from URL

POST /api/documents/url
Authorization: Bearer <access-token>
Content-Type: application/json

{
  "url": "https://example.com/document.pdf"
}

# Response: 201 Created

List Documents

GET /api/documents?page=1&limit=10&status=completed
Authorization: Bearer <access-token>

# Query Parameters:
# - page: Page number (default: 1)
# - limit: Items per page (default: 10, max: 100)
# - status: Filter by status (queued, processing, completed, failed)

# Response: 200 OK
{
  "success": true,
  "data": {
    "documents": [...],
    "pagination": {
      "page": 1,
      "limit": 10,
      "total": 50,
      "totalPages": 5
    }
  }
}

Get Document Details

GET /api/documents/:id
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "document.pdf",
    "status": "completed",
    "chunkCount": 42,
    "embeddingTokensUsed": 5000,
    "embeddingCostUsd": 0.001,
    "createdAt": "2024-01-01T00:00:00Z",
    "processedAt": "2024-01-01T00:01:00Z"
  }
}

Get Document Status

GET /api/documents/:id/status
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "status": "completed",
    "progress": 100
  }
}

Delete Document

DELETE /api/documents/:id
Authorization: Bearer <access-token>

# Response: 200 OK

Download Document

GET /api/documents/:id/download
Authorization: Bearer <access-token>

# Response: 200 OK (file download)

Search Documents

POST /api/documents/search
Authorization: Bearer <access-token>
Content-Type: application/json

{
  "query": "What is the healthcare system?",
  "limit": 10,
  "minScore": 0.7
}

# Response: 200 OK
{
  "success": true,
  "data": {
    "results": [
      {
        "documentId": "uuid",
        "documentTitle": "Healthcare Guide",
        "content": "...",
        "score": 0.95,
        "chunkIndex": 5
      }
    ],
    "query": "What is the healthcare system?",
    "totalResults": 10
  }
}

Get Document Statistics

GET /api/documents/stats
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "totalDocuments": 100,
    "completedDocuments": 95,
    "processingDocuments": 3,
    "failedDocuments": 2,
    "totalChunks": 4500,
    "totalTokensUsed": 125000,
    "totalCostUsd": 2.5
  }
}

Profile

Get Profile

GET /api/profile
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "status": "active",
    "hasOpenAIKey": true,
    "createdAt": "2024-01-01T00:00:00Z"
  }
}

Set OpenAI API Key

PUT /api/profile/openai-key
Authorization: Bearer <access-token>
Content-Type: application/json

{
  "apiKey": "sk-..."
}

# Response: 200 OK
{
  "success": true,
  "message": "OpenAI API key updated successfully"
}

Delete OpenAI API Key

DELETE /api/profile/openai-key
Authorization: Bearer <access-token>

# Response: 200 OK

Check OpenAI Key Status

GET /api/profile/openai-key/status
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "hasKey": true,
    "keyPrefix": "sk-proj-..."
  }
}

Usage Metrics

Get Usage Summary

GET /api/usage/summary
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "apiRequests": 1000,
    "embeddingTokens": 50000,
    "totalCost": 1.25,
    "period": "all-time"
  }
}

Get Usage by Type

GET /api/usage/:type?startDate=2024-01-01&endDate=2024-12-31
Authorization: Bearer <access-token>

# Parameters:
# - type: 'api' | 'embedding' | 'search'
# - startDate: ISO date string (optional)
# - endDate: ISO date string (optional)

# Response: 200 OK

MCP (Model Context Protocol)

List MCP Tools

GET /api/mcp
Authorization: Bearer <access-token>

# Response: 200 OK
{
  "success": true,
  "data": {
    "tools": [
      {
        "name": "search",
        "description": "Search documents using semantic similarity"
      }
    ]
  }
}

Execute MCP Tool

POST /api/mcp
Authorization: Bearer <access-token>
Content-Type: application/json

{
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": {
      "query": "healthcare system",
      "limit": 10
    }
  }
}

# Response: 200 OK

Health Check

System Health

GET /health

# Response: 200 OK
{
  "status": "ok",
  "timestamp": "2024-01-01T00:00:00Z",
  "uptime": 12345
}

Response Format

Success Response:

{
  "success": true,
  "data": { /* response data */ },
  "message": "Operation successful"
}

Error Response:

{
  "success": false,
  "error": "Error message describing what went wrong",
  "code": "ERROR_CODE"
}

Common Error Codes:

  • UNAUTHORIZED - Missing or invalid authentication token
  • FORBIDDEN - Insufficient permissions
  • NOT_FOUND - Resource not found
  • VALIDATION_ERROR - Invalid request data
  • RATE_LIMIT_EXCEEDED - Too many requests
  • INTERNAL_ERROR - Server error

๐ŸŽจ Frontend Application

The Dynamic RAG frontend is a modern React application with a beautiful, responsive UI.

Features

  • ๐Ÿ” Authentication: Login, signup, email verification
  • ๐Ÿ“„ Document Management: Upload, view, delete documents
  • ๐Ÿ” Search Interface: Query documents with semantic search
  • ๐Ÿ‘ค Profile Management: Update settings, manage OpenAI API key
  • ๐Ÿ“Š Usage Dashboard: View statistics and metrics
  • ๐Ÿ“ฑ Responsive Design: Works on desktop, tablet, and mobile
  • ๐ŸŽจ Modern UI: Beautiful design with Tailwind CSS

Pages

Public Pages:

  • /login - User login
  • /signup - New user registration
  • /verify-email - Email verification handler
  • /verification-pending - Verification pending notice

Protected Pages:

  • /dashboard - Main dashboard with overview
  • /documents - Document list and management
  • /upload - Document upload interface
  • /profile - User profile and settings
  • /api-keys - API key management (planned)

Tech Stack

  • React 18 + TypeScript for type safety
  • Vite for lightning-fast development
  • React Router v6 for routing
  • Zustand for state management
  • Axios with interceptors for API calls
  • React Hook Form + Zod for form validation
  • Tailwind CSS for styling
  • Heroicons for icons
  • React Hot Toast for notifications

Development

cd frontend
npm install
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview

See frontend/README.md for detailed frontend documentation.

๐Ÿ”ง Development

Local Development (without Docker)

# Install dependencies
npm install

# Start PostgreSQL & Redis (via Docker)
docker-compose up -d postgres redis minio

# Run migrations
npm run migrate

# Start API server
npm run dev

# Start worker (in another terminal)
npm run worker

# Start frontend (in another terminal)
cd frontend && npm install && npm run dev

Building

# Compile TypeScript
npm run build

# Start production server
npm start

๐Ÿ—„๏ธ Database Schema

PostgreSQL Tables

Core Tables:

  • customers - Customer accounts with encrypted JWT secrets and API keys
  • customer_config - Per-customer settings, quotas, and rate limits
  • documents - Document metadata, processing status, and metrics
  • email_verifications - Email verification tokens with expiration
  • usage_metrics - API usage tracking (requests, tokens, costs)

Key Fields:

-- customers table
CREATE TABLE customers (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  status VARCHAR(50) NOT NULL DEFAULT 'pending_verification',
  jwt_secret TEXT NOT NULL,  -- Encrypted per-customer JWT secret
  openai_api_key TEXT,        -- Encrypted OpenAI API key
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- documents table
CREATE TABLE documents (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id UUID REFERENCES customers(id) ON DELETE CASCADE,
  title VARCHAR(500) NOT NULL,
  mime_type VARCHAR(100),
  file_size BIGINT,
  status VARCHAR(50) DEFAULT 'queued',
  s3_key TEXT,
  chunk_count INTEGER DEFAULT 0,
  embedding_tokens_used INTEGER DEFAULT 0,
  embedding_cost_usd DECIMAL(10, 6) DEFAULT 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  processed_at TIMESTAMP,
  error_message TEXT
);

-- usage_metrics table
CREATE TABLE usage_metrics (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id UUID REFERENCES customers(id) ON DELETE CASCADE,
  metric_type VARCHAR(50) NOT NULL,  -- 'api', 'embedding', 'search'
  api_endpoint VARCHAR(255),
  tokens_used INTEGER DEFAULT 0,
  cost_usd DECIMAL(10, 6) DEFAULT 0,
  request_count INTEGER DEFAULT 1,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

pgvector Vector Storage

Vector embeddings are stored in PostgreSQL with pgvector extension with complete customer isolation:

Document Chunks Tables:

-- For text-embedding-3-small (1536 dimensions)
CREATE TABLE document_chunks (
  id TEXT PRIMARY KEY,
  document_id UUID REFERENCES documents(id) ON DELETE CASCADE,
  customer_id UUID REFERENCES customers(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  embedding vector(1536),  -- OpenAI text-embedding-3-small
  chunk_index INTEGER,
  start_char INTEGER,
  end_char INTEGER,
  title TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- For text-embedding-3-large (3072 dimensions)
CREATE TABLE document_chunks_3072 (
  id TEXT PRIMARY KEY,
  document_id UUID REFERENCES documents(id) ON DELETE CASCADE,
  customer_id UUID REFERENCES customers(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  embedding vector(3072),  -- OpenAI text-embedding-3-large
  chunk_index INTEGER,
  start_char INTEGER,
  end_char INTEGER,
  title TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- HNSW indexes for fast vector similarity search
CREATE INDEX idx_chunks_embedding_hnsw ON document_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

CREATE INDEX idx_chunks_3072_embedding_hnsw ON document_chunks_3072
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- Indexes for customer isolation
CREATE INDEX idx_chunks_customer_id ON document_chunks(customer_id);
CREATE INDEX idx_chunks_3072_customer_id ON document_chunks_3072(customer_id);

Vector Search Query Example:

-- Find top 10 most similar chunks for a customer
SELECT 
  id, 
  document_id, 
  content, 
  title,
  1 - (embedding <=> $1::vector) AS similarity
FROM document_chunks
WHERE customer_id = $2
ORDER BY embedding <=> $1::vector
LIMIT 10;

Benefits of pgvector:

  • โœ… High Performance: HNSW indexes provide fast approximate nearest neighbor search
  • โœ… Customer Isolation: Row-level security with customer_id filtering
  • โœ… ACID Compliance: Full transactional support
  • โœ… Scalable: Handles millions of vectors efficiently
  • โœ… Integrated: All data in one PostgreSQL database
  • โœ… Mature Ecosystem: Battle-tested PostgreSQL reliability
  • โœ… Easy Backup: Standard PostgreSQL backup tools

Database Migrations

# Run migrations
npm run migrate

# Fresh database setup (caution: drops all data)
npm run db:setup

See src/database/schema.sql for the complete database schema.

๐Ÿ“Š Performance

  • Vector Search: โ‰ค50ms p95 latency for typical queries
  • Document Processing: ~5 seconds for 10-page PDF
  • Concurrency: 5 workers processing documents in parallel
  • Rate Limiting: Configurable per-customer limits

๐Ÿณ Docker Containers

Service Container Port Description
Frontend dynamicrag-frontend 3000 React UI (nginx)
API dynamicrag-api 3001 Express server
Worker dynamicrag-worker - BullMQ worker
PostgreSQL dynamicrag-postgres 5432 Database + pgvector
Redis dynamicrag-redis 6379 Cache + Queue
MinIO dynamicrag-minio 9000, 9001 S3 storage

๐Ÿ”’ Security

  • Encryption at rest: AES-256-CBC for sensitive fields
  • JWT per customer: Unique signing secrets per tenant
  • Password hashing: bcrypt with configurable rounds
  • Email verification: Required before account activation
  • Rate limiting: Configurable per customer
  • CORS: Configurable allowed origins
  • SQL injection: Parameterized queries throughout

๐Ÿ“ Configuration

Key environment variables (see .env.example for full list):

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=rag_user
DB_PASSWORD=your_password
DB_NAME=dynamic_rag

# Encryption (REQUIRED)
ENCRYPTION_KEY=<64-char hex string>

# OpenAI
OPENAI_API_KEY=sk-...

# Storage
S3_ENDPOINT=http://minio:9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin123
S3_BUCKET=dynamic-rag-documents

# Email (optional)
SENDGRID_API_KEY=SG...
EMAIL_FROM=noreply@yourdomain.com

๐Ÿ› ๏ธ Troubleshooting

Common Issues and Solutions

1. Worker Container Keeps Restarting

Symptoms:

docker-compose ps worker
# Shows: Restarting or Exit 1

Solutions:

# Check worker logs for errors
docker-compose logs worker --tail=50

# Common cause: pdf-parse module issue
# Solution: Already fixed in Dockerfile with dummy file

# Rebuild worker container
docker-compose build worker --no-cache
docker-compose up -d worker

# Verify it's running
docker-compose ps worker

2. Database Connection Errors

Symptoms:

  • API logs show "ECONNREFUSED" or "database connection failed"

Solutions:

# Check PostgreSQL is running
docker-compose ps postgres

# Check database logs
docker-compose logs postgres --tail=50

# Test connection manually
docker-compose exec postgres psql -U rag_user -d dynamic_rag

# Reset database (caution: deletes all data)
docker-compose down -v
docker-compose up -d postgres
docker-compose exec api npm run db:setup

3. Email Verification Not Working

Symptoms:

  • Users not receiving verification emails
  • Email verification links not working

Solutions:

# Check SendGrid API key is set in .env
grep SENDGRID_API_KEY .env

# Check email logs
docker-compose logs api | grep -i "email"

# Check email verification settings
grep EMAIL_ .env

# Verify EMAIL_VERIFICATION_URL matches your API URL
# Verify FRONTEND_URL matches your frontend URL

# Test without email (check database directly)
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "UPDATE customers SET status = 'active' WHERE email = 'user@example.com';"

4. Document Upload Fails

Symptoms:

  • Upload returns error
  • Documents stuck in "queued" status
  • S3/MinIO errors

Solutions:

# Check MinIO is running
curl http://localhost:9000/minio/health/live

# Check MinIO credentials in .env
grep S3_ .env

# Check worker is processing jobs
docker-compose logs worker --tail=50

# Check Redis is running (needed for job queue)
docker-compose ps redis

# Manually check MinIO
# Visit http://localhost:9001 (minioadmin/minioadmin123)

# Check document status in database
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "SELECT id, title, status, error_message FROM documents ORDER BY created_at DESC LIMIT 10;"

# Retry failed documents
docker-compose restart worker

5. Frontend Can't Connect to API

Symptoms:

  • Frontend shows "Network Error"
  • CORS errors in browser console

Solutions:

# Check VITE_API_URL in frontend/.env
cat frontend/.env

# Should be: VITE_API_URL=http://localhost:3001

# Check CORS settings in backend .env
grep ALLOWED_ORIGINS .env

# Should include: http://localhost:3000

# Check API is accessible
curl http://localhost:3001/health

# Restart services
docker-compose restart api frontend

6. Documents Not Searchable

Symptoms:

  • Search returns no results
  • pgvector errors

Solutions:

# Check if embeddings were created
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "SELECT id, title, status, chunk_count FROM documents WHERE customer_id = '<customer-id>';"

# Check if chunks exist in pgvector tables
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "SELECT COUNT(*) FROM document_chunks WHERE customer_id = '<customer-id>';"

# Check pgvector extension is installed
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "SELECT * FROM pg_extension WHERE extname = 'vector';"

# Check worker processed the document
docker-compose logs worker | grep -i "embedding"

# Verify OpenAI API key is set
# Either in .env or customer profile

# Reprocess a document (delete and re-upload)

7. Authentication Token Errors

Symptoms:

  • "Unauthorized" errors
  • "Invalid token" errors
  • Token expired too quickly

Solutions:

# Check ENCRYPTION_KEY is set in .env
grep ENCRYPTION_KEY .env

# Must be 64-character hex string
# Generate new one: openssl rand -hex 32

# Check JWT expiration settings
grep JWT_ .env

# Clear browser localStorage and login again
# In browser console: localStorage.clear()

# Check customer JWT secret exists
docker-compose exec postgres psql -U rag_user -d dynamic_rag \
  -c "SELECT id, email, jwt_secret IS NOT NULL as has_secret FROM customers;"

8. Rate Limiting Issues

Symptoms:

  • "Rate limit exceeded" errors
  • Too many requests errors

Solutions:

# Check Redis is running (rate limiter uses Redis)
docker-compose ps redis

# Check rate limit configuration in .env
grep RATE_LIMIT .env

# Flush Redis (resets all rate limits)
docker-compose exec redis redis-cli FLUSHALL

# Or restart Redis
docker-compose restart redis

9. High Memory Usage

Symptoms:

  • Services running slow
  • Out of memory errors

Solutions:

# Check Docker resource usage
docker stats

# Limit worker concurrency (in worker code)
# Reduce BullMQ concurrency setting

# Add memory limits to docker-compose.yml
# services:
#   worker:
#     mem_limit: 2g

# Restart services
docker-compose restart

10. Build Errors

Symptoms:

  • Docker build fails
  • npm install errors

Solutions:

# Clear Docker cache and rebuild
docker-compose build --no-cache

# Clear npm cache
npm cache clean --force
cd frontend && npm cache clean --force

# Remove node_modules and reinstall
rm -rf node_modules frontend/node_modules
npm install
cd frontend && npm install

# Check Node.js version
node --version  # Should be 18+

Debug Mode

Enable verbose logging:

# Set LOG_LEVEL=debug in .env
echo "LOG_LEVEL=debug" >> .env

# Restart services
docker-compose restart api worker

# View detailed logs
docker-compose logs -f api worker

Complete Reset

Start fresh (deletes all data):

# Stop all services
docker-compose down

# Remove all volumes (โš ๏ธ DELETES ALL DATA)
docker-compose down -v

# Remove all images
docker-compose down --rmi all

# Clean up Docker system
docker system prune -a --volumes

# Start fresh
docker-compose up -d --build

# Initialize database
docker-compose exec api npm run db:setup

Getting Help

If you're still experiencing issues:

  1. Check logs: docker-compose logs -f
  2. Check documentation: See /docs folder
  3. Search issues: GitHub Issues
  4. Create issue: Include logs, error messages, and steps to reproduce
  5. Ask community: GitHub Discussions

๐Ÿ“– Documentation

๐Ÿ—บ๏ธ Roadmap

Current Status: โœ… Production Ready

The Dynamic RAG system is production-ready with core features fully implemented.

Completed Features โœ…

Phase 1: Foundation

  • โœ… Multi-tenant architecture with customer isolation
  • โœ… Authentication with email verification
  • โœ… JWT with per-customer secrets
  • โœ… Document upload and processing pipeline
  • โœ… PostgreSQL with pgvector extension integration
  • โœ… OpenAI embeddings with customer API keys
  • โœ… React frontend with beautiful UI

Phase 2: Document Processing

  • โœ… PDF, TXT, HTML, Markdown support
  • โœ… Async processing with BullMQ workers
  • โœ… MinIO/S3 document storage
  • โœ… Intelligent chunking algorithm
  • โœ… Usage tracking and cost metrics
  • โœ… Error handling and retry logic

Phase 3: Search & Reranking

  • โœ… Vector semantic search
  • โœ… Multiple search strategies (chunks, broad chunks, catalog)
  • โœ… RRF (Reciprocal Rank Fusion) reranking
  • โœ… MCP protocol integration for Claude Desktop
  • โœ… Search quality optimization

In Progress ๐Ÿšง

Phase 3: Production Ready

  • ๐Ÿšง ML cross-encoder reranking with transformers.js
  • ๐Ÿšง Enhanced monitoring and metrics dashboards
  • ๐Ÿšง Performance benchmarking and optimization
  • ๐Ÿšง Comprehensive documentation updates

Planned Features ๐Ÿ“…

Near Term (Next 2-4 weeks)

OAuth Integration

  • ๐Ÿ”œ Google OAuth signup/login
  • ๐Ÿ”œ Microsoft OAuth integration
  • ๐Ÿ”œ GitHub OAuth integration
  • ๐Ÿ”œ Social account linking

Bulk Operations

  • ๐Ÿ”œ Bulk document upload
  • ๐Ÿ”œ Bulk document deletion
  • ๐Ÿ”œ Bulk metadata updates
  • ๐Ÿ”œ Batch processing optimizations

Enhanced Error Handling

  • ๐Ÿ”œ Specific error codes for all errors
  • ๐Ÿ”œ Error code documentation
  • ๐Ÿ”œ User-friendly error messages
  • ๐Ÿ”œ Troubleshooting guides

Multi-Model Support

  • ๐Ÿ”œ Multiple embedding models (Cohere, HuggingFace, etc.)
  • ๐Ÿ”œ Multiple LLM providers (Anthropic, Google, etc.)
  • ๐Ÿ”œ Per-customer model selection
  • ๐Ÿ”œ Model performance comparison

Backend Enhancements

  • ๐Ÿ”œ Use customer's OpenAI keys for all operations
  • ๐Ÿ”œ API key rotation support
  • ๐Ÿ”œ Usage quota enforcement
  • ๐Ÿ”œ Cost alerts and limits

Documentation

  • โœ… Completed! - Comprehensive README update
  • ๐Ÿ”œ API documentation with examples
  • ๐Ÿ”œ Architecture decision records (ADRs)
  • ๐Ÿ”œ Video tutorials

Phase 4: Deployment

  • ๐Ÿ”œ Production deployment guide
  • ๐Ÿ”œ Kubernetes manifests
  • ๐Ÿ”œ Monitoring and alerting setup
  • ๐Ÿ”œ Backup and disaster recovery

Future Enhancements ๐Ÿ”ฎ

Advanced Features

  • Multi-factor authentication (MFA/2FA)
  • Webhook notifications
  • Document versioning
  • Collaborative workspaces
  • Advanced analytics dashboard
  • Custom embedding models
  • Fine-tuned reranking models

Enterprise Features

  • SSO/SAML integration
  • Advanced RBAC (Role-Based Access Control)
  • Audit logging
  • Compliance reporting (SOC2, GDPR)
  • White-label customization
  • On-premise deployment options

Performance Improvements

  • Caching layer optimization
  • CDN integration for document delivery
  • Query result caching
  • Streaming responses
  • GraphQL API option

Developer Experience

  • SDKs (Python, JavaScript, Go)
  • CLI tool for document management
  • Terraform modules
  • Helm charts
  • API webhooks
  • GraphQL playground

Community Requested Features

Have a feature request?

Release Schedule

  • v1.0.0 - โœ… Current (Production Ready)
  • v1.1.0 - OAuth & Bulk Operations (Est. March 2026)
  • v1.2.0 - Multi-Model Support (Est. April 2026)
  • v2.0.0 - Enterprise Features (Est. Q3 2026)

๐Ÿค Contributing

We welcome contributions from the community! Whether it's bug fixes, new features, documentation improvements, or examples, your help is appreciated.

How to Contribute

  1. Fork the repository

    git clone https://github.com/prk2007/dynamic-rag.git
    cd dynamic-rag
    git checkout -b feature/your-feature-name
  2. Make your changes

    • Follow the existing code style
    • Add tests for new features
    • Update documentation as needed
  3. Test your changes

    # Run the application
    docker-compose up -d
    
    # Test your changes thoroughly
    # Add test cases if applicable
  4. Commit your changes

    git add .
    git commit -m "feat: Add your feature description"
  5. Push and create a Pull Request

    git push origin feature/your-feature-name
    # Then create a PR on GitHub

Development Guidelines

Code Style:

  • โœ… Use TypeScript for all new code
  • โœ… Follow existing code formatting and structure
  • โœ… Use async/await instead of callbacks
  • โœ… Add JSDoc comments for public APIs
  • โœ… Keep functions small and focused

Security:

  • โœ… Always use parameterized SQL queries
  • โœ… Maintain multi-tenant isolation (customer_id filtering)
  • โœ… Never log sensitive data (passwords, API keys)
  • โœ… Validate and sanitize all user inputs
  • โœ… Use encryption for sensitive fields

Architecture:

  • โœ… Follow the existing folder structure
  • โœ… Keep routes thin, logic in services
  • โœ… Use middleware for cross-cutting concerns
  • โœ… Handle errors gracefully with proper messages

Documentation:

  • โœ… Update README.md for new features
  • โœ… Add inline comments for complex logic
  • โœ… Update API documentation
  • โœ… Add examples for new features

Commit Message Format

We use conventional commits for clear git history:

feat: Add new feature
fix: Fix bug in component
docs: Update documentation
style: Format code
refactor: Refactor without changing behavior
test: Add or update tests
chore: Update dependencies or config

Areas We Need Help With

  • ๐Ÿ› Bug Fixes: Find and fix bugs
  • โœจ Features: Implement items from the roadmap
  • ๐Ÿ“š Documentation: Improve guides and examples
  • ๐Ÿงช Testing: Add unit and integration tests
  • ๐ŸŒ i18n: Add internationalization support
  • ๐ŸŽจ UI/UX: Improve frontend design
  • โšก Performance: Optimize slow queries or code

Questions?

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

What This Means

โœ… You can:

  • Use this software commercially
  • Modify the source code
  • Distribute the software
  • Use it privately

โŒ You cannot:

  • Hold the authors liable
  • Use the authors' names for endorsement

๐Ÿ“‹ You must:

  • Include the license and copyright notice
  • State changes made to the code

๐Ÿ™ Acknowledgments

This project is built on the shoulders of giants:

Core Technologies:

  • PostgreSQL - Powerful open-source database
  • pgvector - Vector similarity search for PostgreSQL
  • OpenAI - Embeddings and AI models
  • React - UI framework
  • Express - Web framework
  • BullMQ - Job queue system
  • MinIO - High-performance object storage

Inspiration:

Special Thanks:

  • The open-source community
  • All contributors to this project
  • Users who report bugs and suggest features

๐Ÿ“ž Support

Getting Help

Documentation:

Community Support:

Professional Support:

Reporting Issues

When reporting issues, please include:

  1. Environment details

    • OS and version
    • Docker version
    • Node.js version
  2. Steps to reproduce

    • What you did
    • What you expected
    • What actually happened
  3. Logs and errors

    docker-compose logs api worker
  4. Configuration (remove sensitive data)

    • Relevant .env settings
    • docker-compose.yml modifications

Security Issues

๐Ÿ”’ Do not report security vulnerabilities in public issues!

Instead:


โญ Star History

If you find this project useful, please consider giving it a star! โญ

Star History Chart