Upload. Analyze. Understand.
Transform your documents into actionable insights with cutting-edge AI
A production-ready, multi-tenant SaaS built with Next.js 16, featuring hybrid RAG chat, real-time processing, and a gorgeous glassmorphic UI
DocuMind is a full-stack AI document intelligence platform that lets users upload PDFs, Word documents, and PowerPoint files β then chat with them using sophisticated RAG (Retrieval-Augmented Generation). It intelligently chunks documents, indexes them using hybrid search (BM25 + Trigram), and retrieves precise context to generate grounded AI answers.
Not a toy project. DocuMind is a fully deployed, multi-tenant SaaS with authentication, real-time updates, persistent chat history, project organization, storage management, Stripe billing, and a pixel-perfect responsive UI.
|
|
|
|
|
|
graph TD
subgraph Frontend ["FRONTEND (Next.js 16)"]
Landing[Landing Page]
Dash[Dashboard Client]
DocView[Document View]
Chat[Chat Panel]
end
subgraph API ["API LAYER (Route Handlers)"]
ChatAPI["/api/chat (Hybrid Search)"]
CheckoutAPI["/api/checkout"]
SuggestAPI["/api/suggest"]
InngestAPI["/api/inngest"]
end
subgraph BG ["Inngest"]
Ingest["Document Ingestion"]
Chunk["Text Chunking"]
Summarize["AI Summarization"]
end
subgraph DB ["DATA & SERVICES"]
Supabase[("Supabase (PostgreSQL + Storage)")]
Clerk{"Clerk Auth"}
Groq(("Groq\n(Llama 3.3 70B)"))
end
Landing & Dash & DocView & Chat --> API
InngestAPI --> BG
BG --> Supabase & Groq
API --> Supabase & Clerk & Groq
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16 (App Router) | Full-stack React with RSC & Server Actions |
| Language | TypeScript | End-to-end type safety |
| Styling | Tailwind CSS 4 + CSS Animations | Responsive design + fluid animations |
| UI Library | shadcn/ui + Radix UI | Accessible, composable components |
| Auth | Clerk | OAuth, email auth, session management |
| Database | Supabase (PostgreSQL) | Documents, chunks, chat history, real-time |
| Storage | Supabase Storage | File uploads with per-user buckets |
| AI / LLM | Groq (Llama 3.3 70B) | Blazing-fast chat inference (free tier) |
| Search | Hybrid (BM25 + Trigram RRF) | Keyword + fuzzy matching via Supabase RPC |
| Background Jobs | Inngest | Durable document processing pipeline |
| Payments | Stripe | Subscription billing & webhooks |
| File Parsing | pdf-parse, Mammoth, JSZip | PDF, DOCX, PPTX (per-slide) extraction |
| Deployment | Vercel | Edge-optimized hosting |
- Node.js 18+ and npm
- Supabase project (free tier)
- Clerk application (free tier)
- Groq API key (free tier)
git clone https://github.com/your-username/DOCU_MIND.git
cd DOCU_MIND/docu-mind
npm installCreate a .env.local file with the following variables:
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# AI
GROQ_API_KEY=gsk_...
# Stripe (optional)
STRIPE_SECRET_KEY=sk_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_...
STRIPE_WEBHOOK_SECRET=whsec_...Run the SQL migrations in your Supabase SQL editor:
-- Enable Extensions
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Documents table
CREATE TABLE documents (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id TEXT NOT NULL,
file_name TEXT NOT NULL,
file_type TEXT,
file_size BIGINT NOT NULL DEFAULT 0,
file_url TEXT,
status TEXT NOT NULL DEFAULT 'queued',
summary TEXT,
is_starred BOOLEAN NOT NULL DEFAULT FALSE,
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
project_id UUID REFERENCES projects(id),
last_opened_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
page_count INTEGER
);
-- Document chunks for Search
CREATE TABLE document_chunks (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
document_id UUID REFERENCES documents(id) ON DELETE CASCADE,
user_id TEXT NOT NULL,
content TEXT NOT NULL,
page_number INTEGER,
chunk_index INTEGER NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
fts tsvector GENERATED ALWAYS AS (to_tsvector('english', coalesce(content, ''))) STORED
);
CREATE INDEX idx_chunks_fts ON document_chunks USING GIN (fts);
CREATE INDEX idx_chunks_trgm ON document_chunks USING GIN (content gin_trgm_ops);
-- Chat messages
CREATE TABLE chat_messages (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
document_id UUID REFERENCES documents(id) ON DELETE CASCADE,
user_id TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
content TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Projects
CREATE TABLE projects (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Hybrid Search Function (BM25 + Trigram RRF)
CREATE OR REPLACE FUNCTION hybrid_search_chunks(
query_text TEXT,
target_doc_id UUID,
target_user_id TEXT,
match_count INT DEFAULT 10,
bm25_weight FLOAT DEFAULT 1.0,
trigram_weight FLOAT DEFAULT 0.5
) RETURNS TABLE (
id UUID,
content TEXT,
chunk_index INT,
page_number INT,
bm25_score FLOAT,
trigram_score FLOAT,
combined_score FLOAT
) LANGUAGE plpgsql AS $$
-- Implementation details in supabase/phase5_hybrid_search.sql
$$;
-- Enable Realtime
ALTER PUBLICATION supabase_realtime ADD TABLE documents;npm run devOpen http://localhost:3000 β you're ready to go! π
docu-mind/
βββ src/
β βββ app/
β β βββ (auth)/ # Sign-in / Sign-up pages (Clerk)
β β βββ api/
β β β βββ chat/ # RAG chat endpoint
β β β βββ checkout/ # Stripe checkout session
β β β βββ suggest/ # AI question suggestions
β β β βββ webhooks/ # Stripe webhook handler
β β βββ dashboard/
β β β βββ document/[docId] # Document viewer + chat
β β β βββ documents/ # All documents page
β β β βββ chat-history/ # Chat history page
β β β βββ plans/ # Pricing plans
β β βββ page.tsx # Landing page
β β βββ layout.tsx # Root layout (Clerk + Theme)
β β βββ globals.css # Design system tokens
β βββ components/
β β βββ chat/ # ChatPanel, ChatMessage
β β βββ ui/ # shadcn/ui primitives
β β βββ DocumentCard.tsx # Document grid/list card
β β βββ DocumentViewer.tsx # PDF/file viewer
β β βββ DragDropZone.tsx # Upload with drag & drop
β β βββ Header.tsx # Top navigation bar
β β βββ Sidebar.tsx # Collapsible sidebar
β β βββ SortFilterBar.tsx # Sort & filter controls
β β βββ SettingsView.tsx # User settings page
β β βββ ThemeToggle.tsx # Dark/light mode switch
β βββ lib/
β β βββ actions/ # Server actions
β β β βββ ingest.ts # File parsing + chunking
β β β βββ documents.ts # CRUD operations
β β β βββ chat.ts # Chat history management
β β β βββ summarize.ts # AI summarization
β β βββ supabase.ts # Supabase admin client
β β βββ supabase-browser.ts # Supabase browser client
β β βββ utils/ # Helpers (fileTypes, time)
β βββ hooks/ # Custom React hooks
β βββ types/ # TypeScript definitions
βββ supabase/ # Database migrations
βββ public/ # Static assets
βββ package.json
sequenceDiagram
participant U as User
participant F as Frontend
participant A as /api/chat
participant S as Supabase
participant L as Groq LLM
U->>F: Types question
F->>A: POST { messages, docId }
A->>S: hybrid_search_chunks(query_text, docId)
S-->>A: Top matches (BM25 + Trigram Fusion)
A->>L: System prompt + doc overview + chunks + question
L-->>A: AI-generated answer
A->>S: Save chat message
A-->>F: JSON response
F-->>U: Display answer
DocuMind follows a premium glassmorphic design language with these principles:
- π Dual Themes β Full dark mode and light mode with seamless transitions
- β¨ CSS Animations β Staggered entrance effects, glow pulses, and smooth transitions
- π± Mobile-First β Tab-based layouts on mobile, split-pane on desktop, touch-optimized hit targets
- π Glassmorphism β Backdrop blur, translucent surfaces, and layered depth
- β‘ Optimistic UI β Instant feedback with background sync for star, archive, and rename actions
This project is open-source under the MIT License.
Built with β€οΈ using Next.js
If you found this helpful, consider giving it a β