267 lines
No EOL
13 KiB
Markdown
267 lines
No EOL
13 KiB
Markdown
---
|
||
name: "Mod Comms"
|
||
client: Barclays
|
||
status: active
|
||
tech: [React, TypeScript, FastAPI, Python, PostgreSQL, Docker, Google Gemini, Alembic]
|
||
local_path: /Users/ai_leed/Documents/Projects/Oliver/modcomms
|
||
deploy: ./deploy.sh
|
||
url: https://baic.oliver.solutions/modcomms/
|
||
server: baic
|
||
tags: [barclays, ai, compliance, proof-review, multi-agent, gcp]
|
||
created: 2026-04-14
|
||
last_commit: 2026-05-14
|
||
commits: 208
|
||
port: 8000
|
||
db: PostgreSQL
|
||
---
|
||
|
||
## Overview
|
||
|
||
ModComms is an AI-powered marketing proof review tool built by OLIVER Agency (BAIC team) for Barclays and Barclaycard. Users upload marketing assets (images, PDFs) and a five-agent AI system analyzes each proof in parallel for legal compliance, brand adherence, tone of voice, and channel suitability. Results return as Red/Amber/Green (RAG) verdicts with actionable feedback within seconds. The system is live in production and serves as internal tooling for Barclays' compliance and marketing teams.
|
||
|
||
## Tech Stack
|
||
|
||
- **Frontend:** React 18+ with TypeScript, Vite, MSAL (Azure AD auth)
|
||
- **Backend:** FastAPI with Python 3.12+, Uvicorn, asyncio
|
||
- **Database:** PostgreSQL 16 (Alpine Docker image)
|
||
- **Infrastructure:** Docker Compose, Apache HTTP Server (reverse proxy), Linux
|
||
- **AI/ML:** Google Gemini 2.5 Pro (primary), Gemini 2.5 Flash (fallback), LlamaParse for KB ingestion
|
||
- **Key libraries:** SQLAlchemy async ORM, Alembic migrations, PyMuPDF (PDF rasterization), Pydantic, python-multipart
|
||
|
||
## Architecture
|
||
|
||
ModComms uses a **multi-agent parallel pipeline** with REST polling (replaced WebSocket to fix GCP load balancer 30s timeout). The frontend is a React SPA served by Apache; the backend is a FastAPI service in Docker that orchestrates four specialist AI agents (Legal, Brand, ChannelBestPractices, ChannelTechSpecs) concurrently, then synthesizes results via a Lead Agent.
|
||
|
||
**Data flow:**
|
||
1. User uploads file → frontend base64-encodes → POST `/api/analyze`
|
||
2. Backend creates job ID, returns immediately, spawns asyncio background task
|
||
3. `_run_analysis()` loads reference docs (brand guidelines, channel specs), deduplicates via MD5 hash
|
||
4. Four agents call Gemini 2.5 Pro concurrently (each builds system prompt + reference context)
|
||
5. Lead Agent combines four SubReviews into single overallStatus (Passed/Failed/Requires Manual Legal Review)
|
||
6. File stored to `/app/storage` volume, thumbnail generated, proof_version inserted to PostgreSQL
|
||
7. Frontend polls `/api/jobs/{job_id}` until complete
|
||
|
||
**Model fallback:** Rate limits trigger automatic retry with Gemini 2.5 Flash; sets `job.model_fallback = true`.
|
||
|
||
**Timeout:** Hard 300-second limit per analysis.
|
||
|
||
```
|
||
Browser (React SPA)
|
||
↓ HTTPS/REST polling
|
||
Apache (baic.oliver.solutions)
|
||
├─ /modcomms/ → frontend/dist/
|
||
└─ /back/ → proxy to :8000
|
||
↓
|
||
FastAPI Backend (Docker :8000)
|
||
├─ Auth (Azure AD JWT)
|
||
├─ /api/analyze, /api/jobs, /api/campaigns, /api/proofs, /api/knowledge-base, /api/export
|
||
├─ asyncio agents:
|
||
│ ├─ LegalAgent → Gemini 2.5 Pro
|
||
│ ├─ BrandAgent → Gemini 2.5 Pro
|
||
│ ├─ ChannelBestPracticesAgent → Gemini 2.5 Pro
|
||
│ ├─ ChannelTechSpecsAgent → Gemini 2.5 Pro
|
||
│ └─ LeadAgent (synthesis)
|
||
└─ Services:
|
||
├─ AnalysisService (orchestration)
|
||
├─ ReferenceDocsService (brand/channel KB)
|
||
├─ KnowledgeBaseService (LlamaParse + distillation)
|
||
├─ StorageService (/app/storage)
|
||
└─ PDFService (PyMuPDF render)
|
||
↓
|
||
PostgreSQL (Docker :5432)
|
||
└─ 12 tables: campaigns, proofs, proof_versions, users, flagged_items, etc.
|
||
```
|
||
|
||
## Dev Commands
|
||
|
||
```bash
|
||
# Clone repo
|
||
git clone git@bitbucket.org:zlalani/modcomms.git
|
||
cd modcomms
|
||
|
||
# Backend setup
|
||
cd backend
|
||
cp .env.example .env
|
||
# Edit .env: set GEMINI_API_KEY, DISABLE_AUTH=true
|
||
python -m venv venv
|
||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||
pip install -r requirements.txt
|
||
|
||
# Start PostgreSQL (Docker)
|
||
docker compose up -d postgres
|
||
|
||
# Run migrations
|
||
alembic upgrade head
|
||
|
||
# Start backend
|
||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||
# Check health: curl http://localhost:8000/health
|
||
|
||
# Frontend setup (new terminal)
|
||
cd frontend
|
||
npm install
|
||
|
||
# Create .env.local
|
||
cat > .env.local << 'EOF'
|
||
VITE_BACKEND_URL=http://localhost:8000
|
||
VITE_AZURE_CLIENT_ID=your_client_id
|
||
VITE_AZURE_TENANT_ID=your_tenant_id
|
||
VITE_AZURE_REDIRECT_URI=http://localhost:3000/
|
||
EOF
|
||
|
||
npm run dev
|
||
# Frontend at http://localhost:3000
|
||
|
||
# Build frontend for production
|
||
npm run build
|
||
```
|
||
|
||
## Deployment
|
||
|
||
- **Server:** baic.oliver.solutions (Apache + Docker Compose)
|
||
- **Deploy:** `./deploy.sh` (full pipeline: git pull → npm build → Docker build → migrations → restart)
|
||
- **URL:** https://baic.oliver.solutions/modcomms/ (frontend), https://baic.oliver.solutions/back/ (backend)
|
||
- **Port:** 8000 (backend container, proxied via Apache)
|
||
- **Service:** Docker Compose (no systemd service)
|
||
- **Local path:** /Users/ai_leed/Documents/Projects/Oliver/modcomms
|
||
|
||
**Deploy process** (on server):
|
||
1. Copy `.env.deploy.example` → `.env.deploy`, fill secrets (GEMINI_API_KEY, Azure tenant/client IDs, DB passwords)
|
||
2. Run `./deploy.sh`
|
||
- `git pull`
|
||
- `npm install && npm run build` in frontend
|
||
- Copy `frontend/dist/` to `/var/vhosts/baic.oliver.solutions/htdocs/modcomms`
|
||
- `docker compose build` backend
|
||
- Start PostgreSQL container
|
||
- `alembic upgrade head` (migrations)
|
||
- `docker compose up -d --force-recreate backend`
|
||
- Wait for `/health` 200 response
|
||
|
||
**Alternative (dev server):** `./deploy-dev.sh` (uses `sudo docker`, fixes dist permissions)
|
||
|
||
## Environment Variables
|
||
|
||
**Backend (`backend/.env`)**
|
||
|
||
- `GEMINI_API_KEY` — Google Gemini API key (required)
|
||
- `DATABASE_URL` — PostgreSQL async connection string; default: `postgresql+asyncpg://modcomms:modcomms_dev@localhost:5432/modcomms`
|
||
- `AZURE_TENANT_ID` — Azure AD tenant ID (required in production)
|
||
- `AZURE_CLIENT_ID` — Azure AD app registration ID (required in production)
|
||
- `DISABLE_AUTH` — Set `true` to skip JWT validation (local dev only); default: `false`
|
||
- `CORS_ORIGINS` — Comma-separated allowed origins; default: `http://localhost:3000`
|
||
- `HOST` — Server bind address; default: `0.0.0.0`
|
||
- `PORT` — Server port; default: `8000`
|
||
- `REFERENCE_DOCS_PATH` — Path to brand/channel guideline documents (local or DB)
|
||
|
||
**Docker Compose (`.env`)**
|
||
|
||
- `POSTGRES_USER` — default: `modcomms`
|
||
- `POSTGRES_PASSWORD` — default: `modcomms_dev`
|
||
- `POSTGRES_DB` — default: `modcomms`
|
||
- `BACKEND_PORT` — host port for backend container; default: `8000`
|
||
- `POSTGRES_PORT` — host port for PostgreSQL; default: `5432`
|
||
|
||
**Frontend (`frontend/.env.local`)**
|
||
|
||
- `VITE_BACKEND_URL` — Backend API URL; default: `http://localhost:8000`
|
||
- `VITE_AZURE_CLIENT_ID` — Azure AD client ID
|
||
- `VITE_AZURE_TENANT_ID` — Azure AD tenant ID
|
||
- `VITE_AZURE_REDIRECT_URI` — Auth redirect; default: `http://localhost:3000/`
|
||
|
||
## API Endpoints
|
||
|
||
**Analysis workflow**
|
||
|
||
- `POST /api/analyze` — Submit proof for analysis; returns `{ job_id, status }`
|
||
- `GET /api/jobs/{job_id}` — Poll analysis status; returns full ProofVersion when complete
|
||
- `GET /api/jobs` — List all jobs (paginated)
|
||
|
||
**Campaign & proof management**
|
||
|
||
- `GET /api/campaigns` — List campaigns (user's org)
|
||
- `POST /api/campaigns` — Create campaign
|
||
- `GET /api/campaigns/{campaign_id}/proofs` — List proofs in campaign
|
||
- `GET /api/proofs/{proof_id}` — Get proof and all versions
|
||
- `GET /api/proofs/{proof_id}/versions/{version_id}` — Get specific version
|
||
|
||
**Knowledge base**
|
||
|
||
- `POST /api/knowledge-base/upload` — Upload KB document (LlamaParse ingestion)
|
||
- `GET /api/knowledge-base` — List knowledge base documents
|
||
- `DELETE /api/knowledge-base/{kb_id}` — Remove KB document
|
||
|
||
**Export**
|
||
|
||
- `GET /api/export/campaign/{campaign_id}/csv` — Export campaign data as CSV (super_admin, oversight_admin only)
|
||
|
||
**Health**
|
||
|
||
- `GET /health` — Unauthenticated health check
|
||
|
||
## Known Issues
|
||
|
||
- **WebSocket timeout (resolved):** Replaced WebSocket with REST polling to fix G
|
||
|
||
## Timeline / Git History
|
||
| Date | Change |
|
||
|------|--------|
|
||
| 2026-05-14 | Rename Legal Agent to Risk & Control Agent across frontend and backend |
|
||
| 2026-04-15 | Replace logo SVG with PNG v6 in Sidebar and PDF Report |
|
||
| 2026-04-15 | Add deploy-dev.sh for dev server (sudo docker, fix dist permissions) |
|
||
| 2026-04-14 | Replace logo with v6 SVG across Sidebar and PDF Report |
|
||
| 2026-03-19 | Add CSV export of campaign data for super_admin and oversight_admin |
|
||
| 2026-03-18 | **Critical:** Switch WebSocket → REST polling (GCP LB 30s timeout fix) |
|
||
| 2026-03-18 | Switch AI model: Pro primary, Flash fallback |
|
||
| 2026-03-18 | Fix WebSocket keepalive + 25s→10s heartbeat |
|
||
| 2026-03-16 | Fix PDF logo URL with Vite base path in production |
|
||
| 2026-03-16 | Fix LlamaParse 401 + update logo to v5 |
|
||
|
||
## Sessions
|
||
### 2026-05-14 – Added grey placeholder text to Workfront
|
||
**Asked:** Added grey placeholder text to Workfront Campaign ID field in Create New Campaign modal showing "WF1234567" format without hashtag/underscores and removed validation warning.
|
||
**Done:** Placeholder text implemented and validation warning removed from modal component.
|
||
|
||
### 2026-05-14 – Asked | Show grey placeholder text
|
||
**Asked:** Asked | Show grey placeholder text for Workfront Campaign ID field and remove validation warning
|
||
**Done:** Done | Removed error validation logic, updated placeholder text to "WF1234567", and cleaned up unused error state declaration
|
||
|
||
### 2026-05-14 – Fix 500 error and document processing
|
||
**Asked:** Fix 500 error and document processing failure on modcomms knowledge base.
|
||
**Done:** Debugged and resolved server-side issue preventing document uploads from being processed.
|
||
|
||
### 2026-05-14 – Rename "Legal Agent" to "Risk &
|
||
**Asked:** Rename "Legal Agent" to "Risk & Control Agent" across three production locations
|
||
**Done:** Deployed changes to baic server after syncing 3 commits behind
|
||
|
||
### 2026-05-14 – Rename "Legal Agent" to "Risk &
|
||
**Asked:** Rename "Legal Agent" to "Risk & Control Agent" across production application | Updated frontend display labels in multiple components and backend agent configuration with new name and dictionary keys | PDFReport.tsx, FeedbackReport.tsx, Projects.tsx, Campaigns.tsx, StatusDashboard.tsx, ChecksOverview.tsx, Analytics.tsx, constants.ts, types.ts, legal_agent.py, lead_agent.py
|
||
**Done:** —
|
||
|
||
### 2026-04-15 – Replace logo with file from /Volumes/SSD/Downloads/BAR-ModComms-logos-v6.png
|
||
**Asked:** Replace logo with file from /Volumes/SSD/Downloads/BAR-ModComms-logos-v6.png and set up server deployment process.
|
||
**Done:** Created deploy-dev.sh script with dev-specific configurations (sudo docker compose, port 8001, dev project name) and successfully deployed changes.
|
||
|
||
### 2026-04-14 – Project catalogued
|
||
**Done:** Added to Obsidian second brain with full details from CLAUDE.md and git history.
|
||
|
||
---
|
||
## Change Log
|
||
| Date | Requested | Changed | Files |
|
||
|------|-----------|---------|-------|
|
||
| 2026-05-14 | Environment variable fix | Docker compose restart with --force-recreate, form submission handling | docker-compose.yml, .env |
|
||
| 2026-05-14 | Docker container restart issue | Applied force-recreate flag to reload env_file, verified container key | docker-compose.yml, .env file |
|
||
| 2026-05-14 | Ask a Question form | Form submission routing, .env.deploy.example values | .env.deploy.example, backend form handler |
|
||
| 2026-05-14 | Profile question submission bug | Fix submission logic, update environment config | server files, .env.deploy.example |
|
||
| 2026-05-14 | Profile questions submission | Mailgun domain placeholder fix, .env.deploy update, backend restart | backend/.env, .env.deploy |
|
||
| 2026-05-14 | Logo update | Added Mailgun credentials to .env.deploy, updated .env.deploy.example | .env.deploy, .env.deploy.example |
|
||
| 2026-05-14 | Campaign ID placeholder | Grey placeholder text format, validation warning removed | CreateNewCampaignModal.tsx |
|
||
| 2026-05-14 | Create New Campaign modal | Remove validation function, remove error state, update placeholder text | CreateNewCampaignModal.tsx |
|
||
| 2026-05-14 | Debugging Wizard skill | Server configuration, error handling, document processor | modcomms backend files, server logs |
|
||
| 2026-05-14 | Rename Legal Agent | Text labels in PDF export, Campaign page, Knowledgebase | PDFExport.tsx, CampaignPage.tsx, Knowledgebase.tsx |
|
||
| 2026-04-15 | Logo replacement, deployment scripts | Added deploy-dev.sh with sudo docker compose and dev port 8001, configured git pull workflow | deploy-dev.sh, deploy.sh |
|
||
| 2026-04-14 | Logo update | Replace logo with v6 SVG | Sidebar, PDF Report |
|
||
| 2026-03-18 | Fix dropped connections on GCP | WebSocket → REST polling | backend, frontend |
|
||
|
||
## Related
|
||
- [[enterprise-ai-hub-nexus/Enterprise AI Hub Nexus]] (similar AI platform)
|
||
- [[semblance/Semblance]] (same GCP deployment issues) |