# param20h/pdf-assistant-rag architecture

> Architecture diagram of the GitHub repository param20h/pdf-assistant-rag, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/param20h/pdf-assistant-rag
- Repository: https://github.com/param20h/pdf-assistant-rag

## Overview

1. This repo is a full-stack “document AI analyst” with a clear split between a FastAPI backend and a Next.js frontend. The backend owns authentication, document lifecycle, ingestion, retrieval, chat generation, and admin/health APIs; the frontend owns user interaction, document management, chat streaming UI, and PDF/graph viewing.

2. The backend is the system boundary for almost all business logic. `backend/app/main.py` wires the FastAPI app, middleware, routers, and lifespan hooks. The route layer is organized by domain: auth, documents, chat, workspaces, profile, admin, graph, health, and GitHub integration.

3. Persistent application state is stored in a relational database via SQLAlchemy models. PostgreSQL is the primary deployment target, with SQLite supported for local/dev. The database holds users, documents, sessions, roles, workspace membership, and ingestion/chat metadata; migrations in the repo show schema evolution for roles, processing columns, extracted URLs, and indexes.

4. Document ingestion is asynchronous and decoupled from request handling. Upload endpoints enqueue Celery jobs through Redis, and the ingestion service then extracts text, chunks content, generates embeddings, builds search indexes, and persists document status. This makes the upload path fast while heavy processing happens in the background.

5. The RAG pipeline is the core architecture. `backend/app/rag/` contains extraction, chunking, embeddings, vector storage, BM25 keyword indexing, hybrid retrieval, reranking, prompt assembly, summarization, OCR/vision helpers, URL extraction, and GraphRAG graph building. The retrieval path is explicitly multi-stage: vector search + BM25, merged with reciprocal rank fusion, then reranked before generation.

6. Vector and lexical search are separate storage/compute paths. ChromaDB stores embeddings, while BM25 indexes are maintained per document. Embeddings are generated locally with sentence-transformers and cached with Redis/LRU, so the system minimizes repeated compute and keeps semantic search local before anything is sent to an external LLM.

7. Answer generation is delegated to HuggingFace Inference API. The backend assembles retrieved context and calls the configured model for generation, then streams tokens back to the client over SSE. The frontend chat panel is built around this streaming contract, so response rendering is incremental rather than request/response only.

8. Per-user isolation is an architectural boundary, not just an authorization check. The system scopes documents, vectors, chats, and graph artifacts by user/workspace identity, and the auth layer uses JWT plus bcrypt. Rate limiting, CORS, password validation, and file validation are additional guardrails around the public API.

9. There is a second knowledge layer beyond plain RAG: graph extraction and graph retrieval. `graph_builder.py` and `graph_retriever.py` indicate entity/relationship extraction for document-specific knowledge graphs, and the README references GraphRAG evaluation. This means the system supports both chunk-based retrieval and graph-oriented context.

10. The frontend is a stateful client application built on Next.js App Router with TypeScript, Tailwind, and Zustand stores. It contains dedicated surfaces for login/register, dashboard, drive/document management, chat, settings, sharing, admin, and legal pages. Key UI components include a PDF viewer, knowledge graph view, source cards, and document sidebars.

11. The repo includes several integration surfaces beyond the main app. `bots/discord/bot.py` adds Discord connectivity, while `backend/app/routes/github.py` suggests GitHub-related workflows. These are adjacent services, but the main architecture still centers on the FastAPI core and shared backend state.

12. Observability and operational safety are first-class concerns. The backend exposes deep health checks for database, Redis, Celery, and ChromaDB, and also includes metrics and tracing modules. The repo ships Grafana dashboard assets, indicating the deployment expects runtime monitoring rather than just basic uptime checks.

13. Deployment is container-oriented. A multi-stage backend Dockerfile, a separate frontend Dockerfile, and `docker-compose.yml` support CPU, GPU, and debug profiles. This is important architecturally because the app is designed to run as a composed stack with database, Redis, worker, API, and frontend services.

14. Quality gates are spread across unit, integration, and browser testing. The backend has extensive pytest coverage for retrieval, ingestion, auth, chat, vector storage, OCR, and GraphRAG. The frontend adds Vitest and Playwright E2E/snapshot tests, so the repo’s architecture is validated at both API and UI boundaries.

Main entry points: [`backend/app/routes`](https://github.com/param20h/pdf-assistant-rag/tree/dev/backend/app/routes) (Routes), [`backend/app/database.py`](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/database.py) (Database), [`backend/app/routes/health.py`](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/health.py) (Health), [`backend/app/services/document_ingestion.py`](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/services/document_ingestion.py) (Ingestion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Backend"]
  node_backend_main["App entry<br/>FastAPI app<br/>[main.py]"]
  node_backend_routes["Routes<br/>API layer"]
  node_backend_auth["Auth<br/>JWT/bcrypt<br/>[auth.py]"]
  node_backend_documents["Documents<br/>doc lifecycle<br/>[documents.py]"]
  node_backend_chat["Chat<br/>streaming RAG<br/>[chat.py]"]
  node_backend_workspaces["Workspaces<br/>tenant scope<br/>[workspaces.py]"]
  node_backend_graph_api["Graph API<br/>knowledge graph<br/>[graph.py]"]
  node_backend_health["Health<br/>checks<br/>[health.py]"]
  node_backend_admin["Admin<br/>ops API<br/>[admin.py]"]
  node_backend_ingestion["Ingestion<br/>async pipeline"]
  node_backend_rag_retrieval["Retrieval<br/>hybrid RAG<br/>[retriever.py]"]
  node_backend_rag_generation["Generation<br/>prompt/LLM<br/>[prompts.py]"]
  node_backend_graph_rag["Graph RAG<br/>entity graph<br/>[graph_builder.py]"]
  node_backend_storage_db[("Database<br/>SQLAlchemy/PG<br/>[database.py]")]
  node_backend_storage_vector[("Vector store<br/>ChromaDB<br/>[vectorstore.py]")]
  node_backend_storage_cache[("Cache<br/>Redis/LRU<br/>[cache.py]")]
  node_backend_queue["Queue<br/>Celery/Redis<br/>[celery_app.py]"]
end

subgraph group_frontend["Frontend"]
  node_frontend_app["Next app<br/>App Router"]
  node_frontend_chat["Chat UI<br/>stream client"]
  node_frontend_documents["Docs UI<br/>document workspace"]
  node_frontend_graph["Graph view<br/>knowledge graph<br/>[KnowledgeGraph.tsx]"]
  node_frontend_state["State<br/>Zustand stores"]
  node_frontend_api["API client<br/>fetch layer<br/>[api.ts]"]
end

subgraph group_ops["Ops & Integrations"]
  node_integrations_bot["Discord bot<br/>integration<br/>[bot.py]"]
  node_ops_obs["Observability<br/>metrics/tracing<br/>[observability.py]"]
  node_ops_deploy["Deploy stack<br/>containers<br/>[docker-compose.yml]"]
end

node_frontend_app -->|"uses"| node_frontend_api
node_frontend_api -->|"requests"| node_backend_main
node_frontend_chat -->|"reads/writes"| node_frontend_state
node_frontend_documents -->|"reads/writes"| node_frontend_state
node_frontend_graph -->|"loads"| node_frontend_api
node_backend_main -->|"mounts"| node_backend_routes
node_backend_routes -->|"exposes"| node_backend_auth
node_backend_routes -->|"exposes"| node_backend_documents
node_backend_routes -->|"exposes"| node_backend_chat
node_backend_routes -->|"exposes"| node_backend_workspaces
node_backend_routes -->|"exposes"| node_backend_graph_api
node_backend_routes -->|"exposes"| node_backend_health
node_backend_routes -->|"exposes"| node_backend_admin
node_backend_documents -->|"enqueues"| node_backend_queue
node_backend_queue -->|"runs"| node_backend_ingestion
node_backend_ingestion -->|"persists"| node_backend_storage_db
node_backend_ingestion -->|"indexes"| node_backend_storage_vector
node_backend_ingestion -->|"caches"| node_backend_storage_cache
node_backend_chat -->|"retrieves"| node_backend_rag_retrieval
node_backend_rag_retrieval -->|"searches"| node_backend_storage_vector
node_backend_rag_retrieval -->|"filters"| node_backend_storage_db
node_backend_rag_retrieval -->|"supplies context"| node_backend_rag_generation
node_backend_rag_generation -->|"streams"| node_backend_chat
node_backend_graph_api -->|"queries"| node_backend_graph_rag
node_backend_graph_rag -->|"persists"| node_backend_storage_db
node_backend_auth -->|"authenticates"| node_backend_storage_db
node_backend_workspaces -->|"scopes"| node_backend_storage_db
node_backend_health -->|"checks"| node_backend_storage_db
node_backend_health -->|"checks"| node_backend_storage_cache
node_backend_health -->|"checks"| node_backend_queue
node_backend_health -->|"checks"| node_backend_storage_vector
node_ops_obs -->|"observes"| node_backend_main
node_ops_deploy -->|"runs"| node_backend_main
node_ops_deploy -->|"runs"| node_frontend_app
node_integrations_bot -.->|"integrates"| node_backend_routes

click node_backend_main "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/main.py"
click node_backend_routes "https://github.com/param20h/pdf-assistant-rag/tree/dev/backend/app/routes"
click node_backend_auth "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/auth.py"
click node_backend_documents "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/documents.py"
click node_backend_chat "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/chat.py"
click node_backend_workspaces "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/workspaces.py"
click node_backend_graph_api "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/graph.py"
click node_backend_health "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/health.py"
click node_backend_admin "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/admin.py"
click node_backend_ingestion "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/services/document_ingestion.py"
click node_backend_rag_retrieval "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/retriever.py"
click node_backend_rag_generation "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/prompts.py"
click node_backend_graph_rag "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/graph_builder.py"
click node_backend_storage_db "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/database.py"
click node_backend_storage_vector "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/vectorstore.py"
click node_backend_storage_cache "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/cache.py"
click node_backend_queue "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/celery_app.py"
click node_frontend_app "https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/app"
click node_frontend_chat "https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/components/chat"
click node_frontend_documents "https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/components/document"
click node_frontend_graph "https://github.com/param20h/pdf-assistant-rag/blob/dev/frontend/src/components/graph/KnowledgeGraph.tsx"
click node_frontend_state "https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/store"
click node_frontend_api "https://github.com/param20h/pdf-assistant-rag/blob/dev/frontend/src/lib/api.ts"
click node_integrations_bot "https://github.com/param20h/pdf-assistant-rag/blob/dev/bots/discord/bot.py"
click node_ops_obs "https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/observability.py"
click node_ops_deploy "https://github.com/param20h/pdf-assistant-rag/blob/dev/docker-compose.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_backend_main,node_backend_routes,node_backend_auth,node_backend_documents,node_backend_chat,node_backend_workspaces,node_backend_graph_api,node_backend_health,node_backend_admin,node_backend_ingestion,node_backend_rag_retrieval,node_backend_rag_generation,node_backend_graph_rag,node_backend_storage_db,node_backend_storage_vector,node_backend_storage_cache,node_backend_queue toneBlue
class node_frontend_app,node_frontend_chat,node_frontend_documents,node_frontend_graph,node_frontend_state,node_frontend_api toneAmber
class node_integrations_bot,node_ops_obs,node_ops_deploy toneMint
```

## Components

### Backend

FastAPI core for auth, documents, chat, RAG, persistence, and background processing

- [App entry](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/main.py): FastAPI app · Wires middleware, routers, and lifespan hooks · `backend/app/main.py`
- [Routes](https://github.com/param20h/pdf-assistant-rag/tree/dev/backend/app/routes): API layer · Domain route surface for auth, documents, chat, workspaces, admin, graph, health, and GitHub · `backend/app/routes`
- [Auth](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/auth.py): JWT/bcrypt · Login, registration, verification, and security boundaries · `backend/app/routes/auth.py`
- [Documents](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/documents.py): doc lifecycle · Upload, validation, metadata, sharing, and document status · `backend/app/routes/documents.py`
- [Chat](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/chat.py): streaming RAG · Conversation endpoints and SSE token streaming · `backend/app/routes/chat.py`
- [Workspaces](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/workspaces.py): tenant scope · Workspace membership and per-user document isolation · `backend/app/routes/workspaces.py`
- [Graph API](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/graph.py): knowledge graph · Graph retrieval and graph artifact access · `backend/app/routes/graph.py`
- [Health](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/health.py): checks · Deep checks for database, Redis, Celery, and vector store · `backend/app/routes/health.py`
- [Admin](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/routes/admin.py): ops API · Administrative actions and exports · `backend/app/routes/admin.py`
- [Ingestion](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/services/document_ingestion.py): async pipeline · Background document extraction, chunking, indexing, and persistence · `backend/app/services/document_ingestion.py`
- [Retrieval](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/retriever.py): hybrid RAG · Vector search, BM25, fusion, and reranking · `backend/app/rag/retriever.py`
- [Generation](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/prompts.py): prompt/LLM · Prompt assembly and HuggingFace inference calls · `backend/app/rag/prompts.py`
- [Graph RAG](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/graph_builder.py): entity graph · Entity/relationship extraction and graph retrieval · `backend/app/rag/graph_builder.py`
- [Database](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/database.py): SQLAlchemy/PG · Users, documents, sessions, roles, workspaces, and ingestion metadata · `backend/app/database.py`
- [Vector store](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/rag/vectorstore.py): ChromaDB · Embedding-backed semantic index · `backend/app/rag/vectorstore.py`
- [Cache](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/cache.py): Redis/LRU · Embedding and runtime caching plus job coordination · `backend/app/cache.py`
- [Queue](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/celery_app.py): Celery/Redis · Asynchronous job execution for ingestion and maintenance · `backend/app/celery_app.py`

### Frontend

Next.js client for login, document management, chat, and graph viewing

- [Next app](https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/app): App Router · Client entrypoints, page shells, and shared UI composition · `frontend/src/app`
- [Chat UI](https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/components/chat): stream client · Streaming chat panel, session sidebar, and source cards · `frontend/src/components/chat`
- [Docs UI](https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/components/document): document workspace · Drive, PDF viewer, sidebar, compare, and document actions · `frontend/src/components/document`
- [Graph view](https://github.com/param20h/pdf-assistant-rag/blob/dev/frontend/src/components/graph/KnowledgeGraph.tsx): knowledge graph · Document graph visualization surface · `frontend/src/components/graph/KnowledgeGraph.tsx`
- [State](https://github.com/param20h/pdf-assistant-rag/tree/dev/frontend/src/store): Zustand stores · Auth, chat, settings, and workspace client state · `frontend/src/store`
- [API client](https://github.com/param20h/pdf-assistant-rag/blob/dev/frontend/src/lib/api.ts): fetch layer · Frontend service layer for backend requests and auth/session handling · `frontend/src/lib/api.ts`

### Ops & Integrations

Deployment, monitoring, and adjacent integrations

- [Discord bot](https://github.com/param20h/pdf-assistant-rag/blob/dev/bots/discord/bot.py): integration · Adjacent chat integration service · `bots/discord/bot.py`
- [Observability](https://github.com/param20h/pdf-assistant-rag/blob/dev/backend/app/observability.py): metrics/tracing · Metrics, tracing, and monitoring surfaces · `backend/app/observability.py`
- [Deploy stack](https://github.com/param20h/pdf-assistant-rag/blob/dev/docker-compose.yml): containers · Docker Compose, backend/frontend images, and runtime profiles · `docker-compose.yml`

## Connections

- Next app → API client: uses · Pages and components call the client API layer
- API client → App entry: requests · Frontend talks to the FastAPI backend
- Chat UI → State: reads/writes · Chat interaction is stateful on the client
- Docs UI → State: reads/writes · Document workspace state is kept in stores
- Graph view → API client: loads · Graph view fetches graph artifacts and metadata
- App entry → Routes: mounts · Main app wires the route surface
- Routes → Auth: exposes · Authentication endpoints
- Routes → Documents: exposes · Document lifecycle endpoints
- Routes → Chat: exposes · Chat and streaming endpoints
- Routes → Workspaces: exposes · Workspace membership and scoping endpoints
- Routes → Graph API: exposes · Graph retrieval endpoints
- Routes → Health: exposes · Operational health endpoints
- Routes → Admin: exposes · Admin and export endpoints
- Documents → Queue: enqueues · Uploads push heavy processing into background jobs
- Queue → Ingestion: runs · Celery executes ingestion work
- Ingestion → Database: persists · Stores document state and metadata
- Ingestion → Vector store: indexes · Builds embeddings for semantic retrieval
- Ingestion → Cache: caches · Caches repeated embedding and compute results
- Chat → Retrieval: retrieves · Chat requests trigger multi-stage retrieval
- Retrieval → Vector store: searches · Semantic search over embeddings
- Retrieval → Database: filters · Uses document and permission metadata
- Retrieval → Generation: supplies context · Retrieved passages are assembled for generation
- Generation → Chat: streams · Generated tokens stream back to chat endpoints
- Graph API → Graph RAG: queries · Graph endpoints use extracted entity relations
- Graph RAG → Database: persists · Stores graph artifacts and ownership metadata
- Auth → Database: authenticates · Users and credentials live in the relational store
- Workspaces → Database: scopes · Workspace membership controls data isolation
- Health → Database: checks · Database readiness and liveness
- Health → Cache: checks · Redis/cache readiness and liveness
- Health → Queue: checks · Worker/queue readiness and liveness
- Health → Vector store: checks · Vector store readiness and liveness
- Observability → App entry: observes · Runtime metrics and tracing wrap the API
- Deploy stack → App entry: runs · Backend is deployed as a containerized service
- Deploy stack → Next app: runs · Frontend is deployed as a separate containerized service
- Discord bot → Routes: integrates · Adjacent integration surface connected to backend APIs
