Commit graph

18 commits

Author SHA1 Message Date
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
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
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
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
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
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
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
0e6f5be46d Support both v1.0 and v2.0 Azure AD token issuer formats
Azure AD issues tokens with different issuer formats depending on the
app registration's accessTokenAcceptedVersion setting:
- v1.0: https://sts.windows.net/{tenant}/
- v2.0: https://login.microsoftonline.com/{tenant}/v2.0

Update backend to accept both formats by trying each issuer in sequence.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 17:03:47 -06:00
michael
dd5ee09d07 Fix JWT signature verification by requesting correct token audience
- 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>
2025-12-18 16:59:54 -06:00
michael
04527d65db Add MSAL debug logging to frontend and backend
- Frontend: Set MSAL log level to Info, add [MSAL] prefix
- Frontend: Add [MSAL Auth] logs for token acquisition
- Frontend: Add [MSAL Login] logs for login popup flow
- Backend: Add [MSAL Backend] logs for token verification
- Backend: Add [MSAL Backend] logs for auth dependency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 13:11:30 -06:00
Michael Clervi
dc17cd087c permissions changes 2025-12-18 16:51:27 +00:00
michael
5b9e824da9 Use OpenID scopes instead of custom API scopes
- 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>
2025-12-18 10:50:02 -06:00
michael
99af0164e6 Add PostgreSQL database support with Alembic migrations
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>
2025-12-16 12:27:18 -06:00
michael
321a9ca820 Implement Microsoft MSAL SSO with PKCE flow
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>
2025-12-16 08:43:30 -06:00
michael
e97d0e935c initial commit 2025-12-12 09:03:17 -06:00