← All work
Case study · 2025

BrainBoost AI Tutor

An AI study platform: chat with past exam papers via RAG, turn a syllabus PDF into a roadmap, solve handwritten problems, and a CBT-style support chat.

Next.jsTypeScriptFirebaseLangChainPineconeOpenAIGeminiRazorpayCloudinaryLive site ↗Source ↗
aitutor-gilt.vercel.app
BrainBoost AI Tutor — screenshot of the live site

Overview

BrainBoost is a Next.js study platform that bundles several AI tools a student actually reaches for during exam prep. The core pieces are a retrieval-augmented chat over previous-year question papers, a syllabus-to-roadmap generator, a canvas that reads handwritten maths and solves it, and a mental-health section with a CBT assistant, mood tracker and journal. Usage is metered with tokens that students buy through Razorpay.

The problem

Students preparing for university exams juggle PDFs of old papers, a syllabus that is just a list of headings, and general-purpose chatbots that answer confidently without grounding in their actual course. I wanted answers tied to the specific paper being studied, a structured plan derived from the real syllabus, and a low-friction way to ask about a problem written by hand.

What I built

  • A PDF ingestion route (/api/process-pdf) that fetches an admin-uploaded paper from Cloudinary, extracts text with pdf-parse, splits it into 1000-character chunks with 200 overlap, embeds them with OpenAI text-embedding-3-small, and upserts them into Pinecone tagged with pdfId. Processing status and errors are written back to the pyqPdfs Firestore document.
  • A chat-with-PDF route that builds a LangChain RetrievalQAChain over Pinecone, filtered to the selected pdfId with k = 5, and a prompt that answers from the paper first and must say when it falls back to outside knowledge. It returns source snippets alongside the answer.
  • A syllabus roadmap pipeline: upload a PDF, store its text on a roadmaps document, then have Gemini extract the course metadata and an ordered list of topics with key points and search queries for videos and articles. Progress is tracked per topic.
  • Image and drawing solvers that send a base64 PNG to Gemini, ask for a JSON object with the transcribed text and a step-by-step solution, and validate that both fields exist before returning.
  • A mental-health area with a Gemini chat that keeps conversation history, plus CBT techniques, a thought diary, a guided journal and a mood tracker.
  • Token purchases through Razorpay: a server route creates the order, and a verify route recomputes the HMAC-SHA256 signature over order_id|payment_id before incrementing the user's token balance with the Firebase Admin SDK.

Screens

Landing page Feature overview: AI tutors, PYQs, PDF uploads, multilingual support and token access Learning roadmap: upload a syllabus to generate a tracked study path

Architecture

All AI work runs in Next.js route handlers; Firestore holds app state, Pinecone holds paper embeddings, and two model providers split the work.

flowchart LR
  subgraph client["Client"]
    ui["Next.js pages - PYQ, roadmap, canvas, CBT"]
  end
  subgraph server["Next.js API routes"]
    ingest["process-pdf"]
    rag["chat-with-pdf"]
    road["roadmap routes"]
    solve["solve-image and solve-drawing"]
    mh["mental-health-chat"]
    pay["razorpay create and verify"]
  end
  subgraph data["Data"]
    fs[("Firestore")]
    pc[("Pinecone index")]
    cdn[("Cloudinary PDFs")]
  end
  subgraph ext["External AI and payments"]
    oai["OpenAI embeddings and chat"]
    gem["Gemini"]
    rzp["Razorpay"]
  end
  ui --> ingest
  ui --> rag
  ui --> road
  ui --> solve
  ui --> mh
  ui --> pay
  ingest --> cdn
  ingest --> oai
  ingest --> pc
  rag --> pc
  rag --> oai
  road --> gem
  solve --> gem
  mh --> gem
  pay --> rzp
  ingest --> fs
  road --> fs
  pay --> fs

System design

The RAG path has two phases: a one-time ingestion when an admin uploads a paper, then retrieval scoped to that paper on every question.

sequenceDiagram
  participant A as Admin
  participant S as Student
  participant API as Next.js API
  participant C as Cloudinary
  participant O as OpenAI
  participant P as Pinecone
  participant F as Firestore
  A->>C: Upload PYQ PDF
  A->>API: POST process-pdf with pdfId and fileUrl
  API->>C: Fetch PDF bytes
  API->>API: pdf-parse then split 1000 by 200 overlap
  API->>O: Embed chunks
  API->>P: Upsert vectors tagged with pdfId
  API->>F: Mark contentProcessed true
  S->>API: POST chat-with-pdf with question and pdfId
  API->>P: Top 5 chunks filtered by pdfId
  P-->>API: Matching chunks
  API->>O: Stuff chunks into QA prompt
  O-->>API: Answer
  API-->>S: Answer plus source snippets

Decisions & trade-offs

  • OpenAI for embeddings and the PDF QA chain, Gemini for everything multimodal or long-form. Gemini handles images and long syllabus text well; keeping embeddings on one stable OpenAI model avoids re-indexing Pinecone.
  • One shared Pinecone index with a pdfId metadata filter instead of a namespace per paper. Simpler to operate, but every query depends on the filter being correct.
  • A "stuff" chain over five chunks rather than map-reduce or refine. It is one LLM call and cheap, at the cost of missing context when an answer spans many pages.
  • Payment verification is server-side only and credits tokens with an atomic Firestore increment, so a client cannot mint tokens by faking a success callback.

What I'd do next

  • Move the Gemini key off NEXT_PUBLIC_ so it never ships in the client bundle, and check token balance server-side on each AI route.
  • Record each verified payment in a transactions collection and make verification idempotent per order ID.
  • Add page numbers to chunk metadata so answers can cite the exact page of the paper.