Commit graph

79 commits

Author SHA1 Message Date
michael
e68aab0d03 Correct padding direction - more top padding to push text down
Text was sitting too high, so need 5px top / 4px bottom to push
the text downward for visual centering.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:03:31 -06:00
michael
8dc3ef34b0 Fix PDF status pill vertical centering with asymmetric padding
Use 4px top / 5px bottom padding to compensate for Arial font metrics
where the visual center differs from mathematical center. The extra
bottom padding pushes the text up to appear visually centered.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:03:15 -06:00
michael
1799902448 Fix PDF status pill text centering for html2canvas
Replace flexbox-based centering (inline-flex, alignItems, justifyContent)
with explicit height + line-height matching (22px) for reliable rendering
in html2canvas. Flexbox properties don't render consistently when
converting HTML to canvas.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:54:48 -06:00
michael
5629d18df4 Fix email service crash when Mailgun not configured
Add validation to check MAILGUN_API_URL has a valid protocol prefix
and MAILGUN_API_KEY is set before attempting to make HTTP request.
Returns False gracefully with warning log instead of crashing with
httpx.UnsupportedProtocol error.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:40:42 -06:00
michael
c7228c95a2 Apply UI audit fixes for Barclays design guidelines compliance
- Update font config to prioritize Barclays Effra with Inter fallback
- Add "powered by OLIVER" text to sidebar branding
- Fix sidebar user profile button border radius to consistent 10px
- Update Hero "View Documentation" button to Active Blue outline style
- Remove legacy color definitions from Tailwind config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:27:51 -06:00
michael
7698bbbd5a Apply Barclays brand colors to Projects.tsx and fix Sidebar corner radius
Updates Projects.tsx to use Barclays design system colors throughout:
- StatusBadge: bg-warning/bg-success/bg-warning-light/bg-grey-100
- OverallStatusBadge: bg-success/bg-error/bg-grey-300
- Tables: bg-lime headers, bg-grey-300 borders, even:bg-grey-100 rows
- Buttons: rounded-full pill shape, border-2 outlines
- Forms: rounded-[10px], text-black-title labels
- Hover states: hover:bg-info-light for row selection
- Delete modal: rounded-[10px], bg-error delete button

Updates Sidebar.tsx nav buttons from rounded-xl to rounded-[10px] per spec.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:19:15 -06:00
michael
0fdaedc7ff Complete UI design system migration to Barclays brand colors
Updates all remaining frontend components to use the new Barclays
design system color tokens:
- brand-dark-blue → primary-blue (#1A2142)
- brand-accent → active-blue (#006DE3)
- brand-light-blue → cyan-brand (#00AEEF)
- brand-gray → grey-100 (#F6F6F6)

Components updated:
- CampaignDetail and ProofDetailView in Campaigns.tsx
- Projects.tsx (full component migration)
- StatusDashboard.tsx (status tiles and colors)
- CreateProjectModal.tsx (modal styling)
- FeedbackReport.tsx (remaining brand colors)
- Login.tsx and Profile.tsx
- WIPReviewer.tsx and CopyGenAI.tsx
- Header, LoadingVisual, ToggleSwitch
- AssetPreview, ProofPreview, AssetUpload
- ProofTypeManager

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 14:00:13 -06:00
michael
75b2c6e699 Update modals and remaining UI components in Campaigns
- Update UploadProofModal with new design system colors
- Update LoadingCell progress bar to active-blue
- Update DeleteConfirmationModal with pill buttons and rounded corners
- Update CampaignDeleteConfirmationModal styling
- Apply consistent border radius (10px) to all modals
- Update drag & drop zone colors to use success theme

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 13:52:57 -06:00
michael
532d7541d6 Implement Barclays design system UI update
- Update Tailwind config with new color tokens (primary-blue, active-blue,
  electric-violet, lime, grey-100/300/700/900, success, warning, error)
- Add Inter font from Google Fonts as Barclays Effra alternative
- Update Sidebar with primary-blue background and white active state
- Update Hero with electric-violet accent and pill-shaped buttons
- Update all tables with lime (#C3FB5A) header backgrounds
- Implement alternating row colors (white/grey-100) on tables
- Update status badges: In Progress (amber), Completed (green)
- Update tabs with active-blue underline styling
- Apply 10px border radius to cards and containers
- Update button styling to pill-shaped with active-blue
- Update input/dropdown borders to grey-700 with 2px
- Update selected state highlighting to info-light (#E7F0FB)
- Update FeedbackReport RAG status colors to new design system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 13:50:46 -06:00
michael
e5a841716e Add categorized issue display for revision analysis
When analyzing proof revisions (version > 1), SubReviewCard now displays
issues in three distinct categories: Resolved Issues (green, collapsed by
default), Outstanding Issues (amber), and New Issues (red). Each section
is collapsible with count badges. Original mode (version 1) maintains
backward compatibility with the single "Actionable Issues" list.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:39:42 -06:00
michael
bf1d689f42 Fix migration down_revision to correct revision ID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:18:11 -06:00
michael
2f547dc494 Detect identical file uploads via MD5 hashing
- Add file_hash and is_identical_file columns to proof_versions table
- Compute MD5 hash on file upload and compare with previous version
- Display warning banner when uploading identical file as revision
- Return is_identical_file in WebSocket response and API endpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:15:48 -06:00
michael
3a5c3bcde3 Implement revision-aware proof analysis pipeline
When a subsequent revision of a proof is uploaded, the analysis now takes
place in context of the previous version's results. The system identifies:
- Resolved issues: fixed in the new revision
- Outstanding issues: still present from previous version
- New issues: introduced in the new revision

Key changes:
- Add resolvedIssues, outstandingIssues, newIssues fields to SubReview
- Add PreviousReviewContext model for passing previous review data
- Update all specialist agents to accept previous_review context
- Extend GeminiService with include_revision_fields parameter
- Add get_latest_version_review() repository method
- Update LeadAgent to synthesize cross-version context in summary
- Fetch previous analysis in WebSocket handler for revisions

First version analysis continues to work exactly as before with revision
fields set to null.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:04:16 -06:00
michael
f13fa2f7e8 Parallelize specialist agent analysis with asyncio.gather
Run all 4 specialist agents (Legal, Brand, Channel Best Practices,
Channel Tech Specs) concurrently instead of sequentially. This reduces
total analysis time to roughly the duration of the slowest agent rather
than the sum of all agent times.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:13:15 -06:00
michael
8eac1f8492 Update Gemini model to gemini-3-pro-preview
Changed the AI model used for proof analysis from gemini-2.5-flash
to gemini-3-pro-preview for improved analysis capabilities.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:09:04 -06:00
michael
53351c86f3 Fix PDF pages route ordering for correct path matching
Move /files/{storage_key}/pages endpoint before the base /files/{storage_key}
endpoint so FastAPI matches the more specific route first.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:04:58 -06:00
michael
d97be02b0b Add PDF preview support with on-demand rasterization
- Backend: Generate PDF thumbnail from first rasterized page on upload
- Backend: Add /files/{storage_key}/pages endpoint for PDF rasterization
- Frontend: Add getPdfPages() method to apiService
- Frontend: Create usePdfPages hook for on-demand PDF page loading
- Frontend: Pass pdfPages prop to ProofPreview in Campaigns view

This fixes the issue where PDF uploads showed no visual preview in results.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:56:23 -06:00
michael
0bfe28af59 Add bullet style to actionable issues list in PDF export
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:31:24 -06:00
michael
bf22248025 Fix PDF export formatting by parsing HTML and bullet text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:26:31 -06:00
michael
17495d4291 Fix feedback report formatting by parsing HTML and bullet text
Add formatFeedbackText() utility that converts raw HTML tags and
concatenated bullet points from Gemini API into properly formatted
React elements with proper line breaks and list styling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:19:28 -06:00
michael
907c3a520e Fix large file preview and download issues
- Add persistent Docker volume for file storage to fix 404 download errors
- Set FILE_STORAGE_PATH env var in Dockerfile and docker-compose.yml
- Increase thumbnail generation limit from 500KB to 10MB for images
- Remove encodeURIComponent from file download URL to prevent path encoding

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:06:41 -06:00
michael
687edb547c Add campaign delete functionality with single and bulk selection
- Add CampaignDeleteConfirmationModal for campaign deletion confirmation
- Add checkbox selection column to CampaignList with select all/indeterminate state
- Add actions column with trash icon for single campaign deletion
- Add bulk actions bar showing selected count with Clear/Delete buttons
- Add handleDeleteCampaign handler in App.tsx using apiService.deleteCampaign
- Pass onDeleteCampaign prop through Campaigns component chain

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 07:46:51 -06:00
michael
5388c390ed Fix AgentReview missing toneAgentReview attribute after refactor
Replace removed toneAgentReview and channelAgentReview with the new
channelBestPracticesAgentReview and channelTechSpecsAgentReview in
the WebSocket handler. Update /info endpoint agent list to match.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 07:30:16 -06:00
michael
4fbc118239 Add comprehensive legal compliance specification for Gemini analysis
Replaces placeholder legal.md with complete specification based on:
- Marketing LRR Questions (Feb 2024)
- Marketing Legal Decision Tree (Aug 2025)
- BUK Marketing High/Low Risk Definitions

Includes 16 sections covering:
- Financial promotion detection and regulated products
- Risk classification (high/low)
- COBS 4.5 communication standards
- CAP/BCAP code requirements
- Representative APR requirements
- Testimonials, comparisons, and promotions
- Sustainability/ESG content rules
- Consumer Duty requirements
- Common violations checklist
- RAG status guidelines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:24:26 -06:00
michael
fc52ea6b11 Add comprehensive channel tech specs specification for Gemini analysis
Replaces placeholder with detailed technical specifications including:
- Platform-specific dimensions and safe zones (Meta, TikTok, Pinterest, YouTube/PMAX, Snapchat)
- Exact pixel measurements for safe zones extracted from source templates
- Brand element placement rules for Barclays and Barclaycard
- File format, typography, and accessibility requirements
- Comprehensive violations checklist for analysis

Based on Barclays and Barclaycard Social Templates (August 2025).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:18:47 -06:00
michael
7ed2486537 Add comprehensive channel best practices specification for Gemini analysis
Replace the 60-line placeholder with a detailed 613-line spec covering:
- 6 core creative principles and trust paradox for financial services
- Platform-specific guidelines: LinkedIn, Reddit, Instagram, Facebook, Twitter/X, YouTube
- Performance metrics and benchmarks from industry research
- Short-form video guidelines based on System1 research
- Mobile-first design requirements with touch targets and safe zones
- Copy and headline guidelines with character limits by platform
- Comprehensive violations checklist for assessment
- Measurement benchmarks and KPIs by platform

Sources: LinkedIn Creative Handbook, Reddit Mega Deck, Global Creative
Inspiration Report, LinkedIn B2C Guide, System1 research, Barclays campaigns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:10:36 -06:00
michael
404ba6868b Restructure agent system: remove Tone, split Channel, implement Legal
- Remove Tone Agent (tone is now part of Brand specs)
- Split Channel Agent into Channel Best Practices Agent and Channel Tech Specs Agent
- Convert Legal Agent from stub to full Gemini-powered implementation
- Add new prompt files for channel_best_practices.md, channel_tech_specs.md, legal.md
- Update ReferenceDocsService with new methods for loading specs
- Update schemas and analysis service to use new agent structure
- Update all frontend components to use new agent names and properties
- Update mock data in Projects.tsx and Campaigns.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:58:17 -06:00
michael
f24b7c7905 Add comprehensive Barclays brand specification for Gemini analysis
Creates prompts/brand_barclays.md with complete brand guidelines including:
- Sacred assets (Eagle, Portal, Cyan)
- Logo/Eagle specifications with sizing rules
- Portal sizing and treatment guidelines
- Full masterbrand color palette (24 colors with hex codes)
- Typography rules (Barclays Effra, 5 weights)
- Digital, social media, email, and advertising guidelines
- Accessibility requirements (WCAG AA/AAA)
- Common violations checklist for brand assessment

This spec is sent to Gemini when users select "Barclays" brand for
proof analysis, providing condensed guidelines for accurate assessment.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:41:10 -06:00
michael
2cd3b2b9ae Add brand selection support for Barclays vs Barclaycard guidelines
- Add brand field to AnalyzeProofOptions interface and WebSocket message
- Pass campaign's brandGuidelines to analyzeProof in App.tsx (upload & retry)
- Extract brand from WebSocket message in handlers.py and pass to analysis
- Update AnalysisService.analyze_proof to accept brand parameter
- Refactor BrandAgent to dynamically select brand spec based on brand param
- Add get_barclays_brand_spec() method to ReferenceDocsService (placeholder)

The brand agent now uses the appropriate specification (Barclaycard spec or
Barclays spec when available) based on the campaign's brandGuidelines setting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:31:59 -06:00
michael
d3e7f99be0 Add comprehensive Barclaycard brand specification for Gemini analysis
- Create prompts/brand_barclaycard.md with structured brand guidelines
  covering logo, Card Portal, colors, typography, and accessibility
- Update ReferenceDocsService with get_barclaycard_brand_spec() method
- Update BrandAgent to use the new spec instead of raw reference docs
- Spec is ~15KB vs ~293KB of raw docs for more efficient analysis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:25:46 -06:00
michael
b52162b111 Fix vertical text alignment in RAG status badges for PDF export
Add lineHeight: 1 to RagStatusBadge component styling to ensure text
is tightly contained within its bounding box, allowing flexbox centering
to work correctly in PDF rendering engines.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:52:11 -06:00
michael
ec2fb82205 Make Gemini analysis responses concise and actionable
Add explicit formatting instructions to agent prompts requesting bullet-point
output instead of verbose paragraphs. Update JSON schema descriptions for
feedback and summary fields to enforce concise, outline-style format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:48:08 -06:00
michael
e094014dbe Improve CLAUDE.md and README.md with backend documentation
- Add workflow instruction to commit and push after code changes
- Add backend development commands (Python venv, uvicorn)
- Add database commands (Alembic migrations)
- Expand environment setup for both frontend and backend
- Document backend architecture (agents, services, repositories, models)
- Add PostgreSQL and Alembic to tech stack
- Update data persistence section for backend storage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:42:39 -06:00
michael
c1030ee292 Add PDF rasterization support for reliable preview and analysis
PDFs are now converted to PNG images at 200 DPI before being sent to
Gemini for analysis. This fixes the unreliable iframe-based PDF preview
and ensures all pages are properly analyzed.

- Add PyMuPDF dependency for PDF rasterization
- Create pdf_service.py with rasterize() and get_page_count()
- Update agent interfaces to accept list of images for multi-page support
- Add analyze_with_images() to Gemini service for multi-image analysis
- Return rasterized PDF pages via WebSocket for frontend display
- Add page navigation UI for multi-page PDFs in preview components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:36:56 -06:00
michael
caf4539e1d Fix analytics pass rate calculation and add Analysis Errors stat
- Exclude errors from pass rate denominator since they weren't successfully reviewed
- Add missing Analysis Errors stat card to display error count
- Update grid layout to accommodate 5 stat cards

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:19:44 -06:00
michael
a4d67fdf46 Format campaign last modified date for better readability
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:09:10 -06:00
michael
f1776df710 Persist navigation state in URL for browser refresh support
- Add URL utility functions for parsing and building URL state
- Initialize app state from URL parameters on page load
- Sync navigation changes to URL via browser history API
- Handle browser back/forward navigation with popstate listener
- Support deep linking to campaigns and proofs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:04:04 -06:00
michael
e2fd9549f7 Add support email functionality via Mailgun
Backend:
- Add email_service.py with Mailgun API integration
- Add SupportEmailRequest schema for email endpoint
- Add Mailgun config settings (API URL, key, from address, support email)
- Update .env.example with Mailgun configuration variables

Frontend:
- Update Login.tsx SupportModal to send emails via /api/support/email
- Update Profile.tsx question form to send emails via apiService
- Add loading states, success/error feedback, and auto-close on success

The support forms on both the login page and profile page now actually
send emails to the support team instead of just showing alerts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 07:03:11 -06:00
michael
b119951f93 Fix retry button for failed proofs and hook up download asset button
- Add GET /files/{storage_key:path} endpoint to serve stored files
- Add getFile() method to apiService to fetch files from backend
- Update convertProofToFrontend() to preserve fileStorageKey
- Update handleRetryAnalysis() to fetch file from backend when not in memory
- Update handleDownload() to download original file instead of thumbnail

After page refresh, the retry button now fetches the original file from
backend storage using the fileStorageKey, allowing failed proofs to be
reprocessed. The Download Asset button also now downloads the original
uploaded file rather than the preview thumbnail.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 07:01:58 -06:00
michael
94a37f3ed8 Add migration to cleanup duplicate dropdown options
The staging database has duplicate sub-channels (5 "Meta", 2 "Magazine")
which causes the last duplicate (with 0 proof types) to overwrite the
correct one in the API response.

This migration:
1. Identifies duplicate sub-channels and channels
2. Keeps the one with the most children (proof types)
3. Deletes the duplicates
4. Adds unique partial indexes to prevent future duplicates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:22:44 -06:00
michael
874c1fceee Add debugging for proof types not showing in dropdown
Backend logging:
- Log channel, sub-channel, and proof type counts in get_all_hierarchical()
- Log Meta proof types specifically
- Log API response for Social.Meta

Frontend logging:
- Log raw API response in apiService
- Log dropdown options in App.tsx when loaded
- Log available proof types in UploadProofModal when channel/subchannel selected

This will help diagnose why Meta proof types are not appearing on staging.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:09:25 -06:00
michael
3b868f7415 Fix proof types not loading for sub-channels in dropdown hierarchy
Replace nested selectinload chain with separate explicit queries for
channels, sub-channels, and proof types. The self-referential
selectinload chain didn't reliably load the third level (proof types)
in async SQLAlchemy.

Also add order_by to DropdownOption.children relationship for
consistent ordering.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:01:39 -06:00
michael
d2d01aaea7 Fix campaign update by re-fetching after flush
The previous refresh() call only reloaded relationships, not scalar
attributes like updated_at. Re-fetching via get_by_id ensures all
attributes and relationships are properly loaded.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:27:26 -06:00
michael
f4fd850a49 Force recreate backend container on deploy
Ensures new code changes are picked up by using --force-recreate
flag when starting the backend container.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:24:43 -06:00
michael
37c2532263 Fix async SQLAlchemy MissingGreenlet error on campaign update
Refresh campaign object after flush to reload expired attributes
and relationships, preventing lazy load failures in async context.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:20:56 -06:00
michael
96d459c322 Center text in PDF report status badges
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:13:20 -06:00
michael
091f9ecd87 Add proof types for Meta sub-channel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:07:28 -06:00
michael
74930d623f Replace agent icons with clean Heroicons
Replaced custom AI-generated icons with standard Heroicons for a more
professional appearance on the home page.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:02:28 -06:00
michael
8038e4014e Make Workfront Campaign ID optional and propagate to proofs
The Workfront Campaign ID field is now optional when creating campaigns.
When provided, it is used as the base for proof workfront IDs instead of
generating random ones.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:49:23 -06:00
michael
abfcb6aae2 Fix campaign status change not persisting in UI
Use optimistic update pattern to immediately reflect status changes
in the UI, with rollback on API error.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:31:59 -06:00