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_Syncwas 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
-
✅ 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
- Moved
-
✅ Add
add_optionHook (class-zoho-scheduled-sync.php)- Added
add_option_hvac_zoho_auto_synchook for first-time setting creation - WordPress fires
add_option_(notupdate_option_) on first save
- Added
-
✅ Explicit Scheduling in Save (
class-zoho-admin.php)save_settings()now explicitly callsschedule_sync()orunschedule_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 globallyincludes/zoho/class-zoho-scheduled-sync.php- Add first-time option hookincludes/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:
- Safari Blocker Bug: Identified and fixed
HVAC_Find_Trainer_Assetscorrectly blocking assets on Safari. - Safety Script Race Condition:
mapgeo-safety.jshas a hard 6-second timeout loop that conflicts with slower resource loading. - Stale Cache Issue: Browser continues to serve old
mapgeo-safety.js(6s timeout) despite file update (30s timeout) and version bump (.fix1). - Environment Constraints:
wp cache flushfailed (command not found), indicating potential restriction on direct WP-CLI use.
Fixes Applied (Pending Verification):
- ✅ Removed Safari Blocker: Corrected logic in
class-hvac-find-trainer-assets.php. - ✅ Increased Timeouts: Updated
assets/js/mapgeo-safety.jsto 30s global timeout. - ✅ Version Bump: Added
.fix1suffix to enqueue version inclass-hvac-mapgeo-safety.php.
Next Steps:
- Resolve caching issue to ensure updated
mapgeo-safety.jsis 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
-
✅ 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
-
✅ Updated
class-zoho-sync.php- All 5 sync methods now accept
$since_timestampparameter - When provided, filters queries by
post_modified >= since_date
- All 5 sync methods now accept
-
✅ 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
- Added
-
✅ 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
- ✅ Backend Pagination:
- All sync methods (
sync_events,sync_users,sync_attendees,sync_rsvps,sync_purchases) now accept$offsetand$limitparameters - Each returns
has_more,next_offset, andtotalfor pagination - Admin endpoint updated to pass offset to sync methods
- All sync methods (
- ✅ 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
- New
Files Modified
includes/zoho/class-zoho-sync.php- Pagination for all 5 sync methodsincludes/admin/class-zoho-admin.php- Offset parameter handlingassets/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
- ✅ Campaign Member Linking:
- Fixed API endpoint:
PUT /Contacts/{id}/Campaigns(was/Campaigns/{id}/Contacts/{id}) - Fixed
log_debug()visibility (private → public)
- Fixed API endpoint:
- ✅ 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_fieldswith hyphenated field names
- measureQuick Email →
- ✅ Email Fallback Logic:
- If attendee email empty, use measureQuick email (and vice versa)
- Only fails if BOTH emails are empty
- ✅ DUPLICATE_DATA Handling:
- When Zoho returns "duplicate exists", extract existing contact ID from error
- Use that ID to update instead of failing
- ✅ 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:
-
✅ OAuth Authentication Verified
- Refresh token exists and is valid
- API connection successful (53 modules accessible)
- Read operations working (Contacts, Campaigns, Users)
-
✅ 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.
-
✅ Sync Class Bug Fixes
- Fixed user roles:
trainer/trainee→hvac_trainer/hvac_master_trainer - Fixed event filter: Removed restrictive
_hvac_event_typemeta query - Fixed event display: Changed
eventDisplayfromlisttocustomto include past events - Fixed WooCommerce dependency: Added graceful error handling
- Fixed user roles:
-
✅ 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_*)
-
✅ 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:
- Events → Campaigns (direct mapping)
- Trainers (hvac_trainer, hvac_master_trainer) → Contacts (with Contact_Type field)
- Ticket Attendees → Contacts + Campaign Members (links Contact ↔ Campaign)
- RSVPs → Leads + Campaign Members (links Lead ↔ Campaign)
- Ticket Orders → Invoices (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 Ticketsincludes/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:
-
✅ 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)
-
✅ Environment Configuration
- Updated
.gitignoreto allow.agent/,.mcp.json,GEMINI.md - Created
/home/ben/dev/upskill-event-manager/.agent/workflows/test.md - Fixed file access blocked by gitignore
- Updated
-
✅ PHP 8+ Compatibility Verification
- Issue:
true|\WP_Errorsyntax causing PHP fatal errors on staging (PHP 8.0) - Fix: Changed to
bool|\WP_Errorinincludes/class-hvac-security-helpers.php:231 - Status: Deployed to staging, verified working
- Issue:
-
✅ 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)
- File:
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)
- ✅ 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>inincludes/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_nonce → hvac_announcements_nonce
Files: includes/class-hvac-announcements-admin.php (line 96)
Status: ✅ Deployed to staging, fully functional
v2.1.6 - Technical Debt Cleanup
Fixes:
- Version synchronization (2.0.0 → 2.1.6 in plugin header)
- FOUC prevention (modal
display: noneby default) - 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)
-
Safety First:
- NEVER delete files outside project directory
- NEVER execute
rm -rfwithout confirmation - NEVER modify system configs (
/etc/*,/var/*) - NEVER deploy to production without explicit request
-
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
-
Testing Mandatory:
node test-comprehensive-validation.js -
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 detailsdocs/CLAUDE-CODE-DEVELOPMENT-BEST-PRACTICES.md- Development patterns
Workflows
.agent/workflows/test.md- Running comprehensive tests (/test)
📋 NEXT ACTIONS
Immediate
- ⏳ Production Deployment - Deploy v2.1.7 + PHP 8+ fixes (pending user approval)
- ✅ PHP 8+ Modernization - Continue Phase 2 modernization
- 🔜 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)
- Playwright Headless Login - Works in headed mode with correct selectors
- jQuery Loading Timing - Brief "jQuery is not defined" error (non-blocking)
- 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