- 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>
- 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>
- 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>
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>
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>
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>
- Change frontend apiTokenRequest scopes from OpenID-only to CLIENT_ID/.default
This makes Azure AD issue tokens with audience = app client ID instead of Graph API
- Add diagnostic logging in backend to show token claims before verification
- Fixes 401 Unauthorized errors on all API calls after login
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change frontend scopes from api://{client_id}/.default to
openid, profile, email for simpler authentication
- Update backend token validation to expect ID token format:
- Audience: client_id (not api://{client_id})
- Issuer: v2.0 endpoint
This avoids requiring Application ID URI setup in Azure AD.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add PostgreSQL service to docker-compose with health checks
- Add SQLAlchemy async models for all entities (Agency, User, Campaign,
Proof, ProofVersion, FlaggedItem, ResolvedItem, ErrorItem)
- Add Alembic migration framework with initial schema migration
- Add repository layer for CRUD operations
- Add REST API endpoints for campaigns, proofs, and audit items
- Add file storage service for proof uploads
- Update WebSocket handler to optionally persist analysis results
Frontend:
- Add apiService.ts for REST API communication
- Update geminiService.ts to support database persistence options
Deployment:
- Update deploy.sh to handle database migrations (6-step process)
- Update Dockerfile to include alembic configuration
- Add PostgreSQL environment variables to .env templates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Frontend:
- Add @azure/msal-browser and @azure/msal-react packages
- Create authConfig.ts with MSAL configuration for PKCE flow
- Create authService.ts for token acquisition and user info
- Wrap App with MsalProvider in index.tsx
- Replace dummy login with real MSAL loginPopup() in Login.tsx
- Update App.tsx to use useIsAuthenticated/useMsal hooks
- Update Profile.tsx to display real user data from claims
- Update geminiService.ts to include access_token in WebSocket messages
- Update WIPReviewer.tsx to pass msalInstance for auth
Backend:
- Add python-jose and httpx dependencies for JWT verification
- Create auth_service.py with Azure AD JWKS fetching and token verification
- Create auth.py FastAPI dependency for protected REST endpoints
- Update main.py to verify tokens on WebSocket and protect /info endpoint
- Add AZURE_TENANT_ID, AZURE_CLIENT_ID, DISABLE_AUTH to config
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>