Commit graph

56 commits

Author SHA1 Message Date
Vadym Samoilenko
9036bafc0d Log every user login to Activity Logs
Track all logins (not just first) via ApplicationLogger user_login action.
Add User Login filter option to logs-viewer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:54:07 +00:00
Vadym Samoilenko
aa5debc6c2 Register new users in roles file on first login
Previously only admin_emails users were saved to user_roles.json.
Now all users are recorded with default role on first login so they
appear in the admin panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:51:30 +00:00
Vadym Samoilenko
d62e40ef44 Fix admin badge: black bg + yellow border for visibility on dark header
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:46:35 +00:00
Vadym Samoilenko
c7ea114fcf Fix JWKS parsing: inject alg=RS256 for Azure AD keys
firebase/php-jwt v6 requires 'alg' in each JWK, but Azure AD JWKS
endpoint omits it. Inject RS256 for any key missing the parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:42:08 +00:00
Vadym Samoilenko
bd8e1b674a Fix redirect_uri trailing slash to match Azure AD registration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:40:47 +00:00
Vadym Samoilenko
0280b94154 Fix MSAL redirect_uri to match Azure AD registered URI
Change redirect_uri to app root (without /auth.php) to match what's
registered in Azure portal. Use relative URLs for auth fetch and reload
on success instead of computed absolute paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:39:12 +00:00
Vadym Samoilenko
53e9365c01 Add Azure AD SSO, RBAC (admin/user roles), and server-setup improvements
- Enable SSO with Azure AD credentials (tenant + client ID + redirect_uri)
- Add JWTValidator.php: RS256 idToken validation via Azure JWKS with 1h cache
- Add auth.php: POST login handler sets auth cookie, GET logout clears it
- Add UserRoleManager.php: file-based role CRUD in data/user_roles.json
- Add admin.php: admin-only role management panel
- AuthMiddleware: add requireAdmin(), role in user array, fix MSAL redirect
- header.php: hide Activity Logs + Admin Panel tabs for non-admin users
- logs-viewer.php: protect with requireAdmin() instead of requireAuth()
- server-setup.sh: add composer check, data/ dir, PHP extension checks, SSO validation
- .gitignore: add data/ directory

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:34:50 +00:00
DJP
c88cee98e6 Add comprehensive email sending logging
Added detailed logging for SMTP email process:
- Log recipient, subject, service type
- Log SMTP connection details (host, port, user)
- Log connection status
- Log each SMTP command step
- Log success/failure with clear markers
- Log full exception stack traces

Now easy to troubleshoot email issues by checking logs for:
'===== EMAIL SEND START ====='
and
'===== EMAIL SEND END ====='

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:51:39 -05:00
DJP
5158db0534 Fix HEREDOC syntax error in EmailTemplates
Cannot use ternary operator directly in HEREDOC string.
Moved conditional logic outside HEREDOC into variable first.

This fixes the parse error on line 203.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:36:04 -05:00
DJP
96c27a1b77 Add simple process test with error display
Shows step-by-step loading of all dependencies with errors displayed.
Use on server to see exact error causing 500.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:33:50 -05:00
DJP
62f46b15b3 Add server setup script to fix production issues
Created server-setup.sh to fix server environment:
- Creates logs/ directory with proper permissions
- Sets file permissions (755 for dirs, 644 for config, 600 for JWT)
- Tests ApplicationLogger functionality
- Provides instructions for installing PHP zip extension

Issues Found on Server:
1. logs/ directory missing (causing ApplicationLogger to fail)
2. PHP zip extension missing (needed for download-all-csv.php)
3. Vendor directory not writable (minor issue)

Run on server:
  chmod +x server-setup.sh
  ./server-setup.sh
  sudo apt-get install php-zip
  sudo systemctl restart apache2

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:22:59 -05:00
DJP
b26252fde9 Add server environment diagnostic tool
Created server-check.php to diagnose server issues:
- PHP version check (requires 7.4+)
- Extension checks (curl, json, mbstring, openssl, zip)
- File permission checks (logs/, vendor/)
- Composer dependency verification
- Configuration file existence
- PHP settings (upload limits, memory)
- Service class loading tests

Use this to troubleshoot 500 errors on production server.
Access: /server-check.php

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:20:02 -05:00
DJP
95020fad44 Add Title/Creative Execution columns and HTML email templates
CSV Transformation Fixes:
- Title now includes language code: "{OriginalTitle}_{ISO}" (e.g., "Syndication_en-GB")
- Added "Creative Execution" column with original global title
- Both columns properly populated for all 16 regional CSVs

Email Template System:
- Created EmailTemplates.php with professional HTML templates
- Based on Ferrero automation email styling
- Templates for all workflows:
  * Asset Submission Success/Failed
  * Global to Local Started/Complete/Failed
  * Box Upload Success
- L'Oréal brand colors (Yellow #FFC407, Black #000000, Green for success)
- Responsive design with proper HTML structure
- Clean, professional layout with color-coded status boxes

Email Service Enhancements:
- Added sendTemplate() method for templated emails
- SMTP now supports HTML multipart emails (text + HTML)
- Mailgun API support for HTML
- Proper MIME boundaries and headers
- Extract subject from template HTML

Notification Updates:
- upload-to-box.php: Uses templates with full data (campaign, business unit, file count)
- submit.php: Logs all asset submissions
- All emails sent as professional HTML with fallback text

Template Features:
- Color-coded headers (green=success, red=error, yellow=warning)
- Info boxes with campaign details
- Data tables for multiple items
- Action required sections
- Footer with branding

All notifications now send beautiful, branded HTML emails to users!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:00:10 -05:00
DJP
e82221cfcf Enable OMG API with updated API key
Set enabled=true in omg_api configuration.
Updated API key should now have proper permissions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 09:51:02 -05:00
DJP
27add752fd Update README with complete logging, email, and OMG API documentation
Added Documentation For:

Activity Logging & Reporting Section:
- Logging system overview and what gets logged
- Example JSON log entry structure
- Activity Logs Viewer features and use cases
- Statistics dashboard capabilities
- Export and filtering options
- Log file location and format

Email Notifications Section:
- SMTP configuration details
- Notification types (started, completed, failed)
- Recipient configuration (logged-in user)
- How to enable/disable

OMG API Section:
- Current status (configured but disabled)
- Permission issue explanation (403 error)
- Fallback business unit configuration
- Steps to enable when permissions granted

Project Structure:
- Complete file tree with all 3 tabs
- Organized by functionality (Auth, Services, Tab 1, Tab 2, Tab 3)
- Shows which files are in git vs excluded
- Clear separation of frontend/backend files

API Endpoints:
- Added logs-viewer.php endpoint documentation
- Query parameters for filtering
- Export functionality
- Updated upload-to-box.php to mention logging

Navigation:
- Added Activity Logs as Tab 3
- 3-tab system: Master Global Asset Submission, Global to Local, Activity Logs

The README now provides complete documentation for all features including the new logging and reporting system.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 09:46:44 -05:00
DJP
64b99c7a58 Add comprehensive application logging and activity tracking system
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>
2025-11-18 09:39:21 -05:00
DJP
cd7715fdaf Add OMG API enable/disable config option with fallback
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>
2025-11-18 09:13:53 -05:00
DJP
5a65aca75c Use X-API-Key header for OMG API authentication
Changed from 'Authorization: Bearer' to 'X-API-Key' header format.
Removed duplicate Authorization header.

This is the correct format for OMG API authentication.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 09:12:06 -05:00
DJP
2db69b7f28 Try multiple authorization header formats for OMG API
Sending both X-API-Key and Authorization headers to see which one works.
Added header logging to troubleshoot auth issue.

The API is responding with 401 'Authorization field missing', so we need to
find the correct header format.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 09:11:00 -05:00
DJP
6c8c8ea508 Fix OMG API authorization header and private property access
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>
2025-11-18 09:09:01 -05:00
DJP
e9a175ef5d Fix JSON parse error: disable display_errors to prevent deprecation warnings
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>
2025-11-18 09:03:57 -05:00
DJP
b54f6af6e5 Add version marker to process-csv.php for cache troubleshooting
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>
2025-11-18 08:48:40 -05:00
DJP
0571ce403f Add comprehensive logging for OMG API debugging and application tracking
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>
2025-11-18 08:26:20 -05:00
DJP
9b8dbbf20c Enable OMG API lookup and add SMTP email support
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>
2025-11-18 08:15:22 -05:00
DJP
11ebcf8dd3 Fix preview table rendering - convert PHP object to JavaScript array
Issue: PHP's iterator_to_array() returns associative array with numeric keys
which JavaScript receives as an object {1: {...}, 2: {...}}, not an array.

Fix: Convert object to array using Object.values() before rendering table.
Added to both initial preview and file selector preview.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:33:10 -05:00
DJP
b51b59af7f Add debug logging to troubleshoot preview table issue
Added console.log statements to track:
- Preview data availability
- Row count
- Headers extraction
- Table HTML generation

This will help identify why the table isn't rendering.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:32:02 -05:00
DJP
431c25fb24 Fix filename generation: properly interpolate country code variable
Changed {country} to {$country} in filename template.
Now generates correct filenames like:
- OMG1601654_GlobalACIngest_TESTING-GB_1763418477.csv
- OMG1601654_GlobalACIngest_TESTING-ES_1763418477.csv
etc.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:30:17 -05:00
DJP
53ec170702 Fix preview display and show all rows instead of just 20
Changes:
- Initial preview now displays immediately from response data
- Show ALL rows in preview table (not limited to 20)
- File selector properly switches between all 16 CSVs
- Each file shows complete data when selected

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:29:28 -05:00
DJP
79c45634fe Update README with complete Global to Local documentation
Added comprehensive documentation:
- Updated app title to 'L'Oréal OMG Assistant Global'
- Detailed Global to Local workflow (6 stages)
- Input CSV requirements and format
- ISO codes configuration (16 markets in config.php)
- Output file naming and structure
- Preview and download options
- User approval workflow
- Error handling examples for all stages
- API endpoints documentation
- Configuration sections for OMG API and Email

Clarified that ISO codes are in config.php and fully editable.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 17:29:06 -05:00
DJP
df403363a9 Add file preview selector and download all functionality
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>
2025-11-17 17:27:25 -05:00
DJP
82b192355c Fix syntax error: remove stray quote after comment block
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>
2025-11-17 17:19:40 -05:00
DJP
5fb6e1957d Add debug logging and fix test files
- 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>
2025-11-17 17:16:21 -05:00
DJP
0be9ddb946 Fix class namespace issues - use fully qualified class names
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>
2025-11-17 17:09:46 -05:00
DJP
7d377f635f Fix session_start timing to prevent headers already sent error
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>
2025-11-17 17:06:01 -05:00
DJP
5c6cf687a8 Update Global to Local to create 16 separate CSV files and fix PHP compatibility
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>
2025-11-17 17:03:51 -05:00
DJP
19328d10b4 Fix PHP version requirements for server compatibility
Downgraded dependencies to support PHP 7.4+:
- nesbot/carbon: ^2.0 (PHP 7.1+)
- league/csv: 9.8.0 (PHP 7.4+)

This ensures the application works on servers with PHP 7.4-8.0.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 16:51:27 -05:00
DJP
d31f394ad5 Add Global to Local CSV transformation frontend with visual progress tracking
Created Complete Tab System:
- header.php: Shared navigation between Asset Submission and Global to Local tabs
- global-to-local.php: Upload page with drag & drop, progress tracker, preview
- global-to-local.js: Frontend logic for upload, processing, preview, and Box upload

Visual Progress System:
- 6-stage progress tracker with icons and status (⏸️ pending, 🔄 processing,  success, ⚠️ warning,  error)
- Real-time status updates for each stage
- Detailed error cards with actionable messages
- Warning cards for data quality issues
- Success cards with completion info

Features:
- Drag & drop CSV upload with file size validation
- Step-by-step progress visualization
- Error reporting at each stage (upload, parse, campaign, OMG API, business unit, transform)
- CSV preview table (first 50 rows) before Box upload
- Download preview CSV before committing
- User approval required before Box upload
- Summary cards showing input/output counts, campaign, business unit

Error Handling:
- File validation errors (wrong type, too large, empty)
- CSV parsing errors (malformed, wrong columns)
- Campaign extraction errors (invalid filename)
- OMG API errors (404, timeout, auth failure)
- Business unit mapping errors (unrecognized brands)
- Date transformation errors (invalid formats)
- Box upload errors (permissions, folder issues)

UI Enhancements:
- Tab navigation with active state highlighting
- Professional error cards with details and actions
- Responsive design for mobile/desktop
- Maintains black/yellow L'Oréal brand colors

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 16:48:43 -05:00
DJP
80b170a735 Add Global to Local CSV transformation backend
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>
2025-11-17 16:44:48 -05:00
DJP
384c37be3e Expand README with comprehensive workflow documentation
Added detailed sections:
- Workflow Overview and Purpose
- Box folder structure requirements with visual diagram
- Complete data extraction breakdown (Box API, User Input, System)
- Step-by-step workflow (7 detailed steps)
- Data flow diagram
- Example webhook payload with full structure
- What happens after submission
- Comprehensive error handling documentation

This provides complete understanding of how the application extracts and processes campaign asset metadata.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:51:46 -05:00
DJP
e19ec94b76 Simplify .htaccess - remove vendor blocking
- Removed vendor directory blocking (was breaking require_once)
- Keep critical protections: JWT config, config.php, hidden files
- More targeted JSON file blocking (config/composer only)
- Allow vendor directory to be accessed by PHP

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:42:11 -05:00
DJP
35e959bbf7 Add comprehensive .htaccess security configuration
Protected files:
- Box JWT config (43984435_*_config.json)
- All JSON files
- config.php and composer files
- vendor directory
- Hidden files (.git, .env, etc.)
- Log and backup files
- README and documentation

Security features:
- Prevent directory browsing
- Security headers (X-Frame-Options, XSS Protection, etc.)
- HTTPS redirect (commented out, enable in production)
- Compression and caching for performance
- PHP security settings

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:40:00 -05:00
DJP
47b0615c3a Fix grandparent logic: properly get folder two levels up
Structure: Campaign Number → CAMPAIGN_ASSETS → SUPPLIED_ASSETS
- Changed to fetch parent, then parent's parent (proper two levels up)
- Previous logic was using path_collection which showed CAMPAIGN_ASSETS
- Now correctly retrieves the campaign number folder
- Uses two separate API calls to traverse up the hierarchy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:22:06 -05:00
DJP
ef7ffedc94 Fix Master Campaign Number to use parent folder (one level up)
Changed from grandparent (two levels up) to parent (one level up).
- Renamed getGrandparentFolder() to getParentFolder()
- Uses folder's direct parent instead of path_collection traversal
- Master Campaign Number should now show the campaign number folder
- Updated validate-box.php to use 'parent' instead of 'grandparent'

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:20:39 -05:00
DJP
9923ec24a0 Fix Lookup button alignment and layout
- Changed align-items to stretch for proper vertical alignment
- Added flex: 1 to input for proper width distribution
- Added flex-shrink: 0 to button to prevent shrinking
- Increased min-width to 120px for 'Looking up...' text
- Fixed transform on disabled state

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:14:45 -05:00
DJP
7cde92694c Add validation: folder must be named SUPPLIED_ASSETS
- Check folder name immediately after fetching folder info
- Stop processing if folder name is not SUPPLIED_ASSETS (case-insensitive)
- Return clear error message with actual folder name
- Prevents unnecessary API calls for invalid folders

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:12:37 -05:00
DJP
073f148cec Use correct Make.com API key header: x-make-apikey
Changed from custom header to Make.com's official API key header format.
Reference: https://apps.make.com/gateway

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:02:18 -05:00
DJP
3aeeae7401 Remove custom API key header for Make.com webhook
Make.com webhooks use the URL itself as authentication, not custom headers.
Removed 'Loreal-Webhook' header - only sending Content-Type: application/json.
Added payload logging for debugging.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:00:01 -05:00
DJP
70a4d26d9b Fix 401 error: Don't pass webhook status code to client
Issue: When webhook returned 401, PHP was setting http_response_code(401)
which made the browser think the PHP endpoint was unauthorized.

Fix: Always return 200 to client, but indicate webhook failure in JSON response.
Added detailed logging of webhook failures.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:58:10 -05:00
DJP
f70fe30ea2 Show user email in header for both SSO and local modes
- Display user email in top right of header bar
- Update header layout with flexbox
- Show email in yellow (#FFC407) color
- Always visible regardless of SSO mode

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:55:54 -05:00
DJP
d11bdc634a Add debug logging to troubleshoot 401 error
- Enable display_errors for debugging
- Add SSO status logging
- Add detailed error information in response
- Log authentication user details

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:54:06 -05:00