Barclays-banner-builder/docs/project/runbook.md
Vadym Samoilenko 24713ce5e6 Add Oliver rebrand, character counts, delete variants, 6-format spec validation
- Rebrand LoginPage logo to Oliver design system
- Move Admin nav link to bottom-left user area
- Remove "Ask AI to improve" button from step 2 (VariantsGrid)
- Add CharCount component with copy limits across prompt, edit, and export views
- Add delete variant with confirmation dialog on step 2 cards
- Add theme palette migration (0007_theme_palette.py)
- Add copyLimits.ts and themes.ts libs
- Remove unused BannerEditor.tsx page and old logo PNG
- Add AGENTS.md project entry point
- Add docs/ directory

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:35:25 +01:00

6.9 KiB

Runbook

Local Development Setup

# 1. Clone and enter the repo
git clone <repo-url> barclays-banner-builder
cd barclays-banner-builder

# 2. Create .env
cp .env.example .env
# Open .env and set:
#   OPENAI_API_KEY=sk-...
#   Leave APP_BASE_PATH empty for local dev

# 3. Start all services
docker compose up -d --build

# 4. Run migrations
docker compose exec api alembic upgrade head

# 5. Seed admin user
docker compose exec api python scripts/seed_admin.py
# Creates: admin@barclays.com / change_me_password

# 6. Embed RAG corpus (costs OpenAI $)
docker compose exec api python scripts/ingest_rag.py

# 7. Index illustration library (costs OpenAI $)
docker compose exec api python scripts/index_icons.py

Access:


Production Deploy

Deploy target: optical-dev.oliver.solutions at /opt/barclays-banner-builder/

# Full deploy (first-time or update)
bash /opt/barclays-banner-builder/deploy.sh

# Backend-only (skip npm build — faster for Python-only changes)
bash /opt/barclays-banner-builder/deploy.sh --skip-frontend

# Force re-embed RAG corpus and icons (costs OpenAI $)
bash /opt/barclays-banner-builder/deploy.sh --reindex

The script is idempotent — safe to run on first deploy and subsequent updates.


First-Time Server Setup

Before running deploy.sh for the first time, the server needs:

# Install Docker (if not present)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# Install Node.js (for frontend build)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Clone the repo
git clone <repo-url> /opt/barclays-banner-builder

# Create and populate .env
cp /opt/barclays-banner-builder/.env.example /opt/barclays-banner-builder/.env
nano /opt/barclays-banner-builder/.env
# Set: OPENAI_API_KEY, POSTGRES_PASSWORD, SECRET_KEY

Then run bash /opt/barclays-banner-builder/deploy.sh.


Check Service Status

cd /opt/barclays-banner-builder

# Container status
docker compose -f docker-compose.prod.yml ps

# API logs (stream)
docker compose -f docker-compose.prod.yml logs -f api

# Worker logs (stream)
docker compose -f docker-compose.prod.yml logs -f worker

# Health check
curl -s http://127.0.0.1:8010/api/health

# Apache status
sudo systemctl status apache2

Restart Services

cd /opt/barclays-banner-builder

# Restart API only
docker compose -f docker-compose.prod.yml restart api

# Restart worker only
docker compose -f docker-compose.prod.yml restart worker

# Restart everything
docker compose -f docker-compose.prod.yml restart

# Full recreate (picks up code changes in volume-mounted source)
docker compose -f docker-compose.prod.yml up -d --no-deps --force-recreate api worker

Database Operations

cd /opt/barclays-banner-builder

# Run pending migrations
docker compose -f docker-compose.prod.yml exec api alembic upgrade head

# Check migration status
docker compose -f docker-compose.prod.yml exec api alembic current

# Generate new migration (after model change)
docker compose -f docker-compose.prod.yml exec api alembic revision --autogenerate -m "description"

# Connect to PostgreSQL
docker compose -f docker-compose.prod.yml exec postgres psql -U banners -d barclays_banners

# Quick row counts
docker compose -f docker-compose.prod.yml exec api python -c "
import asyncio
from app.database import AsyncSessionLocal
from sqlalchemy import text

async def counts():
    async with AsyncSessionLocal() as db:
        for table in ['users', 'briefs', 'banner_sets', 'banner_variants', 'icons', 'rag_chunks']:
            r = await db.execute(text(f'SELECT COUNT(*) FROM {table}'))
            print(f'{table}: {r.scalar()}')

asyncio.run(counts())
"

Rollback

cd /opt/barclays-banner-builder

# Roll back to a specific commit
git fetch origin
git checkout <commit-sha>

# Roll back DB migrations to a specific revision
docker compose -f docker-compose.prod.yml exec api alembic downgrade <revision>

# Redeploy
bash deploy.sh --skip-frontend  # or full deploy

Re-embed RAG or Icons

Required when:

  • New .docx files added to rag-corpus/
  • New PNG illustrations added to assets/illustrations/
  • Embeddings appear corrupted or missing
# Re-embed RAG corpus only
docker compose -f docker-compose.prod.yml exec api python scripts/ingest_rag.py

# Re-index icons only
docker compose -f docker-compose.prod.yml exec api python scripts/index_icons.py

# Both (via deploy flag)
bash deploy.sh --reindex

Create New Admin User

# Via admin panel (preferred)
# Login as existing admin → /admin → Users tab → Add User

# Via script (when no admin exists yet)
docker compose -f docker-compose.prod.yml exec api python scripts/seed_admin.py
# Then change password immediately via /admin

Update System Prompt

  1. Log in at /admin with admin credentials
  2. Navigate to the System Prompt tab
  3. Click "New Version"
  4. Edit the prompt text and TOV rules
  5. Click "Activate" — previous version is deactivated but retained for audit

The is_active = True version is used immediately for all subsequent copy generation.


Common Problems

Symptom Likely cause Fix
No active system prompt configured DB was seeded but prompt activation failed Run scripts/seed_admin.py again or activate a prompt via /admin
Icons not showing in preview index_icons.py not run or failed docker compose exec api python scripts/index_icons.py
RAG context missing from generated copy ingest_rag.py not run or no chunks in DB docker compose exec api python scripts/ingest_rag.py
PDF download returns 404 PDF generation job still running or failed Poll GET /api/jobs/{job_id} then check worker logs
Apache 502 after deploy API container not ready Wait 10s, check docker compose logs api
OPENAI_API_KEY error in worker logs Key not set in .env Edit .env, docker compose restart worker
Frontend shows blank page Vite build failed or wrong APP_BASE_PATH Check deploy.sh output; verify APP_BASE_PATH=/barclays-banner-builder in .env
DAM search returns mock data ADOBE_DAM_API_BASE_URL not set Expected behaviour — set DAM credentials in .env if real DAM is required

Useful One-Liners

# Tail all container logs together
docker compose -f docker-compose.prod.yml logs -f --tail=50

# Clear RQ queue (discard all pending jobs)
docker compose -f docker-compose.prod.yml exec redis redis-cli -n 0 FLUSHDB

# Check pending RQ jobs
docker compose -f docker-compose.prod.yml exec redis redis-cli LLEN rq:queue:banners

# Delete old PDF artifacts (older than 7 days)
docker compose -f docker-compose.prod.yml exec api find /artifacts -name "*.pdf" -mtime +7 -delete