---
auto_generated: true
created: 2026-05-18
manual_updated_at: 2026-05-18
modified: 2026-05-18
name: Developer_Manual
status: active
tags:
- client/barclays
- domain/ai
- domain/devops
- status/active
- tech/docker
- tech/fastapi
- tech/postgresql
- tech/python
- tech/rag
- tech/react
- tech/redis
- tech/typescript
- type/sop
type: sop
---

# Barclays Banner Builder — Developer Manual

## Architecture Overview

The application follows a decoupled architecture:

1. **Frontend**: React 18 + Vite + TypeScript. Handles UI, state management (Zustand), and HTTP polling for async jobs.
2. **Backend API**: FastAPI (Python 3.12) + SQLAlchemy 2.0 (async). Exposes REST endpoints for banner management, job status, and admin functions.
3. **Worker**: RQ (Redis Queue) worker processes background tasks (AI generation, PDF creation, RAG indexing).
4. **Database**: PostgreSQL 16 + pgvector for semantic search of the RAG corpus.
5. **Cache**: Redis 7 for job queuing and session storage.
6. **External Integrations**: OpenAI (GPT-4o-mini/text-embedding-3-small), Adobe DAM (mock in dev).

## Tech Stack

| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, TypeScript, TailwindCSS, shadcn/ui, Zustand |
| Backend | Python 3.12, FastAPI, SQLAlchemy 2.0, Alembic |
| Queue | RQ, Redis |
| Database | PostgreSQL 16, pgvector |
| AI | OpenAI API (`gpt-5.4-mini`, `text-embedding-3-small`) |
| PDF Generation | WeasyPrint |
| Deployment | Docker Compose, Apache (reverse proxy), Ubuntu |

## Local Setup

### Prerequisites
- Docker & Docker Compose
- Node.js 18+
- Python 3.12+
- `OPENAI_API_KEY` (set in `.env`)

### Steps
1. **Clone & Configure**:
   ```bash
   git clone <repo_url>
   cd <repo_dir>
   cp .env.example .env
   # Edit .env: Set OPENAI_API_KEY and other secrets
   ```

2. **Start Services**:
   ```bash
   docker compose up -d --build
   ```

3. **Initialize Database & Seed Data**:
   ```bash
   docker compose exec api alembic upgrade head
   docker compose exec api python scripts/seed_admin.py
   docker compose exec api python scripts/ingest_rag.py
   docker compose exec api python scripts/index_icons.py
   ```

4. **Access Applications**:
   - Frontend: [http://localhost:5174](http://localhost:5174)
   - API Docs: [http://localhost:8010/docs](http://localhost:8010/docs)

## Environment Variables

Key variables in `.env`:

| Variable | Description | Default/Example |
|---|---|---|
| `POSTGRES_DB` | Database name | `barclays_banners` |
| `OPENAI_API_KEY` | OpenAI Key (NEVER commit) | `sk-...` |
| `OPENAI_MODEL` | Generation Model | `gpt-5.4-mini` |
| `ADOBE_DAM_API_BASE_URL` | DAM Endpoint (empty for mock) | `"` |
| `SECRET_KEY` | JWT Signing Key | `change_me_to_a_long_random_string` |
| `APP_BASE_PATH` | URL Prefix (e.g. `/barclays-banner-builder`) | `"` |
| `VITE_BASE_PATH` | Frontend Base Path | `"` |
| `DATABASE_URL` | Constructed internally in docker-compose | `postgresql+asyncpg://...` |

## Key Services & Entry Points

### Backend (`/backend`)
- **Main App**: `app/main.py` (FastAPI entry)
- **API Routes**: `app/api/` (v1 endpoints for banners, jobs, auth)
- **Workers**: `app/workers/` (RQ job handlers)
- **DB Models**: `app/db/` (SQLAlchemy 2.0 async models)
- **Scripts**:
  - `scripts/seed_admin.py`: Creates initial admin user.
  - `scripts/ingest_rag.py`: Embeds RAG corpus into pgvector.
  - `scripts/index_icons.py`: Indexes icon assets.

### Frontend (`/frontend`)
- **Config**: `vite.config.ts` (Proxy `/api` to `http://api:8000` in dev)
- **Store**: `src/store/auth.ts` (Zustand auth store)
- **API Client**: `src/api/client.ts` (HTTP client with JWT headers)
- **Types**: `src/types/banner.ts`, `src/types/conversation.ts`
- **Job Polling**: `src/lib/jobPolling.ts` (HTTP polling, no WebSocket)

## API Reference (Key Endpoints)

- `POST /api/auth/login`: Returns JWT token.
- `POST /api/jobs`: Triggers async job (e.g., banner generation). Returns `{ job_id }`.
- `GET /api/jobs/{id}`: Polls job status (`pending`, `running`, `done`, `failed`).
- `GET /api/banners`: Lists all banners.
- `GET /api/icons`: Lists available icons.
- `GET /api/dam/assets`: Lists DAM assets (or mock data).
- `GET /admin`: Admin panel endpoint (protected).

## Deployment

### Deploy Script (`deploy.sh`)
Idempotent script for Ubuntu + Apache.

```bash
# Clone once:
git clone <repo> /opt/barclays-banner-builder

# Deploy:
bash /opt/barclays-banner-builder/deploy.sh

# Flags:
--reindex: Force re-embedding of RAG and icons.
--skip-frontend: Skip npm build, update backend only.
```

### Docker Compose Structure
- `postgres`: PGVector container, health-checked.
- `redis`: Redis container, health-checked.
- `api`: FastAPI app, exposed on `127.0.0.1:8010`.
- `worker`: RQ worker, shares volume mounts for code/assets.

## Known Gotchas

1. **No WebSocket**: The frontend uses HTTP polling (`intervalMs=2000`, `timeoutMs=120000`). Ensure Apache/LB keepalive settings are sufficient.
2. **Character Limits**: Enforced server-side. Frontend (`src/lib/copyLimits.ts`) mirrors these limits for UX but always validate on the backend.
3. **System Prompt Auditing**: The system prompt is editable via `/admin`. Version history is critical for FCA compliance.
4. **DAM Mock Mode**: If `ADOBE_DAM_API_BASE_URL` is empty, the system uses a mock client. In production, ensure this URL is set.
5. **OpenAI Key Security**: Never commit `OPENAI_API_KEY`. Use systemd environment variables or Docker secrets in production.
6. **Base Path**: In production, `APP_BASE_PATH` and `VITE_BASE_PATH` must match (e.g., `/barclays-banner-builder`). The Vite dev server proxies `/api` to the backend, but the base path affects static asset loading in prod.

## Related
- [[01 Projects/enterprise-ai-hub-nexus/DEVELOPER_MANUAL]]
- [[01 Projects/ppt-tool/DEVELOPER_MANUAL]]
- [[01 Projects/ac-tool/DEVELOPER_MANUAL.md]]
- [[01 Projects/Barclays-banner-builder/DEVELOPER_MANUAL.md]]
- [[01 Projects/barclays-banner-builder/DEVELOPER_MANUAL.md]]