- Add 26 documentation files including test reports, deployment guides, and troubleshooting documentation - Include 3 CSV data files for trainer imports and user registration tracking - Add 43 JavaScript test files covering mobile optimization, Safari compatibility, and E2E testing - Include 18 PHP utility files for debugging, geocoding, and data analysis - Add 12 shell scripts for deployment verification, user management, and database operations - Update .gitignore with whitelist patterns for development files, documentation, and CSV data 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			196 lines
		
	
	
		
			No EOL
		
	
	
		
			9.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			No EOL
		
	
	
		
			9.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const { chromium } = require('playwright');
 | ||
| 
 | ||
| async function debugGeocodingIssues() {
 | ||
|     console.log('🔍 DEBUGGING GEOCODING ISSUES - WHY ONLY 16/43 PROFILES GEOCODED');
 | ||
|     console.log('================================================================================');
 | ||
|     
 | ||
|     const browser = await chromium.launch({ headless: false });
 | ||
|     const context = await browser.newContext();
 | ||
|     const page = await context.newPage();
 | ||
|     
 | ||
|     try {
 | ||
|         // Login as master trainer
 | ||
|         console.log('📝 Logging in as master trainer...');
 | ||
|         await page.goto('https://upskill-staging.measurequick.com/wp-login.php');
 | ||
|         await page.fill('#user_login', 'JoeMedosch@gmail.com');
 | ||
|         await page.fill('#user_pass', 'JoeTrainer2025@');
 | ||
|         await page.click('#wp-submit');
 | ||
|         await page.waitForURL('**/master-trainer/master-dashboard/**', { timeout: 15000 });
 | ||
|         console.log('✅ Master trainer login successful');
 | ||
|         
 | ||
|         // Go to a page with AJAX access
 | ||
|         await page.goto('https://upskill-staging.measurequick.com/trainer/profile/');
 | ||
|         await page.waitForLoadState('networkidle');
 | ||
|         
 | ||
|         // Run detailed geocoding analysis to see specific errors
 | ||
|         console.log('\n🗺️ STEP 1: Running detailed geocoding analysis to see errors...');
 | ||
|         
 | ||
|         const detailedGeocodingAnalysis = await page.evaluate(async () => {
 | ||
|             try {
 | ||
|                 const response = await fetch(hvac_ajax.ajax_url, {
 | ||
|                     method: 'POST',
 | ||
|                     headers: {
 | ||
|                         'Content-Type': 'application/x-www-form-urlencoded',
 | ||
|                     },
 | ||
|                     body: new URLSearchParams({
 | ||
|                         action: 'hvac_trigger_geocoding',
 | ||
|                         nonce: hvac_ajax.nonce
 | ||
|                     })
 | ||
|                 });
 | ||
|                 
 | ||
|                 const data = await response.json();
 | ||
|                 return data;
 | ||
|             } catch (e) {
 | ||
|                 return { success: false, error: 'Exception: ' + e.message };
 | ||
|             }
 | ||
|         });
 | ||
|         
 | ||
|         if (detailedGeocodingAnalysis.success) {
 | ||
|             const details = detailedGeocodingAnalysis.data.details || [];
 | ||
|             
 | ||
|             console.log('\n📋 DETAILED GEOCODING ANALYSIS:');
 | ||
|             console.log(`   Total Profiles Analyzed: ${details.length}`);
 | ||
|             
 | ||
|             // Group profiles by status
 | ||
|             const statusGroups = {};
 | ||
|             details.forEach(profile => {
 | ||
|                 const status = profile.status || 'unknown';
 | ||
|                 if (!statusGroups[status]) {
 | ||
|                     statusGroups[status] = [];
 | ||
|                 }
 | ||
|                 statusGroups[status].push(profile);
 | ||
|             });
 | ||
|             
 | ||
|             Object.keys(statusGroups).forEach(status => {
 | ||
|                 console.log(`   ${status}: ${statusGroups[status].length} profiles`);
 | ||
|             });
 | ||
|             
 | ||
|             // Show detailed error information
 | ||
|             const errorProfiles = (statusGroups['error'] || []).concat(statusGroups['failed'] || []);
 | ||
|             if (errorProfiles.length > 0) {
 | ||
|                 console.log('\n❌ DETAILED ERROR ANALYSIS:');
 | ||
|                 errorProfiles.slice(0, 10).forEach(profile => {
 | ||
|                     console.log(`   ❌ ${profile.title}:`);
 | ||
|                     console.log(`      Address: ${profile.address || 'No address constructed'}`);
 | ||
|                     console.log(`      Error: ${profile.message || 'Unknown error'}`);
 | ||
|                     console.log(`      ID: ${profile.id}`);
 | ||
|                     console.log('');
 | ||
|                 });
 | ||
|                 
 | ||
|                 if (errorProfiles.length > 10) {
 | ||
|                     console.log(`   ... and ${errorProfiles.length - 10} more error profiles`);
 | ||
|                 }
 | ||
|             }
 | ||
|             
 | ||
|             // Show profiles that should have geocoded but didn't
 | ||
|             const noAddressProfiles = statusGroups['no_address'] || [];
 | ||
|             if (noAddressProfiles.length > 0) {
 | ||
|                 console.log('\n⚠️  PROFILES MARKED AS "NO ADDRESS" (but should have location data):');
 | ||
|                 noAddressProfiles.forEach(profile => {
 | ||
|                     console.log(`   ❌ ${profile.title} (ID: ${profile.id})`);
 | ||
|                     console.log(`      Reason: ${profile.message || 'No address data found'}`);
 | ||
|                 });
 | ||
|             }
 | ||
|             
 | ||
|             // Show successful geocodings for comparison
 | ||
|             const successfulProfiles = (statusGroups['geocoded'] || []).concat(statusGroups['already_geocoded'] || []);
 | ||
|             if (successfulProfiles.length > 0) {
 | ||
|                 console.log('\n✅ SUCCESSFUL GEOCODINGS FOR COMPARISON:');
 | ||
|                 successfulProfiles.slice(0, 5).forEach(profile => {
 | ||
|                     if (profile.coordinates) {
 | ||
|                         console.log(`   ✅ ${profile.title}: ${profile.coordinates.lat}, ${profile.coordinates.lng}`);
 | ||
|                         console.log(`      Address: ${profile.address}`);
 | ||
|                     } else {
 | ||
|                         console.log(`   ✅ ${profile.title}: Already geocoded`);
 | ||
|                     }
 | ||
|                 });
 | ||
|             }
 | ||
|             
 | ||
|             // Analysis of the gap
 | ||
|             const totalWithLocation = 43; // We know this from the import
 | ||
|             const actuallyGeocoded = successfulProfiles.length;
 | ||
|             const shouldHaveGeocoded = totalWithLocation - actuallyGeocoded;
 | ||
|             
 | ||
|             console.log('\n📊 GAP ANALYSIS:');
 | ||
|             console.log(`   Expected profiles with location data: ${totalWithLocation}`);
 | ||
|             console.log(`   Actually geocoded profiles: ${actuallyGeocoded}`);
 | ||
|             console.log(`   Profiles that should have geocoded but didn't: ${shouldHaveGeocoded}`);
 | ||
|             console.log(`   Error profiles: ${errorProfiles.length}`);
 | ||
|             console.log(`   No address profiles: ${noAddressProfiles.length}`);
 | ||
|             
 | ||
|             if (errorProfiles.length > 0) {
 | ||
|                 console.log('\n🔍 LIKELY CAUSES OF GEOCODING FAILURES:');
 | ||
|                 console.log('   1. Google Maps API rate limiting');
 | ||
|                 console.log('   2. Address format issues (need city, state, country format)');
 | ||
|                 console.log('   3. Invalid or unrecognizable addresses');
 | ||
|                 console.log('   4. API quota exceeded');
 | ||
|                 console.log('   5. Network timeouts');
 | ||
|             }
 | ||
|         }
 | ||
|         
 | ||
|         // Check if we can manually trigger another geocoding run to see current behavior
 | ||
|         console.log('\n🔄 STEP 2: Running another geocoding attempt to see current behavior...');
 | ||
|         
 | ||
|         const secondGeocodingAttempt = await page.evaluate(async () => {
 | ||
|             try {
 | ||
|                 const response = await fetch(hvac_ajax.ajax_url, {
 | ||
|                     method: 'POST',
 | ||
|                     headers: {
 | ||
|                         'Content-Type': 'application/x-www-form-urlencoded',
 | ||
|                     },
 | ||
|                     body: new URLSearchParams({
 | ||
|                         action: 'hvac_trigger_geocoding',
 | ||
|                         nonce: hvac_ajax.nonce
 | ||
|                     })
 | ||
|                 });
 | ||
|                 
 | ||
|                 const data = await response.json();
 | ||
|                 return data;
 | ||
|             } catch (e) {
 | ||
|                 return { success: false, error: 'Exception: ' + e.message };
 | ||
|             }
 | ||
|         });
 | ||
|         
 | ||
|         if (secondGeocodingAttempt.success) {
 | ||
|             const results = secondGeocodingAttempt.data;
 | ||
|             console.log('📋 Second geocoding attempt results:');
 | ||
|             console.log(`   Total Profiles: ${results.total_profiles}`);
 | ||
|             console.log(`   Successfully Geocoded: ${results.geocoded_count}`);
 | ||
|             console.log(`   Skipped (no address): ${results.skipped_count}`);
 | ||
|             console.log(`   Errors: ${results.error_count}`);
 | ||
|             console.log(`   API Key Valid: ${results.api_key_valid}`);
 | ||
|             
 | ||
|             const newlyGeocoded = results.details?.filter(d => d.status === 'geocoded') || [];
 | ||
|             if (newlyGeocoded.length > 0) {
 | ||
|                 console.log(`\n🎉 NEWLY GEOCODED in this run: ${newlyGeocoded.length}`);
 | ||
|                 newlyGeocoded.forEach(profile => {
 | ||
|                     console.log(`   ✅ ${profile.title}: ${profile.coordinates.lat}, ${profile.coordinates.lng}`);
 | ||
|                     console.log(`      Address: ${profile.address}`);
 | ||
|                 });
 | ||
|             } else {
 | ||
|                 console.log('\n⚠️  No new profiles geocoded in this run');
 | ||
|             }
 | ||
|         }
 | ||
|         
 | ||
|         await page.screenshot({ path: 'geocoding-debug-analysis.png', fullPage: true });
 | ||
|         
 | ||
|         console.log('\n================================================================================');
 | ||
|         console.log('🎯 GEOCODING DEBUGGING COMPLETE');
 | ||
|         console.log('================================================================================');
 | ||
|         
 | ||
|         console.log('\n📋 DEBUGGING CONCLUSIONS:');
 | ||
|         console.log('1. System successfully imported location data for 43 profiles');
 | ||
|         console.log('2. Only 16 profiles successfully geocoded');
 | ||
|         console.log('3. Need to investigate specific error messages and address formats');
 | ||
|         console.log('4. May need to retry geocoding with different strategies');
 | ||
|         console.log('5. Could be API rate limiting or address format issues');
 | ||
|         
 | ||
|     } catch (error) {
 | ||
|         console.error('❌ Error during geocoding debugging:', error);
 | ||
|         await page.screenshot({ path: 'geocoding-debug-error.png', fullPage: true });
 | ||
|     } finally {
 | ||
|         await browser.close();
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| debugGeocodingIssues(); |