ai_qc/backend
nickviljoen 29ee941037 refactor(formatting_diff): narrow scope to bold + italic only
First real-data test against the AXA car-insurance PDFs surfaced a
noise problem: the new document is a brand refresh — every page flips
font (PublicoBanner-Bold→PublicoHeadline-Bold) and colour
(#893f4a→#2e3092). At medium-per-finding that crashed the diff score
to 0.0 and drowned the bold-regression signal AXA actually flagged.

Drop font, size, colour comparators. Keep bold + italic — the
attributes the vision-LLM consistently misses on dense layouts. The
LLM already narrates colour-scheme rebrands and font swaps in its
Modified / Style-changes blocks; running both layers on the same
visual change just double-counts it.

Tests inverted from "X change is flagged" to "X change is NOT
flagged" to lock the scope decision in.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 12:37:19 +02:00
..
_archive/dow_jones chore(dow-jones): archive profiles, checks, and per-client doc 2026-05-14 21:11:54 +02:00
brand_guidelines Add Honda client, video QC, session refresh, Amazon check tuning 2026-04-16 14:53:52 +02:00
config chore(secrets): untrack env files + add JWT path to .gitignore 2026-05-14 23:13:18 +02:00
document_mode refactor(formatting_diff): narrow scope to bold + italic only 2026-05-19 12:37:19 +02:00
output Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
profiles fix(hp_copy_review): correct llm casing + route HP reports to /hp/ folder 2026-05-17 22:07:25 +02:00
scripts fix(deploy): use git's own -n limit instead of | head -20 2026-05-17 15:25:38 +02:00
tests refactor(formatting_diff): narrow scope to bold + italic only 2026-05-19 12:37:19 +02:00
uploads Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
visual_qc_apps feat(hp_copy_review): single-check LLM grader against Source Messaging 2026-05-17 21:25:30 +02:00
ai_qc.service Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
apache_config.conf Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
api_server.py fix(hp_copy_review): correct llm casing + route HP reports to /hp/ folder 2026-05-17 22:07:25 +02:00
auth_middleware.py Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
AXA_DOCUMENT_MODE_PLAN.md Add AXA document-mode QC pipeline (Phases 1, 3, 4, 5) 2026-05-01 18:38:14 +02:00
BACKEND_README.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
box_client.py Compute Box OAuth redirect URI from the request 2026-04-27 15:50:59 +02:00
BOX_CLIENT_ONBOARDING.md docs: add Box client onboarding runbook 2026-05-17 14:12:48 +02:00
box_jwt_client.py feat(box-jwt): move source file to _PROCESSED after successful run 2026-05-17 13:29:45 +02:00
box_tokens.py PR1: Box.com OAuth + token storage 2026-04-27 15:39:27 +02:00
brand_guidelines_db.py Process multi-page PDF reference assets with LLM summarization 2026-03-26 22:02:47 +02:00
CLAUDE.md Restructure CLAUDE.md docs: slim project-wide root, complete per-client coverage 2026-05-06 12:29:16 +02:00
CLEANUP_SUMMARY.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
client_config.py feat(hp): promote HP client + add hp_copy_review profile 2026-05-17 21:08:18 +02:00
DEPLOYMENT_RESTRUCTURE.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
DEV_PROD_SETUP.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
email_service.py Simplify settings UX and add client access request flow 2026-04-27 14:02:40 +02:00
excel_processor.py fix(excel-processor): wrap extraction in try/except to honour 'never raises' 2026-05-17 20:55:54 +02:00
file_naming_validator.py Add wsj podcast profile to Dow Jones client, File naming check added to all profiles 2026-04-29 18:17:36 +02:00
generate_usage_report.py Fix usage report generator to handle missing token data 2026-02-02 13:32:47 +02:00
headless_curl_examples.sh Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
headless_example.py Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
jwt_validator.py Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
llm_config.py Add Honda client, video QC, session refresh, Amazon check tuning 2026-04-16 14:53:52 +02:00
localization_processor.py Fix localization matrix parser: wrong dates for Message B 2026-03-31 21:47:47 +02:00
media_plan_processor.py Load media-plan workbooks in read_only mode to skip pivot caches 2026-04-22 21:23:08 +02:00
migrate_output_files.py Add client-specific output folders and 14-day auto-cleanup 2026-02-02 11:18:05 +02:00
MIGRATION_CHECKLIST.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
MIGRATION_GUIDE.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
MIGRATION_SUMMARY.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
msal_pkce_flow.md Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
NEW_FEATURES_QUICKSTART.md Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00
ocr_measurement.py Tone down OCR from authoritative to supplementary to reduce false positives 2026-04-02 13:54:00 +02:00
pdf_processor.py Process multi-page PDF reference assets with LLM summarization 2026-03-26 22:02:47 +02:00
PRICING_GUIDE.md Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00
profile_config.py Add Boots Production Pack profile (multi-page document mode) 2026-05-05 12:47:13 +02:00
PROFILE_MANAGEMENT.md Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00
README.md Update READMEs for user access control and new deploy flow 2026-04-22 18:49:24 +02:00
requirements.txt Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
run_api_server.py Create frontend and backend folder structure for deployment 2025-11-06 11:55:53 +02:00
technical_check.py feat(tech-check): add machine-side pre-flight inspection module 2026-05-14 21:53:06 +02:00
TOKEN_TRACKING_ENHANCEMENT.md Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00
USAGE_REPORTS.md Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00
usage_tracker.py Simplify settings UX and add client access request flow 2026-04-27 14:02:40 +02:00
user_access.py Add per-user client access control and admin management 2026-04-22 12:33:09 +02:00
validate_pricing.py Add usage tracking reports, profile versioning, and token tracking 2026-02-02 13:22:33 +02:00

Visual AI QC - AI-Powered Quality Control Platform

AI-driven visual quality control system for marketing materials, advertisements, and design assets

Overview

Visual AI QC is an intelligent quality control platform that uses advanced AI (OpenAI GPT-4o and Google Gemini 2.5 Pro) to automatically analyze visual and video content against brand guidelines, technical specifications, and design best practices. The system provides comprehensive feedback, scoring, and recommendations for improving assets across 75 specialized QC checks, 14 profiles, and 8 clients.

Key Features

  • AI-Powered Analysis: Leverages both OpenAI GPT-4o and Google Gemini 2.5 Pro for comprehensive visual analysis
  • Video QC: Native video analysis using Gemini's video understanding (mp4, mov, avi, webm)
  • OCR Layout Measurement: Tesseract OCR provides pixel-level measurements for margin, alignment, and spacing checks
  • Multi-Client Platform: 8 client workspaces (Diageo, Unilever, L'Oreal, Amazon, Boots, Dow Jones, Honda, General)
  • 14 QC Profiles: Brand-specific and general-purpose profiles with weighted scoring
  • Real-Time Progress Tracking: Live analysis progress with batch-based parallel processing
  • PDF Brand Guidelines: Upload multi-page PDF guidelines with automatic LLM summarization
  • Media Plan Integration: Upload Excel media plans for automatic asset spec validation
  • Enterprise Authentication: Microsoft Azure AD with MSAL/PKCE and silent token refresh
  • User Access Control: Default-deny per-user client access. Admins grant/revoke client visibility; all changes audit-logged
  • Admin Panel: Platform-wide usage analytics, user tracking, cost estimation, and user-access management
  • Client-Scoped Reporting: Per-client usage dashboards with date range filtering
  • Profile Versioning: Automatic version control when profiles are edited

System Architecture

Visual AI QC Platform
+-- Authentication Layer (MSAL/Azure AD with silent refresh)
|   +-- JWT Token Validator (jwt_validator.py)
|   +-- Auth Middleware (auth_middleware.py)
|   +-- httpOnly Cookie Sessions
+-- Web Interface (web_ui.html)
+-- API Server (api_server.py) - Parallel batch processing
+-- LLM Engine (llm_config.py)
|   +-- OpenAI GPT-4o (image analysis)
|   +-- Gemini 2.5 Pro (image + video analysis)
+-- OCR Engine (ocr_measurement.py) - Tesseract pixel measurements
+-- QC Check Modules (visual_qc_apps/) - 75 checks
+-- Profile System (profiles/) - 14 profiles
+-- Client Config (client_config.py) - 8 clients
+-- Brand Guidelines DB (brand_guidelines/)
+-- Media Plan Processor (media_plan_processor.py)
+-- PDF Processor (pdf_processor.py)
+-- Usage Tracker (usage_tracker.py)
+-- Output Reports (output/)

Quick Start

Prerequisites

  • Python 3.8+
  • OpenAI API Key
  • Google AI API Key
  • Microsoft Azure AD account (for authentication)
  • Tesseract OCR (optional, for pixel-level measurements): brew install tesseract (macOS) or sudo apt install tesseract-ocr (Ubuntu)

Installation

  1. Clone and Setup:

    cd ai_qc/backend
    python -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
    
  2. Configure Development Environment:

    cp config/.env.template config/development.env
    # Edit config/development.env with your API keys and Azure AD config
    
  3. Start Development Server:

    ./scripts/run-local.sh
    # Access at http://localhost:7183
    

Deploying to Dev / Prod

The dev server (optical-dev.oliver.solutions/ai_qc/) tracks the develop branch. Prod will track tagged releases on main. Both use the same deploy scripts; only the mode argument differs.

ssh <server>
cd /opt/ai_qc

# Deploy
backend/scripts/deploy.sh dev                   # pulls develop
backend/scripts/deploy.sh prod v1.2.0           # checks out tag v1.2.0
backend/scripts/deploy.sh dev --dry-run         # preview only

# Recover
backend/scripts/rollback.sh last                # revert last deploy
backend/scripts/rollback.sh <commit-hash>       # revert to specific commit

# Check
backend/scripts/health-check.sh                 # exits 0 if healthy

The deploy script captures a rollback checkpoint before applying, re-runs pip install only if requirements.txt changed, restarts the systemd service, and auto-rolls back on smoke-test failure.

See CLAUDE.md for full environment and branch strategy.

Clients

Client Profiles Description
Diageo diageo_key_visual, diageo_packaging, static_general, video_general Spirits brand visual and packaging QC
Unilever unilever_key_visual, unilever_packaging, static_general, video_general FMCG key visual and packaging QC with zero-score logic
L'Oreal loreal_static, static_general, video_general Beauty brand static QC with strict grading (any check <6 = Fail)
Amazon amazon_static, static_general, video_general ASD 2025 design compliance with OCR measurements
Boots boots_static, static_general, video_general Retail promotional artwork compliance
Dow Jones dow_jones_static, marketwatch_static, wsj_static, static_general, video_general Corporate + sub-brand QC for DJ, MarketWatch, WSJ
Honda static_general, video_general Automotive marketing QC
General / Other static_general, video_general, inclusive_accessibility General-purpose and accessibility checks

QC Profiles

Static Profiles

Profile Checks Scale Description
General Check 10 100-point General-purpose QC with even weighting
Static General 10 100-point Baseline digital static asset QC used by all clients
Unilever Key Visual 15 120-point Unilever brand guidelines with bonus check zero-scoring
Unilever Packaging 17 100-point Unilever packaging design standards
Diageo Key Visual 11 100-point Diageo brand guidelines for key visuals
Diageo Packaging 13 100-point Diageo packaging design standards
L'Oreal Static 4 100-point Focused L'Oreal QC (any check <6 = overall Fail)
Amazon Static 6 100-point ASD 2025 compliance with OCR support
Boots Static 5 100-point Retail compliance (any check <6 = overall Fail)
Dow Jones Static 5 100-point Corporate brand QC
MarketWatch Static 6 100-point MarketWatch sub-brand QC
WSJ Static 6 100-point Wall Street Journal sub-brand QC
Inclusive Accessibility 2 100-point Accessibility and inclusive design

Video Profile

Profile Checks Scale Description
Video General 4 100-point Video QC using Gemini native video analysis

Video checks: video_visual_quality, video_brand_consistency, video_text_legibility, video_pacing_flow

Video analysis uses Gemini's File Upload API to process the full video (motion, transitions, temporal flow) rather than just extracting frames. Gemini is automatically selected for video files regardless of profile LLM setting.

Amazon QC Checks (with OCR)

The 6 Amazon checks have clearly defined scope boundaries to prevent cross-check penalization:

Check Scope OCR Enhanced
amazon_required_elements Element presence only (not content correctness) No
amazon_logo_country Locale/country URL and logo correctness No
amazon_typography Font, size ratios, leading, tracking, spacing, ligatures Yes
amazon_headline_layout Alignment, prominence, positioning, line breaks Yes
amazon_margins Margin distances, left-alignment consistency Yes
amazon_element_placement Box positioning, cropping rules, tape visibility No

OCR provides Tesseract pixel-level measurements to the 3 layout-sensitive checks. Checks gracefully fall back to visual estimation when OCR is unavailable.

Scoring System

Individual Check Scores

  • Each check scores 1-10
  • 8-10: Pass (Green)
  • 5-7: Adequate (Yellow)
  • 1-4: Fail (Red)

Overall Score

  • Weighted average scaled to 100 points
  • Weights defined per-profile
  • Special rules: L'Oreal and Boots profiles fail overall if any individual check scores below 6

Grades

  • A (85-100): Excellent
  • B (70-84): Good
  • C (50-69): Adequate
  • D (35-49): Poor
  • F (0-34): Fail

Supported File Types

Input

  • Images: PNG, JPG, JPEG, BMP, WebP, GIF, TIFF
  • PDFs: First page extracted as image for analysis
  • Video: MP4, MOV, AVI, WebM, MKV, WMV, FLV (Gemini only)

Brand Guidelines

  • PDF: Multi-page with automatic text extraction and LLM summarization
  • Images: PNG, JPG, GIF, JPEG
  • Excel: XLSX/XLS for media plans and localization matrices

Output

  • HTML Reports: Visual reports with expandable sections and scoring
  • JSON Data: Raw analysis data for programmatic processing

Authentication

Azure AD with MSAL

  • PKCE security flow for single-page applications
  • httpOnly cookie session management
  • Silent token refresh every 45 minutes (sessions last full workday)
  • Proactive + reactive refresh to prevent session expiry
  • localStorage-based MSAL cache for cross-tab persistence

Admin Panel

Two tabs — Usage Overview and User Access:

  • Usage Overview: platform-wide stats (users, analyses, cost) + per-user breakdown
  • User Access: search users, toggle per-client visibility, promote/demote admins

Admin role and per-user client grants live in backend/user_access.json (bootstrapped on first start with nick.viljoen@brandtech.plus as the sole admin). All grant/revoke/promote/demote actions are logged as access_change events in backend/usage_logs/.

User Access Control

New users default to the General client only. Admins grant per-client visibility through the admin panel. Client-scoped endpoints enforce access server-side (403 with code: "client_access_denied" on denied requests), so frontend filtering alone isn't the security boundary. Revocation during an active session bounces the user back to the client picker with a toast.

API Endpoints

Authentication

Method Endpoint Description
POST /auth/login Validate MSAL token, create session
POST /auth/logout Clear session
GET /auth/status Check auth status, log user visit

Analysis

Method Endpoint Description
POST /api/start_analysis Start async analysis (auth required)
GET /api/progress/{session_id} Get real-time progress
POST /api/process_file Direct file processing (auth required)

Profiles & Guidelines

Method Endpoint Description
GET /api/profiles List profiles for client
POST /api/profiles Create new profile (auto-versioned)
PUT /api/profiles/{id} Edit profile (creates new version)
POST /api/brand_guidelines Upload brand guideline
GET /api/brand_guidelines/{id}/status Check PDF processing status

Admin & Reporting

Method Endpoint Description
GET /api/admin/check Check if user is admin
GET /api/admin/users Get all platform users (admin only)
GET /api/admin/user_access List users with their client grants (admin only)
PUT /api/admin/user_access/<email> Set client list for a user (admin only)
POST /api/admin/user_access/<email>/promote Grant admin role (admin only)
POST /api/admin/user_access/<email>/demote Remove admin role (admin only; blocked if last admin)
GET /api/client_usage_stats Client-scoped usage report

Media Plans

Method Endpoint Description
POST /api/media_plan Upload Excel media plan
GET /api/media_plan?client={id} Get client's media plan
DELETE /api/media_plan/{client_id} Remove media plan

Configuration

Environment Variables

OPENAI_API_KEY=your_openai_key
GOOGLE_API_KEY=your_google_key
AZURE_TENANT_ID=your_tenant_id
AZURE_CLIENT_ID=your_client_id
SECRET_KEY=your_flask_secret
FLASK_PORT=7183
DEBUG_MODE=false
ENVIRONMENT=development  # or production

Adding New QC Checks

  1. Create directory: visual_qc_apps/{check_name}/
  2. Create app.py using flask_app_template.py as base
  3. Add check to relevant profile JSON files
  4. Restart server

Adding New Clients

Add entry to CLIENT_PROFILES in client_config.py:

'client_id': {
    'name': 'Client Name',
    'profiles': ['static_general', 'video_general'],
    'display_name': 'Client Name',
    'description': 'Description of client QC needs'
}

Documentation

  • CLAUDE.md - Full development guide and system documentation
  • CLAUDE_AMAZON.md - Amazon check details and prompt tuning history
  • CLAUDE_BOOTS.md - Boots check details
  • CLAUDE_DOW_JONES.md - Dow Jones / MarketWatch / WSJ check details
  • CLAUDE_LOREAL.md - L'Oreal check details and prompt tuning history
  • DEV_PROD_SETUP.md - Development and production environment guide
  • backend/USAGE_REPORTS.md - Usage reporting CLI tool guide
  • backend/PROFILE_MANAGEMENT.md - Profile versioning and visibility guide

License

This project is proprietary software. All rights reserved.


Visual AI QC Platform - Ensuring quality through intelligent automation