Upload Excel media plans per client. On QC analysis, automatically
match the uploaded file's name against the media plan's Asset IDs
to validate dimensions and file type, and include the media plan
context (country, language, placement, vendor) in QC check prompts.
- New backend/media_plan_processor.py: Excel parsing, fuzzy filename
matching, dimension/file-type validation, prompt context builder
- New backend/media_plans/ directory for storage
- API endpoints: POST/GET/DELETE /api/media_plan
- Settings modal: new "Media Plan" tab for upload/manage
- Analysis flow: auto-match + validation in response + context in prompts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PDF brand guidelines were previously ignored - QC checks received no
content from uploaded PDFs. Now on upload, all pages are text-extracted,
summarized by Gemini into a structured brand guidelines summary, and
a cover image is extracted. QC checks receive the full summary in their
prompt and the cover image as visual reference.
- New backend/pdf_processor.py: text extraction, cover image, LLM summary
- brand_guidelines_db.py: summary/cover path tracking, cleanup on delete
- api_server.py: background processing on upload, summary-aware content
retrieval, PDF cover image support, status/reprocess endpoints, startup
backfill for existing unprocessed PDFs
- web_ui.html: processing status badges and upload feedback for PDFs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-save reports to client-specific subfolder (was saving to root)
- Read client_id from form data (matching what frontend sends)
- Add Amazon to profile-based client detection fallback
- Fix get_client_from_profile matching 'static' as L'Oreal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Convert admin panel from popup modal to dedicated full page section
- Log user_login events on auth status check to track all visitors
- Admin user list now shows all users (login visitors + analysts)
- Fix cost field name (total_cost_usd vs estimated_cost_usd fallback)
- Round scores to 2 decimal places in reporting tables
- Reset reporting dashboard when switching clients
- Clear stale data on client switch before loading new client
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move reporting from settings modal into a dedicated tab within each
client's main view with date range filtering, usage stats, and cost
tracking. Add admin panel with platform-wide user activity overview,
accessible only to configured admin users.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For the loreal_static profile only, override the grade to Fail if any
single check scores below 6, regardless of the overall weighted score.
Both checks must pass for the asset to pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create visual_readability_contrast combined check merging text readability
and background contrast into a single LLM call for L'Oreal Static profile
- Update loreal_static.json to use combined check (2 checks, 100-point scale)
- Add client_id filtering to brand guidelines (upload, fetch, backfill migration)
- Restructure settings modal from 5 tabs to 4: Profile, Create New Profile,
Reference Assets, Reporting (removed Model Selection, merged Tools into Profile)
- Add GET /api/profile_usage_stats endpoint with summary cards and recent analyses
- Add POST /api/consolidate_reports endpoint generating HTML summary with
pass/fail highlighting from multiple selected reports
- Add report selection checkboxes and consolidation controls to saved files list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Log client_filter parameter received by backend
- Log selectedClient value in frontend
- Log number of files returned
- Help diagnose why all files are showing for all clients
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## New Features
### L'Oréal Static General Profile
- Created new profile with 3 checks optimized for digital marketing assets
- Even weighting (33.3% each) for 100-point scoring scale
- Removed print-specific requirements (3m viewing distance)
- Focus on marketing text vs product packaging distinction
### Multi-File Queue System (web_ui.html)
- Added file queue functionality for batch processing
- Users can now upload and process multiple files simultaneously
- Queue displays file status (pending, analyzing, complete, error)
- Individual file removal and queue clearing options
- Progress tracking for batch operations
### New General QC Checks
1. background_contrast_general
- Optimized for digital assets (no distance requirements)
- Checks logo, product, and marketing text contrast
- Detects overlapping and blending issues
- Provides element-by-element breakdown
2. text_readability_general
- Focus on marketing text only (excludes product packaging)
- Checks for overlapping elements
- Digital readability optimization
- Specific issue identification
3. language_consistency (enhanced)
- Better distinction between marketing and packaging text
- Detailed language detection and reporting
- Lists specific text analyzed
### Usage Tracking System
- Added usage_tracker.py for analysis logging
- Tracks user activity, profile usage, and costs
- Daily log files in JSONL format
- Cost estimation per LLM provider
## Bug Fixes
### Authentication & User Management
- Fixed Flask 'g' import missing issue
- Fixed user info access in background threads
- Pass user_info to threads instead of accessing g.user
- Improved error handling for usage logging
### HTML Report Generation
- Fixed missing analysis details in reports
- Now extracts and displays all JSON fields properly
- Shows comprehensive breakdowns:
- Analysis details
- Elements checked (logo, product, text)
- Marketing text found
- Issues identified
- Specific recommendations
- No more blank "Pass/Fail" results
### Scoring System
- Fixed usage_tracker to handle dict of check results (not list)
- Better handling of model_used field variations
- Skip non-dict check results gracefully
## Configuration Changes
### Model Versions (llm_config.py)
- Fixed invalid GPT-4.1 model ID to gpt-4o
- Added Gemini 3 Pro beta model option
- AVAILABLE_MODELS dict for UI selection
- Model version override support
### Profile Updates
- Static General: 3 checks, total weight 10.0
- Each check: text_readability_general (3.33), background_contrast_general (3.33), language_consistency (3.34)
- Maximum score: 100 points
## Technical Improvements
- Enhanced prompt engineering for consistent LLM outputs
- Mandatory detailed explanations in all checks
- Structured JSON responses with comprehensive fields
- Better error messages and fallback handling
- Client configuration support (client_config.py)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added weight_scale support for profiles (default 100)
- Enhanced /api/profiles endpoint to return detailed profile data
- Includes check weights, LLM assignments, and enabled status
- Matches functionality from root api_server.py for production deployment
Applied the same web_ui.html path fix to backend/api_server.py that
was previously applied to the root api_server.py. The backend version
needs to reference the parent directory since web_ui.html is located
at /opt/ai_qc/web_ui.html while api_server.py is in /opt/ai_qc/backend/.
This fixes the 404 error when running via Waitress production server.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>