Barclays-banner-builder/docs/project/database_schema.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

8.5 KiB

Database Schema

Database: PostgreSQL 16 with the pgvector extension. Connection string pattern: postgresql+asyncpg://<user>:<password>@<host>:5432/<dbname>

Migrations managed by Alembic (backend/alembic/). Apply with:

docker compose exec api alembic upgrade head

Tables

users

Column Type Constraints Notes
id UUID PK, default uuid4
email VARCHAR(255) NOT NULL, UNIQUE, INDEX Stored lowercase
hashed_password VARCHAR(255) NOT NULL bcrypt
role VARCHAR(50) NOT NULL, default user user or admin
created_at TIMESTAMPTZ NOT NULL UTC

briefs

Column Type Constraints Notes
id UUID PK, default uuid4
user_id UUID NOT NULL, FK → users.id Owner
text TEXT NOT NULL Raw campaign brief text
created_at TIMESTAMPTZ NOT NULL UTC

Relationship: one Brief → many BannerSet


conversations

Column Type Constraints Notes
id UUID PK, default uuid4
user_id UUID NOT NULL, FK → users.id Owner
brief_id UUID NOT NULL, FK → briefs.id Associated brief
title VARCHAR(120) NOT NULL, default "" First 60 chars of first message
created_at TIMESTAMPTZ NOT NULL UTC
updated_at TIMESTAMPTZ NOT NULL Updated on each new message

Relationship: one Conversation → many ConversationMessage


conversation_messages

Column Type Constraints Notes
id UUID PK, default uuid4
conversation_id UUID NOT NULL, FK → conversations.id
role VARCHAR(20) NOT NULL user or assistant
kind VARCHAR(20) NOT NULL, default text text, generation, refinement
content TEXT NOT NULL, default "" Message text
banner_set_id UUID NULLABLE, FK → banner_sets.id Set for generation/refinement messages
job_id UUID NULLABLE, FK → jobs.id Associated background job
created_at TIMESTAMPTZ NOT NULL UTC

Index: ix_conversation_messages_conv_created on (conversation_id, created_at) — composite for efficient history fetch.


banner_sets

Column Type Constraints Notes
id UUID PK, default uuid4
brief_id UUID NOT NULL, FK → briefs.id
status VARCHAR(50) NOT NULL, default draft draft, approved, exported
workfront_campaign_id VARCHAR(255) NULLABLE Optional Workfront reference
created_at TIMESTAMPTZ NOT NULL UTC

Relationship: one BannerSet → many BannerVariant


banner_variants

Column Type Constraints Notes
id UUID PK, default uuid4
banner_set_id UUID NOT NULL, FK → banner_sets.id
aspect_ratio VARCHAR(20) NOT NULL SM2, MD1, MD2, MD3, LG1, LG2, Custom
pair_id UUID NULLABLE, INDEX Groups all format variants from same copy set
custom_width INTEGER NULLABLE Pixels — only for Custom aspect_ratio
custom_height INTEGER NULLABLE Pixels — only for Custom aspect_ratio
theme VARCHAR(20) NOT NULL, default navy navy, sky-blue, yellow, lime, teal
short_title VARCHAR(64) NOT NULL Title copy
long_body VARCHAR(128) NOT NULL Body copy
cta VARCHAR(50) NOT NULL Primary CTA
cta_secondary VARCHAR(50) NULLABLE Secondary CTA (Large formats only)
dam_asset_ref VARCHAR(500) NULLABLE Adobe DAM asset ID
dam_asset_url TEXT NULLABLE DAM asset image URL
icon_id UUID NULLABLE, FK → icons.id Selected illustration
edited_by_user BOOLEAN NOT NULL, default false Manual edits flag
created_at TIMESTAMPTZ NOT NULL UTC

jobs

Column Type Constraints Notes
id UUID PK, default uuid4
type VARCHAR(50) NOT NULL generate_copy, chat_turn, render_pdf, index_icons, ingest_rag
status VARCHAR(20) NOT NULL, INDEX, default pending pending, running, done, failed
payload JSON NULLABLE Input data (brief_id, n_variants, variant_ids, etc.)
result JSON NULLABLE Output data (banner_set_id, pdf_path, etc.)
error TEXT NULLABLE Error message on failure
created_at TIMESTAMPTZ NOT NULL UTC
finished_at TIMESTAMPTZ NULLABLE UTC completion time

Index: status — for efficient polling / queue monitoring.


system_prompts

Column Type Constraints Notes
id UUID PK, default uuid4
version INTEGER NOT NULL, default 1 Auto-incrementing per new version
label VARCHAR(100) NOT NULL, default Default Human-readable name
system_text TEXT NOT NULL Core system prompt
tov_text TEXT NULLABLE Tone-of-voice rules appended to system message
tov_neutral_tone BOOLEAN NOT NULL, default true Legacy flag (kept for DB compat)
tov_uk_english BOOLEAN NOT NULL, default true Legacy flag
tov_no_exclamations BOOLEAN NOT NULL, default true Legacy flag
tov_sentence_case BOOLEAN NOT NULL, default true Legacy flag
tov_banned_phrases TEXT NOT NULL Comma-separated banned phrases
short_title_max INTEGER NOT NULL, default 32 Per-version character limit
long_body_max INTEGER NOT NULL, default 128 Per-version character limit
cta_max INTEGER NOT NULL, default 50 Per-version character limit
is_active BOOLEAN NOT NULL, INDEX, default false Only one row = true at a time
created_by_id UUID NULLABLE, FK → users.id Admin who created this version
created_at TIMESTAMPTZ NOT NULL UTC

Audit trail: Previous versions are never deleted — only is_active is toggled to false.


icons

Column Type Constraints Notes
id UUID PK, default uuid4
name VARCHAR(255) NOT NULL Human-readable name
category VARCHAR(100) NOT NULL, INDEX e.g. Banking, Cards, Nature
path VARCHAR(500) NOT NULL Relative path under assets/illustrations/
keywords ARRAY(VARCHAR) NOT NULL, default [] Tag list for keyword search
embedding Vector(1536) NULLABLE text-embedding-3-small vector for cosine search

rag_chunks

Column Type Constraints Notes
id UUID PK, default uuid4
source_doc VARCHAR(255) NOT NULL, INDEX Source filename (e.g. Consumer Duty summary.docx)
chunk_text TEXT NOT NULL Paragraph chunk
chunk_index INTEGER NOT NULL Position within source document
embedding Vector(1536) NULLABLE text-embedding-3-small vector for cosine retrieval

dam_cache (model present, not actively used)

Defined in models/dam_cache.py — reserved for future DAM response caching.


Relationships Diagram

users ─────────────────────────────────┐
  │ 1:N                                │ 1:N
briefs                          conversations
  │ 1:N                                │ 1:N
banner_sets                   conversation_messages
  │ 1:N                           (references jobs, banner_sets)
banner_variants ──── FK ──── icons
                 ──── FK (optional) ──── jobs (via conversation_messages)

system_prompts   (independent; FK to users for created_by)
rag_chunks       (independent)
icons            (independent; referenced by banner_variants)
jobs             (independent; enqueued by API, updated by worker)

pgvector Usage

Two tables use pgvector Vector(1536) columns for cosine similarity search:

Table Column Used in
rag_chunks embedding RAG retrieval during copy generation
icons embedding Icon matching during banner set creation

Both use OpenAI text-embedding-3-small (1536 dimensions). Cosine search is performed via SQLAlchemy in backend/app/rag/retrieve.py and backend/app/services/icon_matcher.py.