Document Chatbot Platform
Next.js
React
TypeScript
Tailwind CSS
Supabase
PostgreSQL
Deno
- pgvector
An MVP of a multi-tenant web app I built for creating chatbots that answer questions using uploaded documents.
Users can organize documents into collections, choose which collections each chatbot can access, and use the chatbot through an embeddable website widget or a separate API.
The app uses retrieval-augmented generation (RAG). Instead of sending all documents to the language model, it searches for the most relevant sections and adds them as context before generating an answer.
How it works
-
Uploaded documents are stored in Supabase Storage and added to a processing queue.
-
Supabase Edge Functions, written in TypeScript and running on Deno, read the files and split them into smaller chunks of maximum 512 tokens.
-
Each chunk is passed through the gte-small embedding model. The resulting 384-dimensional vectors are stored together with the original text in PostgreSQL using pgvector.
-
When a user asks a question, the question is embedded using the same model. PostgreSQL then performs a vector similarity search across the collections assigned to that chatbot and returns up to 5 relevant chunks.
-
The retrieved chunks are combined with the chatbot's instructions and conversation history, then sent to the selected LLM through OpenRouter.
-
The response is streamed back and displayed to the user.
Project overview
Users manage everything from the dashboard, where they can create projects, organize documents into collections, configure chatbots, change their appearance and instructions, and see basic usage and processing status.
Because the platform is multi-tenant, each project's data and uploaded files are kept separate using Supabase Auth and PostgreSQL Row-Level Security (RLS).
Document processing runs in the background through separate ingestion and embedding queues using pgmq. When new documents are queued, PostgREST is used to trigger the ingestion Edge Function. A pg_cron job also checks the queue periodically, so anything left unprocessed can be picked up again.
Billing and subscription plans are handled through Polar.
Tech Stack
- Frontend: Next.js, React, TypeScript, Tailwind CSS + shadcn/ui
- Backend: Supabase
- Database: PostgreSQL, pgvector
- Billing: Polar