Skip to main content
←Back to work

IntelliPDF — RAG-Powered PDF Chat Platform

Full-stack RAG app for chatting with PDFs — async indexing, streamed cited answers, and a transactional outbox for reliable job hand-off.

Role
Full-stack architecture and implementation
Scope
Asynchronous document indexing with cited, streamed answers
Core stack
React 19 · TypeScript · Vite · Node.js

Project showcase

Selected screens from the shipped product and its core workflows.

System flow

From request to reliable result.

Two paths explain the system: durable ingestion and source-grounded answer streaming.

A durable background pipeline separates the upload request from parsing, embedding, and vector storage.

  1. 01

    Upload

    The API validates and records the PDF.

  2. 02

    Outbox

    PostgreSQL commits the job hand-off atomically.

  3. 03

    BullMQ

    A Redis-backed worker claims retry-safe work.

  4. 04

    Parse + embed

    Chunks become Gemini vector embeddings.

  5. 05

    Qdrant

    Deterministic point IDs prevent duplicates.

  6. 06

    Live progress

    Socket.IO reports each indexing state.

What the project delivers

IntelliPDF is a full-stack Retrieval-Augmented Generation (RAG) application that lets users upload PDFs and chat with their contents, with cited source passages behind every answer. Documents are indexed asynchronously via a Redis-backed BullMQ worker, progressing through queued, processing, embedding, and indexing stages, with live progress broadcast to the client over Socket.IO.

The backend is organized into feature modules (auth, pdf-chat, users, audit) built with Node.js, Express 5, TypeScript, and Prisma, wired through a small composition root for dependency injection. PDFs are parsed and split with LangChain, embedded using Google Gemini embeddings, and stored as vectors in Qdrant, with retrieval scoped per document and filtered by similarity score.

Follow-up questions are rewritten into standalone queries before retrieval, and answers stream to the client over Server-Sent Events from a Groq-hosted LLM, with citations sent ahead of the response text. The system includes a transactional outbox pattern for reliable hand-off between PostgreSQL and BullMQ, compare-and-swap refresh-token rotation, deterministic Qdrant point IDs to prevent duplicate vectors on retry, and guarded deletion flows.

Authentication supports both email/password and Google OAuth, with JWT access tokens, HTTP-only refresh cookies, and role-based access control for admin and manager routes.

Engineering implementation

  • PDF upload with real-time indexing progress via Socket.IO
  • Background indexing pipeline: parsing, chunking, embedding, and vector storage
  • RAG-based chat with conversation-aware, standalone-question retrieval
  • Server-Sent Events streaming for chat responses with citations sent first
  • Transactional outbox pattern for reliable PostgreSQL-to-BullMQ hand-off
  • Deterministic Qdrant point IDs to prevent duplicate vectors on retry
  • Email/password and Google OAuth authentication
  • JWT access tokens with HTTP-only, rotated refresh-token sessions
  • Role-based access control (admin, manager) with audit log endpoints
  • Compare-and-swap refresh-token rotation to prevent concurrent reuse
  • Dockerized local development stack via Docker Compose

Product capabilities

  • Source snippet, page metadata, and similarity score display per answer

Tech Stack

  • React 19
  • TypeScript
  • Vite
  • Node.js
  • Express 5
  • Prisma
  • PostgreSQL
  • Redis
  • BullMQ
  • Qdrant
  • LangChain
  • Google Gemini
  • Groq
  • Socket.IO
  • Docker Compose
  • Tailwind CSS
  • TanStack Query
  • Zustand

Project links