13 KiB
| name | client | status | tech | local_path | deploy | url | server | tags | created | last_commit | commits | port | db | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mod Comms | Barclays | active |
|
/Users/ai_leed/Documents/Projects/Oliver/modcomms | ./deploy.sh | https://baic.oliver.solutions/modcomms/ | baic |
|
2026-04-14 | 2026-05-18 | 210 | 8000 | 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:
- User uploads file → frontend base64-encodes → POST
/api/analyze - Backend creates job ID, returns immediately, spawns asyncio background task
_run_analysis()loads reference docs (brand guidelines, channel specs), deduplicates via MD5 hash- Four agents call Gemini 2.5 Pro concurrently (each builds system prompt + reference context)
- Lead Agent combines four SubReviews into single overallStatus (Passed/Failed/Requires Manual Legal Review)
- File stored to
/app/storagevolume, thumbnail generated, proof_version inserted to PostgreSQL - 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
# 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):
- Copy
.env.deploy.example→.env.deploy, fill secrets (GEMINI_API_KEY, Azure tenant/client IDs, DB passwords) - Run
./deploy.shgit pullnpm install && npm run buildin frontend- Copy
frontend/dist/to/var/vhosts/baic.oliver.solutions/htdocs/modcomms docker compose buildbackend- Start PostgreSQL container
alembic upgrade head(migrations)docker compose up -d --force-recreate backend- Wait for
/health200 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/modcommsAZURE_TENANT_ID— Azure AD tenant ID (required in production)AZURE_CLIENT_ID— Azure AD app registration ID (required in production)DISABLE_AUTH— Settrueto skip JWT validation (local dev only); default:falseCORS_ORIGINS— Comma-separated allowed origins; default:http://localhost:3000HOST— Server bind address; default:0.0.0.0PORT— Server port; default:8000REFERENCE_DOCS_PATH— Path to brand/channel guideline documents (local or DB)
Docker Compose (.env)
POSTGRES_USER— default:modcommsPOSTGRES_PASSWORD— default:modcomms_devPOSTGRES_DB— default:modcommsBACKEND_PORT— host port for backend container; default:8000POSTGRES_PORT— host port for PostgreSQL; default:5432
Frontend (frontend/.env.local)
VITE_BACKEND_URL— Backend API URL; default:http://localhost:8000VITE_AZURE_CLIENT_ID— Azure AD client IDVITE_AZURE_TENANT_ID— Azure AD tenant IDVITE_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 completeGET /api/jobs— List all jobs (paginated)
Campaign & proof management
GET /api/campaigns— List campaigns (user's org)POST /api/campaigns— Create campaignGET /api/campaigns/{campaign_id}/proofs— List proofs in campaignGET /api/proofs/{proof_id}— Get proof and all versionsGET /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 documentsDELETE /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-18 | fix(gemini): update fallback model to gemini-3.1-flash-lite |
| 2026-05-15 | feat(knowledge-base): smart resume for interrupted processing jobs |
| 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)