---
name: "Oliver AI Bot 2.0 (Nexus MVP)"
client: OLIVER Agency
status: active
tech: [Next.js 14, FastAPI, PostgreSQL, Qdrant, Docker, Azure Entra ID, OpenAI, Anthropic]
local_path: /Users/ai_leed/Documents/Projects/Oliver/Oliver-ai-bot_2.0
deploy: ./deploy.sh
url: https://nexus.oliver.agency/nexus
tags: [oliver, ai, rag, nexus, executive-assistant, notebook]
created: 2026-04-14
server: optical-web-1
port: 443
db: PostgreSQL 16
service: docker-compose
---

## Overview

Oliver-ai-bot 2.0 (Enterprise AI Hub Nexus) is a multi-tier enterprise AI platform deployed internally at OLIVER Agency. It provides RAG-powered knowledge base chat, configurable AI agents, a Microsoft 365 personal assistant, SharePoint document sync, and a full admin panel—all secured behind Azure Entra ID (PKCE SPA flow). The system combines a Next.js frontend SPA, a FastAPI REST+SSE backend, vector search (Qdrant), PostgreSQL metadata storage, and background task processing (Celery) to deliver real-time AI-assisted knowledge retrieval and M365 integration for internal employees.

## Tech Stack

- **Frontend:** Next.js 14 (static SPA export), TypeScript, React
- **Backend:** FastAPI (Python 3.11+), Uvicorn, async/await
- **Database:** PostgreSQL 16 (metadata), Qdrant v1.12.1 (vector embeddings), Redis 7 (Celery broker + cache)
- **Infrastructure:** Docker Compose, Google Compute Engine (n2d-standard-4 VM), Google Cloud Run (document processor), Apache 2.4 reverse proxy
- **AI/ML:** OpenAI GPT-5.2 (RAG answers), text-embedding-3-large (embeddings), Anthropic Claude Sonnet 4.6 (agent tool loop), Claude Haiku 4.5 (reranking/expansion), Google Gemini 3.1 Pro (summarization)
- **External APIs:** Azure Entra ID (PKCE auth), Microsoft Graph v1.0 (M365 integration), LlamaParse (OCR), Tavily (web search), Firecrawl (web scraping), LibreCodeInterpreter (sandboxed Python)
- **Key libraries:** alembic (migrations), Celery (background tasks), pydantic (validation), SQLAlchemy (ORM)

## Architecture

**Nexus** is a four-layer system:

1. **Frontend (Next.js SPA):** Static-exported React app served via Apache at `/nexus`. Handles PKCE OAuth flow with Azure Entra ID, stores JWT, and communicates with backend over HTTPS + SSE.

2. **API Gateway (Apache 2.4):** Reverse proxy on `optical-web-1` that terminates TLS, serves static files, and proxies `/api/v1/*` to FastAPI backend on `127.0.0.1:1222`.

3. **Backend (FastAPI):** REST + Server-Sent Events API with 16 endpoint modules. Guards all routes with JWT verification. Core features:
   - **RAG Pipeline:** Multi-query expansion → Qdrant vector search → LLM reranking → streaming answers
   - **Agent Engine:** Configurable agents (LLM choice, tool scope, RAG documents)
   - **M365 Tools:** Calendar, Mail, Teams, Planner, People queries via MS Graph
   - **Document Processor:** Two-phase extraction (Cloud Run) + embedding/upsert (VM)
   - **Code Interpreter:** Sandboxed Python execution via LibreCodeInterpreter container

4. **Data Layer:**
   - **PostgreSQL:** User profiles, documents, knowledge bases, chat history, agent configs
   - **Qdrant:** Vector embeddings for RAG retrieval
   - **Redis:** Celery task broker and result backend
   - **Uploads volume:** Knowledge docs and chat attachments

**Background Workers (Celery):**
- **celery-worker:** Processes two queues: `sharepoint` (document sync), `default` (general tasks)
- **celery-beat:** Scheduler for periodic tasks (e.g., token refresh, SharePoint sync)

**Document Flow:**
```
Upload → FastAPI validator → Cloud Run nexus-processor (extract/chunk)
         → LlamaParse (OCR) + LLM structuring
         → Backend upsert to PostgreSQL + Qdrant vectors
```

**Auth Flow (PKCE):**
```
Browser → generate code_verifier + code_challenge (S256)
       → redirect to Azure AD
       → Azure returns auth_code
       → exchange code_code + code_verifier → MS access_token
       → POST ms_access_token to /api/v1/auth/login
       → Backend validates via Graph /me + auto-provisions user
       → Backend returns JWT (HS256, 15-min access + 7-day refresh)
```

**Container Topology:**
```
┌─────────────────────────────────────────┐
│       Browser (Next.js SPA @ /nexus)    │
└────────────────┬────────────────────────┘
                 │ HTTPS/SSE
                 ▼
    ┌────────────────────────────┐
    │   Apache (reverse proxy)   │
    └───┬──────────────────────┬─┘
        │ /api/v1/*            │ /nexus/*
        ▼                      ▼
   FastAPI:1222         static files
   ┌───────────┐        /var/www/html/
   │ Backend   │
   └─────┬─────┘
         │
    ┌────┼────┬────────┬──────────┐
    ▼    ▼    ▼        ▼          ▼
   PG  Redis Qdrant  Celery   Code-Int
 :5432 :6379 :6333 worker    :8877
                     │
                     └─ Cloud Run nexus-processor
                     └─ Azure AD / MS Graph
```

## Dev Commands

```bash
# Clone repo
git clone git@bitbucket.org:zlalani/enterprise-ai-hub-nexus.git
cd enterprise-ai-hub-nexus

# Configure environment
cp backend/.env.example backend/.env
# Edit backend/.env: DATABASE_URL, REDIS_URL, QDRANT_URL, ENTRA_CLIENT_ID, 
# ENTRA_TENANT_ID, OPENAI_API_KEY, ANTHROPIC_API_KEY, JWT_SECRET (gen: openssl rand -hex 32)

# Start backend services (PostgreSQL, Redis, Qdrant, FastAPI, Celery)
docker compose -f docker-compose.yml up -d

# Apply migrations
docker exec nexus-backend alembic upgrade head

# Start frontend (separate terminal)
cd frontend
npm install
npm run dev
# http://localhost:3000/nexus

# View API docs
# http://localhost:1222/docs

# View backend logs
docker logs nexus-backend -f

# View Celery worker logs
docker logs nexus-celery-worker -f

# View PostgreSQL logs
docker logs nexus-postgres -f

# Stop all services
docker compose -f docker-compose.yml down
```

## Deployment

- **Server:** `optical-web-1` (Google Compute Engine, n2d-standard-4, 4 vCPU, 16 GB RAM, europe-west1)
- **Deploy:** Run `./deploy.sh` from `/opt/enterprise-ai-hub-nexus/` as non-root user
  - Pulls latest code (`git pull --ff-only`)
  - Builds Docker images (`docker compose -f docker-compose.prod.yml build`)
  - Builds frontend (`npm ci && npm run build`)
  - Syncs static export to `/var/www/html/enterprise-ai-hub-nexus/`
  - Starts backend, celery-worker, celery-beat
  - Runs migrations (`alembic upgrade head`)
- **URL:** `https://nexus.oliver.agency/nexus` (Apache reverse proxy on optical-web-1, TLS terminated)
- **Port:** 443 (Apache HTTPS), backend listens on 127.0.0.1:1222 (proxied)
- **Service:** Docker Compose (`docker-compose.prod.yml`), no systemd service
- **Local path:** `/Users/ai_leed/Documents/Projects/Oliver/Oliver-ai-bot_2.0`

## Environment Variables

**Backend (`backend/.env`):**
- `DATABASE_URL` — PostgreSQL connection string (e.g., `postgresql+asyncpg://user:pass@localhost:5432/nexus`)
- `REDIS_URL` — Redis broker URL (e.g., `redis://localhost:6380`)
- `QDRANT_URL` — Qdrant HTTP endpoint (e.g., `http://localhost:6333`)
- `ENTRA_CLIENT_ID` — Azure Entra app registration client ID
- `ENTRA_TENANT_ID` — Azure tenant ID
- `JWT_SECRET` — HS256 signing key (generate: `openssl rand -hex 32`)
- `JWT_ALGORITHM` — Default: `HS256`
- `JWT_EXPIRATION_HOURS` — Access token TTL (default: 0.25 = 15 min)
- `REFRESH_TOKEN_EXPIRATION_DAYS` — Refresh token TTL (default: 7)
- `OPENAI_API_KEY` — OpenAI API key for GPT-5.2 and embeddings
- `ANTHROPIC_API_KEY` — Anthropic API key for Claude models
- `GOOGLE_API_KEY` — Google API key for Gemini
- `TAVILY_API_KEY` — Tavily web search API key
- `FIRECRAWL_API_KEY` — Firecrawl web scraping API key
- `LLAMAPARSE_API_KEY` — LlamaParse OCR API key
- `MS_GRAPH_SCOPES` — Microsoft Graph permission scopes (auto-synced during login)
- `CELERY_BROKER_URL` — Celery task broker (points to Redis)
- `CELERY_

## Sessions
### 2026-04-14 – Project catalogued
**Done:** Added to Obsidian second brain.

---
## Change Log
| Date | Requested | Changed | Files |
|------|-----------|---------|-------|
| 2026-04-14 | Initial setup | Note created | — |

## Related
- [[enterprise-ai-hub-nexus/Enterprise AI Hub Nexus]]
- [[oliver-ai-assistant/Oliver AI Assistant]]