upskill-event-manager/Status.md

17 KiB

HVAC Community Events - Project Status

Last Updated: December 20, 2025 Current Session: Scheduled Sync Persistence Fix - Complete Version: 2.1.11 (Deployed to Production)


🎯 CURRENT SESSION - SCHEDULED SYNC PERSISTENCE FIX (Dec 20, 2025)

Status: COMPLETE - Deployed to Production

Problem: Scheduled sync showed "Not Scheduled" after page refresh, even though settings were saved correctly.

Root Cause:

  • HVAC_Zoho_Scheduled_Sync was only loaded in admin context
  • On non-admin requests (including WP-Cron), custom cron schedules weren't registered
  • WordPress was clearing cron events because it didn't recognize the schedules

Fixes Applied

  1. Load Scheduled Sync on ALL Requests (class-hvac-plugin.php)

    • Moved HVAC_Zoho_Scheduled_Sync::instance() initialization to main plugin loader
    • Now loads alongside other schedulers (like Communication Scheduler)
    • Ensures cron schedules and action hooks are always registered
  2. Add add_option Hook (class-zoho-scheduled-sync.php)

    • Added add_option_hvac_zoho_auto_sync hook for first-time setting creation
    • WordPress fires add_option_ (not update_option_) on first save
  3. Explicit Scheduling in Save (class-zoho-admin.php)

    • save_settings() now explicitly calls schedule_sync() or unschedule_sync()
    • Ensures scheduling works even when option value hasn't changed
    • update_option_ hook only fires when value actually changes

Files Modified

  • includes/class-hvac-plugin.php - Load scheduled sync globally
  • includes/zoho/class-zoho-scheduled-sync.php - Add first-time option hook
  • includes/admin/class-zoho-admin.php - Explicit scheduling call

🎯 CURRENT SESSION - PUBLIC MAP & DIRECTORY FIX (Dec 20, 2025)

Status: 🚧 IN PROGRESS (Debugging)

Problem: "Find a Trainer" map loads briefly then disappears, replaced by "Map Temporarily Unavailable". Directory filters working but map unstable.

Findings:

  1. Safari Blocker Bug: Identified and fixed HVAC_Find_Trainer_Assets correctly blocking assets on Safari.
  2. Safety Script Race Condition: mapgeo-safety.js has a hard 6-second timeout loop that conflicts with slower resource loading.
  3. Stale Cache Issue: Browser continues to serve old mapgeo-safety.js (6s timeout) despite file update (30s timeout) and version bump (.fix1).
  4. Environment Constraints: wp cache flush failed (command not found), indicating potential restriction on direct WP-CLI use.

Fixes Applied (Pending Verification):

  1. Removed Safari Blocker: Corrected logic in class-hvac-find-trainer-assets.php.
  2. Increased Timeouts: Updated assets/js/mapgeo-safety.js to 30s global timeout.
  3. Version Bump: Added .fix1 suffix to enqueue version in class-hvac-mapgeo-safety.php.

Next Steps:

  • Resolve caching issue to ensure updated mapgeo-safety.js is served.
  • Verify map stability with 30s timeout.

📋 PREVIOUS SESSION - SCHEDULED ZOHO SYNC (Dec 19, 2025)

Status: COMPLETE - WP-Cron Scheduled Sync Implemented

Summary:

  • Scheduled Sync: WP-Cron job syncs new/modified records on configurable interval
  • Incremental Sync: Only syncs records modified since last sync run
  • Admin UI: Enable/disable toggle, interval selector (5min-daily), status display
  • Manual Trigger: "Run Sync Now" button for testing

Changes Made

  1. New File: class-zoho-scheduled-sync.php

    • WP-Cron management with custom intervals
    • run_scheduled_sync() processes all data types
    • Tracks last sync time for incremental filtering
    • Stores results for status display
  2. Updated class-zoho-sync.php

    • All 5 sync methods now accept $since_timestamp parameter
    • When provided, filters queries by post_modified >= since_date
  3. Updated class-zoho-admin.php

    • Added save_settings() AJAX handler
    • Added run_scheduled_sync_now() AJAX handler
    • Enhanced admin UI with new intervals and status display
  4. Updated zoho-admin.js

    • Settings form reloads page on save
    • "Run Sync Now" button with result display

Interval Options

Value Frequency
every_5_minutes Every 5 minutes (default)
every_15_minutes Every 15 minutes
every_30_minutes Every 30 minutes
hourly Hourly
every_6_hours Every 6 hours
daily Daily

Admin Page Location

  • /wp-admin/admin.php?page=hvac-zoho-sync
  • Look for "Scheduled Sync Settings" section

📋 PREVIOUS SESSION - BATCH SYNC ENHANCEMENT (Dec 18, 2025)

Status: COMPLETE - All Sync Tasks Now Auto-Iterate with Progress Bar

Summary:

  • All 5 Sync Types: Now support batch pagination with auto-continue
  • Progress Bar: Visual feedback showing X of Y processed (N%)
  • No Manual Repeating: Frontend auto-loops until has_more: false
  • Orphan Cleanup: Deleted 14 test attendees referencing deleted events

Changes Made

  1. Backend Pagination:
    • All sync methods (sync_events, sync_users, sync_attendees, sync_rsvps, sync_purchases) now accept $offset and $limit parameters
    • Each returns has_more, next_offset, and total for pagination
    • Admin endpoint updated to pass offset to sync methods
  2. Frontend Progress UI:
    • New syncWithProgress() function replaces single AJAX calls
    • Auto-continues batches until complete
    • Progress bar shows percentage and count
    • Accumulated results across all batches

Files Modified

  • includes/zoho/class-zoho-sync.php - Pagination for all 5 sync methods
  • includes/admin/class-zoho-admin.php - Offset parameter handling
  • assets/js/zoho-admin.js - Progress bar + auto-continue logic

📋 PREVIOUS SESSION - ZOHO CRM ATTENDEE SYNC (Dec 17-18, 2025)

Status: COMPLETE - All Attendees Syncing Successfully

Summary:

  • Events Sync: WORKING. 39 events synced with enhanced field mapping.
  • Attendees Sync: WORKING. 50/50 synced, 0 errors, all contacts updated with custom fields.

Issues Resolved

  1. Campaign Member Linking:
    • Fixed API endpoint: PUT /Contacts/{id}/Campaigns (was /Campaigns/{id}/Contacts/{id})
    • Fixed log_debug() visibility (private → public)
  2. Attendee Field Mapping:
    • measureQuick Email → Email (primary, used for lookup)
    • Attendee Email → Secondary_Email
    • Attendee Cell Phone → Mobile
    • Company Role → Primary_Role
    • Fixed meta key: _tec_tickets_commerce_attendee_fields with hyphenated field names
  3. Email Fallback Logic:
    • If attendee email empty, use measureQuick email (and vice versa)
    • Only fails if BOTH emails are empty
  4. DUPLICATE_DATA Handling:
    • When Zoho returns "duplicate exists", extract existing contact ID from error
    • Use that ID to update instead of failing
  5. Existing Contact Updates:
    • Existing contacts now updated via PUT with new field data on each sync

Zoho CRM Integration - Staging Environment (Working)

Status: OAuth Working, Sync Methods Implemented, Dry-Run Tested

Completed:

  1. OAuth Authentication Verified

    • Refresh token exists and is valid
    • API connection successful (53 modules accessible)
    • Read operations working (Contacts, Campaigns, Users)
  2. Read-Only API Tests Passed

    • Organization Info: Manifold Cloud Services (America/Detroit)
    • Contacts: 5+ records readable (Tanner Moore, Pete Knochelmann, etc.)
    • Campaigns: 5+ records readable (Nov 28, Oct 23, etc.)
    • CRM Users: Ben Reed (CEO), JR Lawhorne (Manager), etc.
  3. Sync Class Bug Fixes

    • Fixed user roles: trainer/traineehvac_trainer/hvac_master_trainer
    • Fixed event filter: Removed restrictive _hvac_event_type meta query
    • Fixed event display: Changed eventDisplay from list to custom to include past events
    • Fixed WooCommerce dependency: Added graceful error handling
  4. Event Tickets Integration (NEW)

    • Replaced WooCommerce sync with Event Tickets (Tickets Commerce) support
    • Added sync_attendees() method → Zoho Contacts + Campaign Members
    • Added sync_rsvps() method → Zoho Leads + Campaign Members
    • Updated meta keys for Tickets Commerce (_tec_tickets_commerce_*)
    • Updated meta keys for RSVPs (_tribe_rsvp_*)
  5. Admin Interface Updated

    • Added "Sync Attendees" button (Contacts + Campaign Members)
    • Added "Sync RSVPs" button (Leads + Campaign Members)
    • Renamed "Sync Purchases" to "Sync Orders" (Tickets Commerce)

Dry-Run Results (Staging - No Data Sent to Zoho):

Sync Type Records Found Status
Events → Campaigns 20 Ready
Trainers → Contacts 53 Ready
Attendees → Contacts + Campaign Members 79 Ready
RSVPs → Leads + Campaign Members 4 Ready
Orders → Invoices 52 Ready

Zoho CRM Mapping Strategy:

  • EventsCampaigns (direct mapping)
  • Trainers (hvac_trainer, hvac_master_trainer) → Contacts (with Contact_Type field)
  • Ticket AttendeesContacts + Campaign Members (links Contact ↔ Campaign)
  • RSVPsLeads + Campaign Members (links Lead ↔ Campaign)
  • Ticket OrdersInvoices (financial records)

Staging Protection Active:

  • All write operations (POST/PUT/DELETE) are blocked on staging
  • Only production (upskillhvac.com) can write to Zoho CRM
  • Dry-run shows what would sync without actually sending data

Admin Page Location:

  • /wp-admin/admin.php?page=hvac-zoho-sync

Files Modified:

  • includes/zoho/class-zoho-sync.php - Complete rewrite for Event Tickets
  • includes/admin/class-zoho-admin.php - Added new sync buttons

📅 PREVIOUS SESSION - GEMINI TRANSITION & VALIDATION (Dec 16, 2025)

Gemini Development Environment Setup

Objective: Transition from Claude Code-specific tooling to Gemini/Antigravity agent development workflow.

Completed:

  1. Created GEMINI.md - New development guidelines

    • Critical safety constraints for Cloudways Shared VPS
    • Workflows for testing (/test) and deployment
    • Coding standards (Singleton pattern, security, PHP 8+ modernization)
    • Agent personas (Tester, Security Auditor, Deployment Engineer)
  2. Environment Configuration

    • Updated .gitignore to allow .agent/, .mcp.json, GEMINI.md
    • Created /home/ben/dev/upskill-event-manager/.agent/workflows/test.md
    • Fixed file access blocked by gitignore
  3. PHP 8+ Compatibility Verification

    • Issue: true|\WP_Error syntax causing PHP fatal errors on staging (PHP 8.0)
    • Fix: Changed to bool|\WP_Error in includes/class-hvac-security-helpers.php:231
    • Status: Deployed to staging, verified working
  4. Comprehensive Test Suite

    • File: test-comprehensive-validation.js (Playwright E2E tests)
    • Fixed: Login form selectors (#user_login, #user_pass, #wp-submit)
    • Modes: Headless (default) or headed (DISPLAY=:1 HEADLESS=false)
    • Results:
      • Master Trainer pages: ALL PASSING (4/4)
      • Security endpoints: ALL SECURE (4/4)
      • Trainer pages: ⚠️ Require authentication (expected)

Test Results Summary:

✅ Master Dashboard - Functional with navigation
✅ Announcements - Fully functional & responsive
✅ Pending Approvals - Fully functional & responsive
✅ Trainers - Fully functional & responsive

🔒 Security: All AJAX endpoints properly secured (401/400 responses)
   - hvac_get_trainer_stats
   - hvac_manage_announcement
   - hvac_approve_trainer
   - hvac_approve_trainer_v2

Test Credentials Updated:

  • test_master / Test123! (hvac_master_trainer)
  • test_trainer / Test123! (hvac_trainer)
  • test_admin / Test123! (administrator)
  1. Master Trainer Navigation Dropdown Fix (Dec 16, 2025)
    • Issue: Green/teal colored boxes appearing in navigation toolbar instead of dropdown arrows
    • Root Cause: Empty <span class="menu-toggle"> elements with CSS background styling
    • Fix: Replaced with <span class="dropdown-arrow">▼</span> in includes/class-hvac-master-menu-system.php:327
    • Impact: All master trainer pages (/master-trainer/*)
    • Status: Deployed to staging, verified working
    • Verification: Screenshots confirm dropdown arrows display correctly, green boxes removed

📁 RECENT DEPLOYMENTS

v2.1.7 - Critical Nonce Fix (Nov 3, 2025)

Issue: Announcement submission completely broken - nonce mismatch
Fix: Changed nonce action from hvac_announcements_admin_noncehvac_announcements_nonce
Files: includes/class-hvac-announcements-admin.php (line 96)
Status: Deployed to staging, fully functional

v2.1.6 - Technical Debt Cleanup

Fixes:

  1. Version synchronization (2.0.0 → 2.1.6 in plugin header)
  2. FOUC prevention (modal display: none by default)
  3. Conditional logging (error_log()HVAC_Logger::log())

v2.1.5 - Z-Index Stacking Fix

Issue: WordPress media modal appearing behind announcement modal
Fix: Reduced announcement modal z-index from 999999 → 100000
Result: Media modals (z-index 160000) now properly stack on top


🧪 TESTING INFRASTRUCTURE

Comprehensive Test Suite

File: test-comprehensive-validation.js
Framework: Playwright (Node.js)

Run Tests:

# Headless (default)
node test-comprehensive-validation.js

# Headed mode (visible browser)
DISPLAY=:1 HEADLESS=false node test-comprehensive-validation.js

Test Coverage:

  • Trainer pages (4 pages)
  • Master trainer pages (4 pages)
  • Security/AJAX endpoints (4 endpoints)
  • Layout & responsive design
  • Authentication flows

🚀 DEPLOYMENT

Staging Environment

URL: https://upskill-staging.measurequick.com
Version: 2.1.7 + PHP 8+ fixes
Server: Cloudways Shared VPS (PHP 8.0)
Status: Fully functional

Deploy to Staging:

./scripts/deploy.sh staging

Verify Deployment:

./scripts/verify-plugin-fixes.sh

Production Environment

URL: https://upskillhvac.com
Version: 2.1.8 (latest)
Server: Cloudways Shared VPS


🔧 KEY DEVELOPMENT GUIDELINES

GEMINI.md Rules (NEW)

  1. Safety First:

    • NEVER delete files outside project directory
    • NEVER execute rm -rf without confirmation
    • NEVER modify system configs (/etc/*, /var/*)
    • NEVER deploy to production without explicit request
  2. Infrastructure Constraints:

    • Cloudways Shared VPS (limited resources)
    • Do NOT force PHP version changes
    • Do NOT install system-level packages
    • Be mindful of CPU/RAM usage
  3. Testing Mandatory:

    node test-comprehensive-validation.js
    
  4. Security Standards:

    • Always sanitize input
    • Always escape output
    • Verify nonces on forms & AJAX
    • Check roles/capabilities

WordPress Architecture

  • Singleton Pattern: All core classes use ::instance()
  • Template Security: All templates start with security check
  • PHP 8+ Modernization: In progress (avoid PHP 8.2+ features)

📚 DOCUMENTATION

Primary Files

  • GEMINI.md - Gemini agent development guidelines (NEW)
  • CLAUDE.md - Claude Code agent guidelines (legacy)
  • docs/ARCHITECTURE.md - Plugin architecture details
  • docs/CLAUDE-CODE-DEVELOPMENT-BEST-PRACTICES.md - Development patterns

Workflows

  • .agent/workflows/test.md - Running comprehensive tests (/test)

📋 NEXT ACTIONS

Immediate

  1. Production Deployment - Deploy v2.1.7 + PHP 8+ fixes (pending user approval)
  2. PHP 8+ Modernization - Continue Phase 2 modernization
  3. 🔜 Enhancements - New features for next session

Pre-Production Checklist

  • PHP 8+ compatibility verified
  • Security endpoints validated
  • Master trainer pages functional
  • Comprehensive tests passing
  • No fatal errors on staging

Deploy Command:

./scripts/deploy.sh production

⚠️ KNOWN ISSUES

Minor (Non-Blocking)

  1. Playwright Headless Login - Works in headed mode with correct selectors
  2. jQuery Loading Timing - Brief "jQuery is not defined" error (non-blocking)
  3. Dashboard Responsive - Minor responsive layout issue (cosmetic)

📊 SUMMARY

Current State: PRODUCTION READY

Key Achievements:

  • Gemini development environment established
  • PHP 8+ compatibility verified and deployed
  • Comprehensive test suite functional (headed mode)
  • All security endpoints properly secured
  • Master trainer features fully operational
  • Test accounts updated and working

Quality Metrics:

  • Test Coverage: 8 pages + 4 security endpoints
  • Success Rate: 100% master trainer pages
  • Security: 100% endpoints secured
  • PHP Compatibility: No fatal errors

Agent Transition:

  • From: Claude Code + MCP tools
  • To: Gemini/Antigravity + direct tooling
  • Status: Complete and validated

For detailed historical context, see git history and previous Status.md versions