---
name: "APAC Ops Bot"
client: Oliver Agency APAC
status: active
server: optical-web-1
tech: [Python, FastAPI, React, TypeScript, PostgreSQL, OpenAI API, Azure AD, Docker]
local_path: "/Users/ai_leed/Documents/Projects/Oliver/APAC ops Bot"
deploy: docker compose up -d or deploy.sh
url: 
tags: [oliver, apac, bot, ops]
created: 2026-04-14
port: 8048
db: PostgreSQL
---

## Overview

APAC ops Bot is an AI-powered operations assistant for Oliver Agency's APAC region. It's a RAG-powered chatbot that strictly answers questions from curated OpenAI Vector Store documents (preventing hallucinations), with Azure AD SSO authentication, multi-turn conversation support, and detailed token usage tracking. The bot helps APAC ops teams quickly find answers from internal documentation without requiring hallucination-prone open-ended AI generation.

## Tech Stack

- **Frontend:** React 18, TypeScript, MSAL (Microsoft Authentication Library) for Azure AD SSO, WebSocket for real-time streaming
- **Backend:** Python 3.x, FastAPI, async SQLAlchemy + asyncpg, Alembic for migrations
- **Database:** PostgreSQL (async)
- **Infrastructure:** Docker Compose, bash deployment script
- **AI/ML:** OpenAI Assistants API with `file_search` tool, model `gpt-5-nano-2025-08-07`, OpenAI Vector Store
- **Key libraries:** `openai`, `sqlalchemy`, `alembic`, `pytest`, `black`, `isort`, `flake8`

## Architecture

The system is a three-tier architecture:

1. **Frontend (React + TypeScript):** Browser-based UI with MSAL Azure AD PKCE flow authentication. Real-time chat interface connected via WebSocket.
2. **Backend (FastAPI):** REST API + WebSocket server. Handles auth, conversation state, OpenAI Assistants API calls with RAG, and token tracking. Uses async SQLAlchemy with PostgreSQL.
3. **Database (PostgreSQL):** Stores conversation history, user sessions, token usage metrics, and auth state.

**Data Flow:**
- User authenticates via Azure AD MSAL (or email/password fallback) → Frontend receives JWT/session token
- User sends chat message → WebSocket connection streams response from OpenAI Assistants API (file_search tool only)
- Backend logs conversation, tokens used, and metadata to PostgreSQL
- Frontend displays streamed response in real-time

**Key Design Decisions:**
- **RAG-only constraint:** OpenAI Assistants API with `file_search` tool ensures answers come strictly from Vector Store documents
- **WebSocket:** Enables real-time streaming of bot responses instead of polling
- **Async SQLAlchemy:** Non-blocking database operations for high concurrency
- **Azure AD MSAL:** Enterprise SSO with email/password fallback for flexibility

```
┌─────────────┐
│   Browser   │
│  (React)    │
└──────┬──────┘
       │ HTTPS + WebSocket
       │ (MSAL Auth, JWT)
       ▼
┌─────────────────────────────────┐
│   FastAPI Backend               │
│  - Auth (MSAL/Email)            │
│  - WebSocket streaming          │
│  - OpenAI Assistants (RAG)      │
│  - Token tracking               │
└──────┬──────────────────────────┘
       │ asyncpg (async queries)
       ▼
┌─────────────────────────────────┐
│   PostgreSQL Database           │
│  - Conversations                │
│  - Users / Sessions             │
│  - Token usage logs             │
└─────────────────────────────────┘
       │
       └──► OpenAI Vector Store
           (file_search tool)
```

## Dev Commands

```bash
# Start all services (Docker Compose)
cd /Users/ai_leed/Documents/Projects/Oliver/APAC\ ops\ Bot && docker compose up -d

# Backend: run dev server with auto-reload
cd backend && uvicorn app.main:app --reload --port 8048

# Backend: run tests
cd backend && pytest

# Backend: run tests with coverage report
cd backend && pytest --cov=app

# Backend: lint and format code
cd backend && black app/ && isort app/ && flake8 app/

# Backend: apply database migrations
cd backend && alembic upgrade head

# Backend: rollback last migration
cd backend && alembic downgrade -1

# Frontend: start dev server
cd frontend && npm start

# Frontend: build for production
cd frontend && npm run build

# Frontend: run tests
cd frontend && npm test
```

## Deployment

- **Server:** Unknown (not documented)
- **Deploy:** `./deploy.sh` in project root, or `docker compose up -d`
- **URL:** Unknown (not documented)
- **Port:** 8048 (backend), frontend typically 3000 in dev
- **Service:** No systemd service documented
- **Local path:** `/Users/ai_leed/Documents/Projects/Oliver/APAC ops Bot`

To deploy: navigate to project root and run `./deploy.sh` or use Docker Compose directly.

## Environment Variables

Key environment variables (location: likely `.env` file, not shown in source):

- `OPENAI_API_KEY` — API key for OpenAI Assistants API and Vector Store access
- `OPENAI_ASSISTANT_ID` — ID of the pre-configured OpenAI Assistant with file_search tool
- `OPENAI_VECTOR_STORE_ID` — ID of the Vector Store containing APAC ops documents
- `DATABASE_URL` — PostgreSQL connection string (format: `postgresql+asyncpg://user:pass@host:5432/dbname`)
- `AZURE_AD_TENANT_ID` — Azure tenant ID for MSAL SSO
- `AZURE_AD_CLIENT_ID` — Azure app registration client ID
- `AZURE_AD_CLIENT_SECRET` — Azure app secret (if not using PKCE)
- `BACKEND_URL` — Base URL of FastAPI backend (for frontend API calls)
- `FRONTEND_URL` — Base URL of React frontend (for CORS, redirects)
- `JWT_SECRET_KEY` — Secret for signing JWT tokens
- `JWT_ALGORITHM` — Algorithm for JWT (likely `HS256`)

## API / Endpoints

Key REST + WebSocket endpoints (exact paths not documented in source, but likely in `backend/app/`):

- `POST /auth/login` — Email/password authentication
- `POST /auth/azure-callback` — Azure AD SSO callback
- `POST /api/conversations` — Create new conversation
- `GET /api/conversations/{conversation_id}` — Fetch conversation history
- `WS /ws/chat/{conversation_id}` — WebSocket for real-time chat streaming
- `GET /api/metrics/tokens` — Fetch token usage stats

See `apac-ops-bot/backend/app/` for complete route definitions.

## Known Issues

- Server and production URL not documented — clarify with ops team
- OPENAI_ASSISTANT_ID and OPENAI_VECTOR_STORE_ID must be pre-created in OpenAI account manually (not auto-provisioned)
- Fallback email/password auth may be disabled if Azure AD is the only auth method configured
- No explicit documentation on Vector Store document upload/sync process — may require manual management

## Git

- **Remote:** Not documented in provided source files

---

**Last Updated:** Based on source files dated [check file timestamps]  
**Maintainer:** Unknown (check git history)  
**Related Notes:** None yet — create links as you discover dependencies

## 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 | — |