ApplicationLogger Class:
- Structured JSON logging to logs/application.log
- Tracks all actions: master_asset_submission, global_to_local_transform, box_upload, omg_api_lookup
- Captures: timestamp, user email/name, status, detailed data, IP address, user agent
- Methods: getRecentLogs(), getLogsByAction(), getLogsByUser(), getStatistics()
Logging Integration:
- submit.php: Logs all asset submissions (success/failure)
- process-csv.php: Logs all CSV transformations
- upload-to-box.php: Logs all Box uploads
- Tracks campaign numbers, business units, file counts, dates
Logs Viewer (logs-viewer.php):
- New tab "Activity Logs" in navigation
- Statistics dashboard (total actions, success rate, errors, unique users)
- Filterable table (by action type, user, date range)
- View detailed data for each log entry (expandable JSON)
- Export to CSV functionality
- Shows last 100 entries by default (configurable)
Email Service Enhancement:
- Added SMTP support (in addition to Mailgun API)
- Configured for smtp.mailgun.org with provided credentials
- Sends notifications to logged-in user email
- Proper SMTP protocol implementation with AUTH LOGIN
OMG API Configuration:
- Added 'enabled' flag (currently false due to 403 error)
- Added 'fallback_business_unit' for when OMG disabled
- Uses X-API-Key header format
- Comprehensive error logging
- When API permissions are fixed, set enabled=true
Security:
- logs/ directory excluded from git
- .gitkeep file to preserve directory structure
- Protected by .htaccess (log files already blocked)
Usage:
- All activity automatically logged
- View reports at /logs-viewer.php
- Export logs as CSV for analysis
- Filter by action type, user, or time period
- Monitor system health and usage patterns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added 'enabled' flag to omg_api config (default: false).
Added 'fallback_business_unit' for when OMG API is disabled or fails.
Current API key returns 403 'Access to this API has been disallowed'.
Need to request proper permissions from OMG team for /loreal/v1/getProject endpoint.
For now, set enabled=false to use fallback business unit 'TESTING'.
When API key is updated with proper permissions, set enabled=true.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed two issues:
1. Removed 'Bearer' prefix from Authorization header (OMG API expects just the key)
2. Fixed private property access error (hardcoded endpoint URL instead of accessing $omgService->config)
OMG API now sends: Authorization: PeyJvcmciOiIy...
Instead of: Authorization: Bearer PeyJvcmciOiIy...
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Issue: PHP deprecation warnings from league/csv were being output as HTML
(<br /><b>...) which broke JSON parsing in browser.
Fix: Set display_errors=0 in process-csv.php while keeping log_errors=1.
Errors still logged to error_log but not output to browser.
Reverted test-upload endpoint back to process-csv.php.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added log message at start to confirm correct version is running.
This helps identify if browser is caching old JavaScript or server is serving old PHP.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
OMG API Debug Logging:
- Log full URL being called
- Log API key (first 20 chars for security)
- Log HTTP response code
- Log response body (first 500 chars)
- Log campaign number and business area extraction
- Log business unit mapping result
ApplicationLogger Class:
- Structured JSON logging to logs/application.log
- Track all actions: master_asset_submission, global_to_local_transform, box_upload
- Capture user email, timestamp, IP address, user agent
- Methods for reporting: getRecentLogs(), getLogsByAction(), getLogsByUser()
- Generate statistics: total actions, by user, by action, errors
Email Configuration:
- Configured SMTP via Mailgun (smtp.mailgun.org:587)
- Using twist@mail.dev.oliver.solutions
- Emails sent to logged-in user
This enables full audit trail and troubleshooting capability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Email Configuration:
- Added SMTP support via Mailgun (smtp.mailgun.org:587)
- EmailService now supports both Mailgun API and SMTP
- Configured to use twist@mail.dev.oliver.solutions
- Emails sent to logged-in user (SSO email or local dev email)
OMG API:
- Enabled OMG API lookup in process-csv.php
- API key configured in config.php
- Looks up business unit from campaign number
- Falls back to 'ERROR' if business unit not recognized
SMTP Implementation:
- Full SMTP protocol with AUTH LOGIN
- Proper error handling and logging
- Fallback to Mailgun API if SMTP fails
Notifications sent to user email:
- Process started notification
- Process completed notification (with file count)
- Error notifications
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Title Changes:
- App title: "L'Oréal OMG Assistant Global"
- Tab 1: "Master Global Asset Submission"
- Upload button: "Approve & Upload to OMG"
Preview Enhancements:
- Dropdown selector to preview all 16 CSV files individually
- Shows filename with ISO code (e.g., "en-GB - OMG1601654_...")
- Switch between files to view complete data for each
- Show ALL rows (not just first 20)
Download Features:
- "Download Current File" - Download the currently previewed CSV
- "Download All Files (ZIP)" - Download all 16 CSVs as a ZIP archive
- get-csv-preview.php: Endpoint to fetch any file for preview
- download-all-csv.php: Creates ZIP with all CSVs
UX Improvements:
- File selector styled with brand colors
- Clear labeling of which file is being previewed
- Easy navigation between all regional CSVs
- Test before upload with full data visibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Line 180 had */" which caused PHP parse error.
Changed to just */ to close comment block properly.
This was causing the 500 Internal Server Error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added error_log debugging to process-csv.php
- Fixed test-csv.php syntax (removed use statements in code)
- Created test-process2.php for step-by-step class loading test
- All service classes load successfully in tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed 'use' statements outside namespace context.
Changed to fully qualified class names:
- League\Csv\Reader
- League\Csv\Writer
- Carbon\Carbon
This fixes PHP 500 errors from improper use statements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved session_start() to top of process-csv.php before any output.
Removed duplicate session_start() call.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Key Changes:
- Fixed CSV transformation to create 16 separate files (one per ISO code)
- Each CSV has all input rows with Language/Country replaced
- Handles Excel Sep=, prefix correctly
- Parses date format "24 Mar 2025 00:00" from sample CSV
- Skip OMG API for testing (use business unit "TESTING")
- Upload all 16 CSVs to Box folder
- Show list of all files in preview
- Download preview functionality
PHP Compatibility:
- Downgraded nesbot/carbon to ^2.0 (supports PHP 7.1+)
- Downgraded league/csv to 9.8.0 (supports PHP 7.4+)
- Now compatible with PHP 7.4-8.0 servers
Preview Enhancements:
- Shows all 16 filenames with ISO codes
- Preview table shows first file as sample
- Summary shows file count and total rows
Testing:
- Added sample CSV: Project_1601654_mediaBookings.csv
- OMG API lookup commented out (ready to enable later)
- Using "TESTING" as business unit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Services Created:
- OMGService.php: OMG API integration with detailed error handling
- CSVTransformer.php: CSV parsing and transformation logic
- EmailService.php: Mailgun email notifications
- process-csv.php: Multi-stage CSV processing with progress tracking
- upload-to-box.php: Box upload with approval workflow
Features:
- Comprehensive validation at each stage (upload, parse, campaign, API, transform)
- Detailed error reporting with actionable messages
- Warning system for non-critical issues
- Progress tracking through all stages
- Session-based CSV storage for preview before upload
- Date transformation (parse + add 1 month per blueprint)
- 16x market multiplication per ISO codes
- Business unit mapping per Make.com blueprint logic
Dependencies Added:
- league/csv for CSV parsing
- nesbot/carbon for date manipulation
Configuration:
- Added global_to_local settings (ISO codes, business unit map)
- Added omg_api settings (placeholder for API key)
- Added email settings (Mailgun placeholders)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>