Skip to main content
All Projects
COMPLETED

NexusNote

Workspace-based knowledge management platform with a RAG-powered AI assistant for students and knowledge workers

NexusNote screenshot 1

Role

Full Stack Developer

Team

Solo

Stack
TypeScriptNext.jsReactFastAPIPythonPostgreSQLpgvectorGoogle GeminiCloudinaryTipTapTailwind CSSshadcn/uiTurborepoTanStack Query
Challenges
  • Strict workspace-scoped RAG with no cross-workspace vector leakage
  • SSE-based embedding job status streaming from FastAPI BackgroundTasks
  • TipTap Markdown serialization with debounced auto-save and no edit overwrite on re-render
  • Atomic resource deletion cascading pgvector chunks and Cloudinary assets
  • Google OAuth token delivery to Next.js SPA without CORS issues
Insights
  • pgvector similarity search with workspace-scoped WHERE filtering
  • FastAPI BackgroundTasks driving an async embedding pipeline with SSE status
  • TanStack Query v5 global 401 handler and optimistic UI updates
  • Turborepo monorepo coordinating a Next.js frontend and FastAPI backend
  • RAG context assembly strictly from per-workspace document chunks — never raw content fields

Overview

NexusNote is a full-stack knowledge management and AI assistant platform. Users organise their research into isolated workspaces — each containing text notes, uploaded PDFs, and scraped web links. A RAG-powered AI assistant within each workspace answers queries grounded strictly in that workspace's indexed content, with no cross-workspace leakage.

The application is structured as a Turborepo monorepo with a Next.js 14 (App Router) frontend, a fully async FastAPI backend, and a shared TypeScript types package. All AI features are powered by Google Gemini — gemini-2.0-flash for chat completions and text-embedding-004 for vector generation.


Key Features

Workspaces

  • Create, rename, and delete workspaces (max 5 per user).
  • Workspace switcher in the top navbar with instant context switching.
  • Default to most recently used workspace on every login.

Knowledge Sources

  • Notes: TipTap rich-text editor with Markdown persistence. Debounced auto-save (1.5 s). Per-note "Create Embedding" to index content into pgvector.
  • PDFs: Drag-and-drop upload → stored on Cloudinary → text extracted server-side with pypdf. In-app PDF viewer via Cloudinary URL. Per-PDF embedding with cascade deletion of vectors and Cloudinary asset on remove.
  • Links: Paste a URL → server scrapes and stores extracted text (httpx + BeautifulSoup). Per-link embedding with vector deletion on remove.

Embedding Pipeline

  • FastAPI BackgroundTasks drives an async embedding worker per resource.
  • Text chunked → embedded via Gemini text-embedding-004 → vectors upserted into Neon PostgreSQL with pgvector.
  • Every chunk row carries workspace_id + resource_id + resource_type for scoped retrieval and targeted deletion.
  • Job status (pending → processing → done / error) streamed to the frontend via an SSE endpoint.

AI Assistant

  • Dedicated chat page per workspace with multiple named, persistent sessions.
  • RAG retrieval: top-k vector similarity search filtered strictly by workspace_id — no cross-workspace exposure.
  • LLM: gemini-2.0-flash assembles responses grounded in retrieved document chunks.
  • Optimistic message UI with scroll-to-bottom, typing indicator, and full chat history persistence.

Auth & Security

  • Email/password signup with JWT session management (FastAPI + python-jose).
  • Google OAuth 2.0 — token delivered to the SPA via URL fragment (/dashboard#accessToken=...) to avoid CORS issues with cross-origin cookie delivery.
  • Every route handler verifies resource.user_id == current_user.id; all RAG queries include a hard WHERE workspace_id = :workspace_id guard.

Design

  • Dual dark / light theme toggled by the user — default dark.
  • Design language: premium technical workspace — clean geometry, generous whitespace, subtle surface layering, single violet accent (#6e6bff).
  • Inter for UI, JetBrains Mono for code. All color values through CSS custom properties — no hardcoded hex.
  • Custom landing page aesthetic: Modern Playfulism — Cyprus + Sand palette, glassmorphism nav, claymorphism hero orb, bento grid features section, mesh gradient blobs.
  • Component library: shadcn/ui on Tailwind CSS. No external icon libraries — Lucide React (stroke only).

Architecture

NexusNote is a Turborepo monorepo with two apps:

  • apps/web: Next.js 14 (App Router), TypeScript strict, Tailwind CSS, shadcn/ui, TipTap, TanStack Query v5.
  • apps/api: FastAPI (Python, fully async), SQLModel (SQLAlchemy + Pydantic v2), Alembic migrations.

Embedding Job Flow

POST /embeddings/{resource_type}/{resource_id}
  → BackgroundTask enqueued
  → embedding_job row created (status = pending)
  → job_id returned to client

GET /embeddings/status/{job_id}  [SSE stream]
  → worker updates status: pending → processing → done | error
  → SSE handler polls DB row, emits events
  → frontend closes stream on done/error, updates UI

RAG Query Flow

user sends message
  → top-k vector search on document_chunks WHERE workspace_id = :id
  → retrieved chunks assembled as context
  → Gemini 2.0 Flash generates grounded response
  → assistant message persisted to chat_messages
  → response streamed back to client

Auth Token Flow

Access token stored in localStorage. On app mount, AuthProvider restores the token to axios headers and calls /session to validate. Google OAuth redirects to /dashboard#accessToken=... — fragment approach avoids CORS issues with cross-origin cookie delivery to the SPA.


Data Model

Five PostgreSQL tables plus pgvector:

  • users — email, hashed password, google_id.
  • workspaces — owned by a single user; max 5 enforced at API layer.
  • notes / pdfs / links — workspace-scoped content with extracted text fields.
  • embedding_jobs — tracks pipeline status per resource.
  • chat_sessions / chat_messages — persistent conversation history per workspace.
  • document_chunks — single source of truth for all vectors: chunk_index, content, embedding vector(768), workspace_id, resource_type, resource_id. No vectors stored anywhere else.

Outcome

NexusNote demonstrates a production-grade RAG knowledge system — combining workspace-isolated vector search, a streaming embedding pipeline, and a persistent AI chat layer across a Turborepo monorepo. Every feature from auth to typing indicators is wired to a real backend with strict workspace isolation enforced at both the query layer and the API boundary.