Commit graph

50 commits

Author SHA1 Message Date
DJP
00f35169a1 Add Global campaign search methods and update debug to show both Local and Global
StatusManager Enhancements:
 searchGlobalCampaigns() - Search for 'Global comm' campaigns (B1-B2 workflow)
 searchAllCampaignTypes() - Search for ALL campaigns (Local + Global)

Workflow Updates:
 Debug search now uses searchAllCampaignTypes()
 Shows both 'Local Adaptation' and 'Global comm' campaigns
 Updated success message: 'Local Adaptation + Global comm'

This fixes the issue where B1 campaigns weren't showing in debug view.

Test:
1. Click '🔍 Debug: Load ALL Campaigns' in any workflow tab
2. Should now see Global comm campaigns with B1/B2 status
3. Example: NUTELLA PLANT-BASED LAUNCH (Status: B1)

Next: Add dedicated B1→B2 workflow tab and status change buttons

🤖 Generated with Claude Code
2025-11-03 12:25:28 -05:00
DJP
c35d027724 Add dedicated CREATIVEX fields section to metadata viewer
Added CREATIVEX Field Display:
 New dedicated section in metadata viewer
 Purple border-left (color: #9b59b6) for visibility
 Shows count in summary: 🎯 CREATIVEX Fields (X)
 Grid layout: Field Name | Value
 Shows field ID below value for reference
 Auto-expanded (open attribute)
 Applied to both Master Assets and Final Assets views

MetadataExtractor Enhancement:
 Extracts all CREATIVEX fields separately
 Stores in metadata['creativex_fields']
 Handles both regular and tabular CREATIVEX fields
 Handles multiple value structures

Display Features:
- Field name as label
- Value displayed prominently
- Field ID shown below (gray text)
- Supports array values (comma-separated)
- Easy to identify with purple color
- Section expanded by default for visibility

CREATIVEX fields will now be prominently displayed in their own
section when viewing Master Assets or Final Assets metadata.

🤖 Generated with Claude Code
2025-10-31 10:05:30 -04:00
DJP
4e1a7fa588 Add video dimensions to upload and disable CREATOR field
Changes:
1. Default Box Folder ID
   - Pre-filled with: 348526703108
   - Saves time entering same folder repeatedly
   - Still editable for different folders

2. Video Dimensions in Upload Manifest
   - Extract video metadata via ffprobe (width, height, duration, bitrate)
   - Add width and height to upload manifest
   - Manifest now includes: file_name, file_type, width, height
   - Should fix Content Info showing -1 for Width/Height

3. CREATOR Field Disabled
   - "ExternalAgency" value still causes upload failure
   - Leaving CREATOR field from master unchanged
   - Need to investigate exact field structure

4. Working Field Updates (Re-enabled):
    ARTESIA.FIELD.ASSET DESCRIPTION → subject_title from filename
    FERRERO.FIELD.STATE → "Local"
    MAIN_LANGUAGES → language_code from filename

Upload Flow Now:
1. Parse V2 filename
2. Load master metadata from DB
3. Download file from Box
4. Extract video metadata (ffprobe)
5. Build MVP asset rep with field updates
6. Add video dimensions to upload manifest
7. Upload to DAM
8. Width/Height should populate (not -1)

Logging:
- "VideoMetadata: Extracted - 1024x576, 2s, 1006892 bps"
- "SIMPLE UPLOADER: Adding video dimensions to manifest - 1024x576"

🤖 Generated with Claude Code
2025-10-30 15:50:36 -04:00
DJP
f2fcaf65ef Add default Box folder ID and re-enable working field updates
UI Changes:
- Box Folder ID input now defaults to: 348526703108
- Pre-filled but still editable
- Saves time re-entering same folder

Field Updates RE-ENABLED (confirmed working):
1. ARTESIA.FIELD.ASSET DESCRIPTION
   - Set to subject_title from V2 filename
   - Example: "TEST-JOB11"

2. FERRERO.FIELD.STATE
   - Force to "Local" for all uploads
   - Valid domain value (Global/Local)

3. MAIN_LANGUAGES
   - Set from V2 filename language_code
   - Example: "de" → "DE"

Field Updates KEPT DISABLED:
- FERRERO.MARKETING.CREATOR
  - "Oliver Agency" is invalid (not in 1,893 domain values)
  - Keeping master value to avoid validation failure
  - Valid options: "ExternalAgency", "ExternalAgencynew"

Video Metadata:
- Extracted via ffprobe (width, height, duration, bitrate)
- Logged for reference
- Not sent to DAM (DAM analyzes automatically)

Result:
 Default folder ID saves time
 Description from filename
 State always Local
 Language from filename
 All uploads should work

🤖 Generated with Claude Code
2025-10-30 15:42:57 -04:00
DJP
5b050c2483 Add field updates from V2 filename and video file analysis
New Features:
1. VideoMetadataExtractor class
   - Uses ffprobe to extract video technical metadata
   - Width, height, duration, bitrate, aspect ratio
   - Frame rate, codec info
   - Formatted duration (HH:MM:SS:FF timecode)
   - Formatted aspect ratio (16:9, 4:3, etc.)

2. Updated MetadataExtractorMVP
   - Now accepts local file path parameter
   - Extracts video metadata from downloaded file
   - Updates fields from V2 filename:
     * ARTESIA.FIELD.ASSET DESCRIPTION ← subject_title from filename
     * FERRERO.FIELD.STATE ← Always "Local" for uploads
     * FERRERO.FIELD.MKTG.ASSET TYPE ← asset_type from filename
     * MAIN_LANGUAGES ← language_code from filename
   - Adds FERRERO.MARKETING.CREATOR ← "Oliver Agency"
   - Logs video dimensions and technical data

3. Workflow integration
   - Pass local file path to buildMVPAssetRepresentation()
   - Video analysis happens after Box download
   - File metadata extracted before upload

Field Updates Summary:
 Description → From filename (TEST-JOB11)
 State → Local (forced)
 Creator → Oliver Agency
 Main Languages → From filename (de → DE)
 Asset Type → From filename (OLV)
 Video metadata extracted (width, height, duration, bitrate)

Next: Test ffprobe extraction and determine where to inject video
technical fields in upload structure (content_info vs metadata).

🤖 Generated with Claude Code
2025-10-30 14:57:54 -04:00
DJP
b31664d88d Stage 2 Complete: Add missing MVP fields from V2 filename + Asset Rep JSON viewer
UI Improvements:
1. Fixed Final Assets metadata display format
   - Now matches Master Assets format (field names, not IDs)
   - Grid layout: "Asset Type: TVC" instead of "FERRERO.FIELD.MKTG.ASSET TYPE\nValue: TVC"
   - Collapsed/expandable categories
   - Same visual style as Master Assets

2. Added Asset Representation JSON viewer
   - 💾 Download button for each successful upload
   - 👁️ View button to see JSON in modal
   - Download saves as: asset_representation_{asset_id}.json
   - Modal view shows formatted JSON with syntax highlighting
   - Click outside modal to close

Stage 2 - V2 Filename Integration:
1. MetadataExtractorMVP.addMissingFieldsFromFilename()
   - Adds MAIN_LANGUAGES from V2 filename language_code (de → DE)
   - Updates FERRERO.FIELD.MKTG.ASSET TYPE from filename asset_type
   - Adds FERRERO.FIELD.ASSETCOMPLIANCE (default: -)
   - Adds MARKETING_TAG (default: Tag)

2. buildMVPAssetRepresentation() enhanced
   - Now accepts parsed V2 filename data
   - Extracts MVP fields from master (24 fields)
   - Adds missing fields from filename (up to 4 more)
   - Updates ASSET NAME to clean filename
   - Total: Up to 28 MVP fields

Logging:
- "Adding MAIN_LANGUAGES from filename: DE"
- "Updated ASSET TYPE from filename: olv"
- "Adding FERRERO.FIELD.ASSETCOMPLIANCE with default: -"
- Shows field count: "Found X out of 28 MVP fields"

Result:
 MVP fields extracted from master
 Missing fields filled from V2 filename
 Asset representation viewable/downloadable
 Metadata display matches Master Assets format

🤖 Generated with Claude Code
2025-10-30 14:28:12 -04:00
DJP
bad362e349 Fix Final Assets metadata display - use custom_fields instead of ferrero_fields
Issue: Final Assets showing only Basic Info and Content Info, no Ferrero metadata
Cause: Display was looking for 'ferrero_fields' but MetadataExtractor creates 'custom_fields'

Fix:
- Changed Final Assets metadata display to use custom_fields
- Now displays all metadata organized by category
- Shows format: 📁 Category Name (X fields)
- Each category is collapsible
- Same structure as Master Assets display

MetadataExtractor creates:
- metadata['basic'] - Basic asset info
- metadata['content'] - Content dimensions/type
- metadata['custom_fields'][Category] - All Ferrero fields organized by category
- metadata['permissions'] - Access permissions
- metadata['renditions'] - Rendition info

Now Final Assets will show ALL uploaded metadata fields organized by category.

🤖 Generated with Claude Code
2025-10-30 14:08:13 -04:00
DJP
811cff6fc6 Implement MVP metadata extraction - Extract specific fields from master
New Approach:
Instead of sending ALL metadata or just 5 fields, extract ONLY the
MVP fields from the master asset metadata.

MetadataExtractorMVP.php:
- New class dedicated to MVP field extraction
- Lists all 28 MVP field IDs from asset_representation MVP.json
- extractMVPFields(): Searches master metadata for MVP fields
- Preserves exact field structure from master (domain values, tabular fields)
- buildMVPAssetRepresentation(): Creates upload JSON with only MVP fields
- Updates ASSET NAME field to clean filename

MVP Fields Extracted (28 total):
- FERRERO.FIELD.MKTG.ASSET TYPE
- FERRERO.FIELD.FISCAL YEAR
- MAIN_LANGUAGES
- FERRERO.FIELD.ASSETCOMPLIANCE
- MARKETING_TAG
- FERRERO.MARKET.FIELD.TYPE_VID
- ARTESIA.FIELD.ASSET DESCRIPTION
- FERRERO.FIELD.MARKETING.FLAVOUR
- FERRERO.FIELD.MARKETING.SIZE
- FERRERO.FIELD.STATE
- ARTESIA.FIELD.ASSET NAME
- FERRERO.FIELD.SUB BRAND
- FERRERO.FIELD.ASSET VALIDITY START/END PERIOD
- FERRERO.MARKETING.FIELD.AGENCY NAME
- FERRERO.MARKET.FIELD.IPRIGHT
- FERRERO.MARKET.PROD_COMPANY
- [... and 12 more fields]

Workflow Changes:
- Use MetadataExtractorMVP instead of MetadataMerger for building asset rep
- Extract MVP fields from full master metadata
- Update ASSET NAME to clean filename
- Log how many fields found vs expected

Benefits:
 Includes all MVP metadata (not just 5 fields)
 Preserves exact field structures from master
 Smaller payload than full metadata (~10-15KB vs 128KB)
 Should work reliably while including more metadata

Next: Test if uploads now appear in folder with MVP metadata.

🤖 Generated with Claude Code
2025-10-30 13:05:09 -04:00
DJP
0ee447e1dc Rollback to simple 5-field metadata structure for uploads
Issue: Assets reporting HTTP 202 success but not appearing in folder
Hypothesis: Large metadata payload (128KB) may be causing silent failures

Rollback Changes:
- MetadataMerger.buildAssetRepresentation() now creates SIMPLE structure
- Only 5 fields (proven to work):
  1. FERRERO.FIELD.MKTG.ASSET TYPE (from filename)
  2. FERRERO.FIELD.FISCAL YEAR (default)
  3. MAIN_LANGUAGES (from filename)
  4. ARTESIA.FIELD.ASSET NAME (clean filename)
  5. FERRERO.FIELD.STATE (Local)

- Removed complex master metadata merging
- Added logging for field values
- Pass parsed filename to buildAssetRepresentation()

Test this to see if uploads now appear in Final Assets folder.

Note on DELETE:
HTTP 405 - Method not supported. DAM may not allow DELETE via API.
Need to investigate alternative approach (move to trash, mark as deleted, etc.)

🤖 Generated with Claude Code
2025-10-29 17:46:07 -04:00
DJP
56a8dafd30 Add asset delete functionality and improved upload success display
debug_assets.php Changes:
- Added delete_asset action handler
- DELETE /v6/assets/{id} API call
- 🗑️ Delete button for each asset
- Confirmation dialog before delete
- Auto-refresh folder after delete
- 🔄 Refresh button to reload folder assets
- Success/deleted message display

workflow_v3.php Changes:
- Show upload folder ID in success message
- Add 🔍 View in Final Assets Folder link
- Direct link to debug_assets.php with folder ID
- Pass upload_folder and master_asset_id in response

Features:
 Delete test assets easily
 Refresh folder to see latest uploads
 Direct link to view uploaded assets in folder
 Confirmation before delete
 Auto-redirect after delete

Usage:
1. Upload asset → Click 🔍 View in Final Assets Folder link
2. See all assets in that folder
3. Click 🗑️ Delete to remove test assets
4. Click 🔄 Refresh to reload after upload

🤖 Generated with Claude Code
2025-10-29 17:35:37 -04:00
DJP
2bcac0a08f Add full_metadata JSONB column - Store complete DAM metadata without truncation
Database Changes:
- ALTER TABLE master_assets ADD COLUMN full_metadata JSONB
- Stores COMPLETE DAM asset metadata (no 5,000 char truncation)
- PostgreSQL JSONB type for efficient storage and querying

DatabaseClient Changes:
- Added full_metadata to INSERT and ON CONFLICT UPDATE
- Store complete json_encode($assetData) in full_metadata column
- Simplified description to just Box info (no metadata)
- Log metadata size when storing
- NO TRUNCATION - preserves all fields

Workflow Changes (workflow_v3.php):
- load_master_metadata: Read from full_metadata JSONB column
- upload_from_box: Read from full_metadata JSONB column
- Both endpoints now get COMPLETE master metadata
- Added logging for metadata size verification

Impact:
BEFORE: Only 5,000 chars stored (truncated)
AFTER: Full metadata stored (10,000+ chars, all fields preserved)

Next Step:
Re-download master assets to populate full_metadata for existing records.
New downloads will automatically use the new column.

🤖 Generated with Claude Code
2025-10-29 16:53:51 -04:00
DJP
ef5f45273f Add Final Assets folder viewing to Download workflow
New Features:
- Added 'Get Final Assets' button in Download (A1→A2) workflow
- View uploaded/localized assets in Final Assets folder
- Display metadata for final assets (same format as master assets)
- Shows asset name, ID, type, size, metadata model

Backend:
- Added get_final_assets action handler
- Loads assets from Final Assets folder (findUploadFolder)
- Uses same getAssetsFromFolder helper as Master Assets

Frontend:
- 'Get Final Assets (Uploaded)' button next to 'Get Master Assets'
- Final Assets list with expandable metadata
- Metadata display includes:
  - Basic Info (name, type, size, model)
  - Content Info (dimensions, format, etc.)
  - Ferrero Fields (all custom metadata)

UI Styling:
- Green border-left for Final Assets (vs blue for Master)
- Same metadata extraction using MetadataExtractor
- Collapsible metadata view per asset

This allows users to verify uploaded assets and review their metadata.

🤖 Generated with Claude Code
2025-10-29 16:31:36 -04:00
DJP
bd9030c0ab Fix upload processing - use correct method and metadata extraction
Changes:
1. Added uploadWithMetadata() method to AssetUploaderSimple
   - Accepts custom asset representation from MetadataMerger
   - Same proven structure as uploadFile() but with custom metadata

2. Fixed database metadata extraction in upload_from_box
   - Metadata stored in description field, not separate column
   - Extract JSON after 'DAM Metadata JSON:' marker
   - Parse and store in masterAsset['metadata']

3. Updated upload call to use uploadWithMetadata()
   - Rename temp file to clean filename before upload
   - Pass merged asset representation
   - Upload to correct folder

This fixes all the upload processing errors.

🤖 Generated with Claude Code
2025-10-29 16:25:38 -04:00
DJP
34c16603cd Fix metadata extraction from database - use description field
The metadata is stored in the description field, not a separate metadata column.
Updated both AJAX endpoints to extract JSON from description field.

Format: 'Box File ID: xxx\nDAM Metadata JSON:\n{...}'

Changed:
- Removed 'metadata' from SELECT query
- Extract JSON from description field after 'DAM Metadata JSON:' marker
- Parse JSON and store in masterAsset['metadata']

This fixes the upload process to correctly load master metadata.

🤖 Generated with Claude Code
2025-10-29 16:22:58 -04:00
DJP
4af7cac196 Fix DatabaseClient instantiation - use new instead of getInstance
DatabaseClient uses standard constructor, not singleton pattern.
Changed all DatabaseClient::getInstance() to new DatabaseClient()

This fixes the upload_from_box AJAX endpoint fatal error.

🤖 Generated with Claude Code
2025-10-29 16:16:58 -04:00
DJP
e71163dea0 Implement complete Upload from Box workflow - Phase 3 Complete
Backend Implementation:
- Complete upload_from_box AJAX endpoint
- 10-step upload process:
  1. Parse filename (V2 validation)
  2. Load master metadata from PostgreSQL
  3. Download file from Box
  4. Merge metadata (filename priority)
  5. Build asset representation
  6. Strip OMG Job Number & Tracking ID
  7. Upload to DAM with AssetUploaderSimple
  8. Clean up temp files
  9. Error handling at each step
  10. Return detailed results

Frontend Implementation:
- Replace placeholder with real upload logic
- Sequential file upload with progress tracking
- Real-time status updates (/)
- Detailed error messages per file
- Upload results summary (success/fail counts)
- Success: Show asset ID and clean filename
- Failure: Show specific error message
- Auto-enable button after completion

Features:
 Download from Box
 V2 filename parsing & validation
 Tracking ID → Master metadata lookup
 Metadata merging (filename wins)
 Filename stripping (Job # & Tracking ID)
 Upload to DAM with proper metadata
 Progress tracking per file
 Detailed success/error reporting
 Temp file cleanup

Flow:
Box File → Parse → Load Master → Merge → Strip → Upload → DAM Asset

🤖 Generated with Claude Code
2025-10-29 16:14:50 -04:00
DJP
ec92b6b407 Add Upload from Box UI and AJAX endpoints - Phase 2 Complete
UI Components Added:
- New "Upload from Box" tab in workflow interface
- Box Folder ID input with load button
- File list table with validation indicators
- Select/deselect files functionality
- Upload progress and results containers

AJAX Endpoints Implemented:
- box_list_files: List files from Box folder with parsing
- parse_filename: Parse individual V2 filenames
- load_master_metadata: Get master metadata from PostgreSQL by tracking ID
- merge_metadata: Merge master + filename data (filename priority)
- upload_from_box: Placeholder for upload processing

JavaScript Functions Added:
- loadBoxFiles(): Fetch files from Box folder via AJAX
- displayBoxFiles(): Render file list table with validation
- toggleAllFiles(): Select/deselect all valid files
- updateUploadButton(): Enable/disable upload button
- uploadSelectedFiles(): Handle upload process (placeholder)
- Helper functions: formatFileSize, escapeHtml

Features:
- Real-time filename validation (V2 naming convention)
- Tracking ID extraction and display
- Clean filename preview (stripped OMG Job # and Tracking ID)
- Validation error messages
- Box file links
- File size formatting

What Works:
 Tab navigation
 Box folder file listing
 V2 filename parsing and validation
 Tracking ID extraction
 Validation indicators (/)
 File selection UI
 Integration with FilenameParser, BoxFileRetriever classes

Next Step: Implement actual upload processing logic

🤖 Generated with Claude Code
2025-10-29 15:54:49 -04:00
DJP
69a8f8672b FIX: Add missing uploadFolderId parameter to database storage
Critical bug fix - upload_directory was always NULL because
uploadFolderId wasn't being passed to storeMasterAsset().

Now passes uploadFolderId as 5th parameter.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:27:57 -04:00
DJP
5a5b29b03f Add debug logging to Box upload workflow 2025-10-29 14:19:08 -04:00
DJP
333f62c9e6 Extract Final Assets folder ID when getting master assets
When user clicks 'Get Master Assets', now also:
- Finds Final Assets folder in campaign
- Stores folder ID in session
- Shows in success message

This folder ID is passed to Box upload → stored in database upload_directory column.

Later used for A2→A3 upload workflow to know where to upload files back to DAM.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 17:06:48 -04:00
DJP
cc92a088a8 Pass Final Assets folder ID through Box upload workflow to database
Workflow now:
1. Get Master Assets → Also finds Final Assets folder
2. Download & Upload to Box → Passes upload folder ID
3. Database stores upload_directory = Final Assets folder ID

This ensures each asset record has the DAM upload target folder stored for later use in A2→A3 workflow.

UI shows upload folder ID in success message.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 17:06:21 -04:00
DJP
6dac3f8d6b Enhance Box upload results UI - show DB status and tracking ID source
Box upload results now display:
- Tracking ID with green highlight
- Clickable Box link with icon
- Database storage status ( Stored or  Failed)
- ID source (database_direct, random, etc.)

Makes it clear when database integration is working.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 15:39:55 -04:00
DJP
d8e542a569 Add PostgreSQL database integration and Box metadata template
Database Integration:
- IDGenerator now connects to PostgreSQL (localhost:5433)
- Generates tracking IDs with uniqueness check against master_assets table
- Fallback to random if database unavailable
- Direct PDO connection to ferrero_tracking database

DatabaseClient:
- Stores master assets in PostgreSQL
- Records: tracking_id, opentext_id, Box links, full metadata JSON
- Updates on conflict (upsert pattern)
- Stores box_file_id and box_url for reference

Box Metadata Enhancement:
- Uses Box metadata template API (enterprise/ferreroDAMMetadata)
- Stores full DAM metadata JSON in 'Ferrero-DAM-Metadata' field
- Fallback to file description if template not configured
- Handles template conflicts (updates existing)

Box Upload Results Now Show:
- Unique tracking ID (from database)
- Box file links (clickable)
- Database storage status
- ID source (database_direct, random, etc.)

Complete workflow: DAM → Download → Generate ID → Upload to Box → Store in DB

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 15:39:32 -04:00
DJP
0c799aebe7 Implement proper Box JWT authentication with RSA signing
Box now uses JWT (JSON Web Token) authentication:
- Signs JWT with RSA private key from config
- Uses RS256 algorithm
- Enterprise-level access
- No expiring developer tokens

JWT Flow:
1. Create JWT header with publicKeyID
2. Create claims with enterprise ID
3. Sign with encrypted private key + passphrase
4. Exchange JWT for access token
5. Token auto-refreshes as needed

Config loaded from: Box-config.json (complete JWT config)

This is the proper production-ready authentication method.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 14:07:52 -04:00
DJP
fd3676e8d0 Use Box developer token for now - OAuth app not configured
Box OAuth requires app to be configured for client credentials grant.
Using developer token as fallback (valid 60 minutes).

User needs to:
1. Go to https://app.box.com/developers/console
2. Generate new Developer Token
3. Update token in code (expires hourly)

OR configure Box app for OAuth 2.0 client credentials grant.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:51:57 -04:00
DJP
c4ccbae765 Fix Box to use OAuth 2.0 client credentials instead of developer token
Box now uses proper OAuth flow:
- Client ID: l2atwxxq4xna7phcjr2uifm4mbah69qp
- Client Secret: 6XcuCQ6akpk9daE0UHaGSv3mSxWaER4l
- Enterprise ID: 43984435
- Grant type: client_credentials with box_subject_type

Loads credentials from Box-config.json for security.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:30:28 -04:00
DJP
61d7835ee8 Add Box connection test and debug logging
Added:
- Box connection test before upload
- Debug logging for troubleshooting
- Better error messages
- Fixed downloadDetails reference

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:21:45 -04:00
DJP
36d45ae188 Add Box.com integration for asset storage with unique ID tracking
New Box Integration Features:
- BoxClient class for Box API operations
- IDGenerator for 6-character unique IDs (A-Z a-z 0-9)
- Auto-create campaign folders in Box
- Rename files with unique ID suffix (filename_ID.ext)
- Upload metadata JSON to Box custom fields
- Track Box file IDs and URLs

Download Workflow Enhancement:
- New button: '📥📦 Download & Upload to Box'
- Downloads from DAM → Uploads to Box
- Each file gets unique 6-char ID
- Creates campaign folder: {campaign_id}_{campaign_name}
- Results show: original → renamed filename with ID

Box Configuration:
- Developer Token: e7Q1kS6rOM1tH2ezzCg4KgRfcyNW2JHI
- Root Folder: 348304357505
- OAuth creds in Box-config.json

ID Generation:
- Phase 1: Random 6-char (current)
- Phase 2: PostgreSQL DB via REST API (ready to integrate)

Metadata Storage:
- Stored in Box file description (custom metadata field later)
- Full DAM metadata JSON preserved
- Includes: asset_id, campaign info, all metadata fields

Ready for testing! Download workflow now stores assets in Box with tracking.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:11:49 -04:00
DJP
a1e6dc6ab0 🎉 BREAKTHROUGH: Upload working! Use AssetUploaderSimple everywhere
TEST UPLOAD SUCCESSFUL! Asset ID: 214659

The simplified uploader works! Now using it for:
- Test uploads 
- Regular workflow uploads 

Key success factors:
- Only 5 metadata fields (not 17)
- Proper filename handling (not temp php names)
- Exact standalone script structure
- Cookie jar for JSESSIONID

Regular upload workflow now ready for testing!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 09:17:52 -04:00
DJP
45b4067150 Create simplified uploader matching exact standalone script
AssetUploaderSimple - exact copy of standalone logic:
- Only 5 metadata fields (not 17)
- Same field order and structure
- Same cURL options
- Produces ~1200 byte payload like standalone

Test upload now uses AssetUploaderSimple for exact match.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 09:12:51 -04:00
DJP
cbdf3f60a7 Simplify standalone test - accept token as argument + show token in UI
Standalone test now accepts token as command line argument instead of
trying to get new token (credentials may have changed).

UI now shows OAuth token in expandable section for copying to standalone test.

Usage: php test_upload_standalone.php "eyJraWQiOiI0Y..."

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 08:39:25 -04:00
DJP
26500422ee Fix test upload to use full metadata structure
Test upload was passing null for master asset, causing it to use
minimal structure instead of the full Postman metadata.

Now passes dummy master asset to trigger buildAssetRepresentationFromMasterAsset()
which contains all 17 required metadata fields.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 08:33:17 -04:00
DJP
c4eec014a4 Add test upload feature for direct folder testing
New test upload panel in Upload workflow:
- Upload directly to any folder ID (bypasses campaign selection)
- Pre-filled with test folder: e96080ba0cd1427d253a28a87504b6665eaa02cb
- Folder ID can be edited for testing different folders
- Shows success/failure with full error details
- Uses same upload mechanism as regular workflow

Use case:
- Test if specific folders allow uploads
- Bypass campaign workflow for testing
- Verify folder permissions
- Isolate upload issues

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 13:12:25 -04:00
DJP
1058525c3f Add metadata JSON download for master assets
New feature in Download workflow (A1→A2):
- Added '💾 JSON' button next to each master asset
- Downloads complete asset metadata as JSON file
- Filename format: {assetname}_metadata.json
- Pretty-printed JSON for readability

Use case:
- Inspect full metadata structure
- Reference for upload field requirements
- Debug metadata field values
- Documentation of master asset data

Buttons per asset:
- 📥 Download (file)
- 💾 JSON (metadata)
- 📋 View (toggle metadata display)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 11:39:36 -04:00
DJP
289d34bf2b Re-enable master asset fetching + Upload troubleshooting document
Master Asset Fetching:
- Re-enabled with better error handling
- Stores only lightweight data: asset_id, name, mime_type, model_id, security_policies
- Avoids storing massive metadata structure that causes crashes
- Graceful error handling if fetch fails

Upload Troubleshooting Document (UPLOAD_TROUBLESHOOTING.md):
- Comprehensive summary of upload blocking issue
- Details of all 5 upload approaches tested
- Technical specifications of API requests
- Error messages and HTTP codes
- Questions for Ferrero DAM support team
- Comparison of working downloads vs blocked uploads
- Recommended next steps

Ready for client to share with Ferrero support team to resolve API upload permissions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 11:24:39 -04:00
DJP
0ebdf5c755 Disable master assets fetching in upload - causes PHP crashes
Upload workflow issues:
- Master asset metadata structures too large for PHP to process
- Causes session storage crashes and HTTP 500 errors
- Temporarily disabled master assets fetching
- Upload folder finding still works

Current upload status:
- ALL file extensions (.tif, .jpg, .png) rejected by API
- Error: "Cannot import asset having restricted file extension"
- Tested with minimal payloads (just manifest + folder + file)
- Suggests server-level restrictions or account permissions issue

Awaiting client confirmation on:
- API upload permissions for user account
- Allowed file extensions for API uploads
- Alternative upload methods if API is restricted

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 11:17:26 -04:00
DJP
3a41a4f964 Add debug and reset features to Rework workflow (A5→A6)
Rework Workflow Enhancements:
- Add "Debug: Load ALL Campaigns" button to Rework tab
- Display all campaigns with their Content Scaling Status
- Add "Reset to A5" button for each campaign in debug view
- Show OAuth status and API response details
- Expandable campaign cards with full metadata view
- Session clearing when resetting campaigns

Upload Debug Improvements:
- Show uploaded filename and detected MIME type
- Display master asset being used for metadata
- Better visual separation of upload file vs master asset info

Mirrors Download workflow debug functionality for consistency across all workflow tabs.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 10:09:55 -04:00
DJP
4f5ac8bfe7 Add standalone Upload workflow with master asset metadata selection
Upload Workflow Improvements:
- Fetch master assets metadata when finding upload folder (standalone workflow)
- Add UI selector to choose which master asset's metadata to copy
- Show master asset details: name, type, metadata model, security policies
- Add comprehensive upload debug output showing file/metadata info
- Add "Reset to A1" button in Upload tab for testing
- Default to first master asset if none selected

Upload Implementation Progress:
- Tried multiple approaches to bypass file extension restrictions
- Current status: All file extensions blocked by API (jpg, tif, png)
- Minimal upload attempt: manifest + security_policy + parent_folder
- Issue: "Cannot import asset having restricted file extension" for all types
- Suggests API upload restrictions or account-level permissions needed

Technical Details:
- Upload endpoint: /v6/assets (POST with multipart/form-data)
- Required fields: manifest, parent_folder_id, files, asset_representation
- Security policy ID: 1594 (from V3 collection)
- File extension restrictions appear to be server/account level

Next Steps:
- Verify API upload permissions with client
- Check allowed file extensions for API uploads
- May need different upload approach or web interface integration

Working Features:
-  Download workflow (A1 → A2) fully functional
-  Status updates working with proper locking
-  Master asset metadata fetching and selection
- 🔄 Upload blocked by file extension restrictions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 09:50:43 -04:00
DJP
156f9ae51d Fix status updates and enhance workflow with proper error handling
Major improvements to workflow_v3.php and supporting classes:

**Status Updates (A1→A2, A2→A3, A5→A6):**
- Fix StatusManager to use correct PATCH endpoint: /v6/folders/{id}
- Add lock_strategy=optimistic parameter to prevent locking errors
- Update request body structure to use edited_folder format
- Status updates now working correctly

**Status Field Extraction:**
- Fix CampaignFormatter to extract CONTENT.SCALING.STATUS field
- Handle domain values with field_value.value path
- Now correctly filters campaigns by status (A1, A2, A5, etc.)

**Error Handling:**
- Extract and display actual API error messages
- Show HTTP status codes in all error messages
- Add expandable debug panels with full API responses
- Enhanced upload error reporting with detailed diagnostics

**Campaign Search:**
- Update to use Postman collection requests directly (avoids 503 errors)
- Fix URL encoding (rawurlencode instead of urlencode)
- Add comprehensive debug output showing OAuth status and API responses
- Search now attempts Postman request first, falls back to manual query

**Upload Improvements:**
- Rewrite AssetUploader to use native PHP CURLFile for multipart uploads
- Add support for additional file types: .mov, .mp4, .avi, .zip, .txt, .doc, .xlsx
- Increase max upload size to 100MB for video files
- Simplify asset_representation to minimal structure
- Add infrastructure to inherit metadata from master assets

**Testing Features:**
- Add "Reset to A1" button for testing workflow iterations
- Add debug mode to view all campaigns and their metadata
- Show Content Scaling Status on all campaign cards
- Display filtering debug info (total vs filtered counts)

**UI Improvements:**
- Rename buttons to clarify "Content Scaling Status" terminology
- Add status badges to campaign cards showing current status
- Better visual feedback for successful/failed operations

Current Status: Workflow A1→A2 fully working. Upload A2→A3 ready for testing
once DAM server recovers from HTTP 503 errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 16:43:09 -04:00
DJP
cf71bcfd96 Complete workflow V3: Add Upload (A2→A3) and Rework (A5→A6) workflows
NEW: Upload Workflow (A2→A3)
- Load campaigns with status A2 (assets sent to agency)
- Select campaign and find upload target folder (Final Assets)
- Multi-file upload with drag-drop interface
- AssetUploader class with multipart/form-data support
- Upload files with metadata to DAM
- Update status to A3 after upload

NEW: Rework Workflow (A5→A6)
- Load campaigns with status A5 (rework needed from agency)
- Select campaign and get rework assets
- Download individual or bulk rework assets
- Beautiful metadata display
- Update status to A6 when rework assets received

Features:
- Three complete workflow tabs (Download, Upload, Rework)
- Status transitions: A1→A2, A2→A3, A5→A6
- Session-based workflow state management
- Clear workflow data button for each tab
- Campaign selection with visual feedback
- Download confirmed working (tested with real asset)
- OAuth2 auto-refresh throughout all workflows

Technical:
- AssetUploader class for multipart file uploads
- Proper metadata JSON structure for uploads
- Support for multiple file formats (JPG, PNG, PDF, AI, PSD, etc.)
- Error handling for each workflow step
- Beautiful UI with color-coded status badges

Ready for testing with real campaign data!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 16:43:26 -04:00
DJP
8cfa971078 Add debug for asset_content_info structure and try all renditions 2025-10-17 15:52:44 -04:00
DJP
9bf6813575 Add fallback to preview/thumbnail renditions if original file missing 2025-10-17 15:50:59 -04:00
DJP
7bd8c30803 Fix rendition URL path - remove duplicate /otmmapi/ prefix 2025-10-17 15:49:15 -04:00
DJP
e0ec556c5e Use cached asset data from folder listing for download (has rendition URLs) 2025-10-17 15:47:36 -04:00
DJP
02c2f0343c Fix: Use load_type=full to get rendition URLs in asset_content_info 2025-10-17 15:44:59 -04:00
DJP
6ea945aabc Fix rendition URL extraction from asset_content_info 2025-10-17 15:38:51 -04:00
DJP
1f88226426 Fix download using renditions + beautiful metadata display
MAJOR FIX: Download now works!
- Extract rendition URL from asset metadata (content.url)
- Download via /v6/renditions/{id} instead of /v6/assets/{id}/contents
- Fallback to direct download if no rendition found
- Files now download successfully!

Beautiful Metadata Display:
- Color-coded sections with icons
- Basic Info (blue) - asset details
- Content Info (green) - file size, dimensions, URLs
- Custom Fields (yellow) - collapsible by category
- Permissions (red) - visual checkmarks
- Renditions (teal) - all available versions

Download Improvements:
- First fetch asset metadata to find correct download URL
- Try rendition URL from metadata
- Show download method and URL used
- Better error messages with tried URL

Metadata Features:
- Grid layout for easy reading
- Collapsible sections to reduce clutter
- Human-readable field names
- Array values displayed as comma-separated
- Shows rendition sizes and dimensions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 15:34:21 -04:00
DJP
a165bd347c Fix asset name extraction and add workflow cache clearing
Fixes:
- Extract folder/asset names from INER_NAME_GENERIC field (correct field ID)
- Add fallback to 'name' field if metadata field not found
- Fix debug_assets.php to maintain campaign_id in URL parameters
- Add "Clear Workflow Data" button to reset cached session data
- Improve error messages when files don't exist in storage
- Allow status update even if downloads fail (test environment)

Changes:
- Update extractFolderName() to check INER_NAME_GENERIC first
- Fix debug_assets.php folder and asset name extraction
- Add clear_results action to workflow_v3.php
- Show folder names correctly in debug interface
- Display clear message about test environment file availability

Working:
 OAuth2 authentication
 Campaign search by status
 Folder navigation
 Asset listing with correct IDs
 Metadata extraction
⚠️  Download fails - files don't exist in test environment storage

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 15:30:32 -04:00
DJP
633c5a525e Fix workflow V3: metadata display and download error handling
Fixes:
- Metadata button now works (fixed JavaScript and element IDs)
- Display full metadata as JSON when clicked
- Detect and show proper error when files don't exist in storage
- Show detailed download error messages (HTTP 500, file not found)
- Display download success/failure with file size and path
- Use old working Postman collection with OAuth2 configured
- Update StatusManager to use working search pattern + status filter

Changes:
- Switch to Content Scaling Flow.postman_collection_Oliver(New).json
- Fix downloadAsset to detect JSON error responses
- Improve metadata display with toggle functionality
- Show clear error messages for missing files in DAM storage

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 15:13:01 -04:00
DJP
a179be5da8 Add Workflow V3 with status-based campaign management
New Features:
- ConfigV3 class with test/production environment switching
- StatusManager for campaign status updates (A1→A2→A3, A5→A6)
- workflow_v3.php with tabbed interface for different workflows
- Auto-refreshing OAuth2 token (60-second buffer before expiry)
- Download workflow: Load A1 campaigns → Download master assets → Update to A2
- Metadata display for all assets
- Configurable base URLs for certificate auth and IP filtering

Status Workflow:
- A1: Ready for localization → Download assets → A2
- A2: Assets sent to agency → Upload processed → A3 (coming soon)
- A5: Rework needed → Download rework assets → A6 (coming soon)

Technical:
- Uses Content Scaling Flow V3.postman_collection.json
- Supports multiple environments (test/production)
- Session-based workflow state management
- Master Assets folder always "01. Master Assets"

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 15:00:21 -04:00