# HVAC Community Events - Project Status **Last Updated:** February 1, 2026 **Current Session:** Tabbed Interface for Find Training Page **Version:** 2.2.6 (Deployed to Staging) --- ## ๐ŸŽฏ NEXT SESSION - CAPTCHA IMPLEMENTATION ### Status: ๐Ÿ“‹ **PLANNED** **Objective:** Add CAPTCHA to all user-facing forms to prevent spam and bot submissions. **Forms to Update:** - Training login form - Trainer registration form - Contact forms (trainer, venue) - Any other public-facing forms --- ## ๐ŸŽฏ CURRENT SESSION - TABBED INTERFACE FOR FIND TRAINING (Feb 1, 2026) ### Status: โœ… **COMPLETE - Deployed to Staging, Verified Working** **Objective:** Refactor the Find Training page sidebar from a single trainer list to a tabbed interface with Trainers, Venues, and Events tabs. ### Changes Made 1. โœ… **Tab Navigation System** (`templates/page-find-training.php`) - Replaced "42 trainers" header with three tabs: Trainers | Venues | Events - Each tab displays dynamic count in parentheses - ARIA accessibility attributes (role="tablist", role="tab", aria-selected) - Keyboard navigation (arrow keys, Home, End) 2. โœ… **Visibility Toggles Relocated** - Moved from map overlay to sidebar header - Colored dots (teal/orange/purple) match marker colors - Only control map marker visibility, not tab content 3. โœ… **Venue Cards** (`assets/js/find-training-map.js`) - Name with building icon - City, State location - "X upcoming events" count 4. โœ… **Event Cards** (`assets/js/find-training-map.js`) - Date badge showing month/day - Event title - Venue name - Cost display - "Past" badge for past events 5. โœ… **Info Modal** (`templates/page-find-training.php`) - "What is Upskill HVAC?" section - "How to Use" instructions - Map Legend (trainer/venue/event markers) 6. โœ… **Context-Aware Search** (`assets/js/find-training-filters.js`) - Placeholder changes based on active tab - Client-side filtering for instant results (150ms debounce) - Falls back to server-side when filters active 7. โœ… **CSS Styling** (`assets/css/find-training-map.css`) - Tab navigation container and button styles - Venue card and event card layouts - Info button and modal styling - Responsive adjustments for tablet/mobile ### Files Modified | File | Change | |------|--------| | `templates/page-find-training.php` | Tab navigation, panels, info modal | | `assets/js/find-training-map.js` | Tab switching, card creators, grid renderers | | `assets/js/find-training-filters.js` | Context-aware search, client-side filtering | | `assets/css/find-training-map.css` | ~300 lines new CSS for tabs, cards, modal | | `includes/class-hvac-plugin.php` | Version bump 2.2.5 โ†’ 2.2.6 (CDN cache bust) | ### Issue Resolved: CDN Cache **Problem:** After deployment, browser loaded old JavaScript without new `initTabs` method. **Root Cause:** CDN cached old assets. Deploy script clears WP/OPcache but not CDN edge cache. **Fix:** Bumped `HVAC_VERSION` from 2.2.5 to 2.2.6, changing script URL query string to force cache refresh. ### Verified on Staging - โœ… 42 trainers tab count - โœ… 9 venues tab count - โœ… 8 events tab count - โœ… Tab switching works with proper ARIA attributes - โœ… Venue cards display correctly - โœ… Event cards with date badges display correctly - โœ… Info modal opens and displays content - โœ… Visibility toggles control map markers --- ## ๐Ÿ“‹ PREVIOUS SESSION - MEASUREQUICK APPROVED TRAINING LABS (Feb 1, 2026) ### Status: โœ… **COMPLETE - Deployed to Staging, Venues Displaying Correctly** **Objective:** Transform /find-training to showcase only measureQuick Approved Training Labs with venue categories, equipment/amenities tags, and contact forms. 1. โœ… **Venue Taxonomies Created** (`includes/class-hvac-venue-categories.php` NEW) - `venue_type` - For lab classification (e.g., "measureQuick Approved Training Lab") - `venue_equipment` - Furnace, Heat Pump, AC, Mini-Split, Boiler, etc. - `venue_amenities` - Coffee, Water, Projector, WiFi, Parking, etc. - All taxonomies registered on `tribe_venue` post type 2. โœ… **9 Approved Training Labs Configured** (via WP-CLI script) - Fast Track Learning Lab (ID: 6631) - Joe Medosch - Progressive Training Lab (ID: 6284) - Samantha Brazie - NAVAC Technical Training Center (ID: 6476) - Andrew Greaves - Stevens Equipment Supply - Phoenix (ID: 6448) - Robert Cone - San Jacinto College South Campus (ID: 6521) - Terry McWilliams - Johnstone Supply - Live Fire Training Lab (ID: 4864) - Dave Petz - Stevens Equipment Supply - Johnstown (ID: 1648) - Phil Sweren - TruTech Tools Training Center (NEW) - Val Buckles - Auer Steel & Heating Supply (NEW) - Mike Breen 3. โœ… **Map Data Filtered by Taxonomy** - `get_venue_markers()` now includes `tax_query` for `mq-approved-lab` term - Only approved training labs appear as venue markers - Equipment, amenities, and POC data included in venue info 4. โœ… **Venue Modal Enhanced** - Equipment badges (teal outline chips) - Amenities badges (gray outline chips) - Contact form with name, email, phone, company, message - POC receives email notification on submission 5. โœ… **6 POC Trainer Accounts Created** - Samantha Brazie, Andrew Greaves, Terry McWilliams - Phil Sweren, Robert Cone, Dave Petz - All with `hvac_trainer` role and approved status ### Files Created | File | Description | |------|-------------| | `includes/class-hvac-venue-categories.php` | Venue taxonomy registration (singleton) | | `scripts/setup-approved-labs.php` | WP-CLI script to configure all labs | | `scripts/check-venue-coordinates.php` | Diagnostic script to verify venue coordinates | | `scripts/geocode-approved-labs.php` | Geocode venues missing coordinates | ### Files Modified | File | Change | |------|--------| | `includes/class-hvac-plugin.php` | Load venue categories class | | `includes/find-training/class-hvac-training-map-data.php` | Add tax_query filter, include equipment/amenities | | `includes/class-hvac-ajax-handlers.php` | Add venue contact form AJAX handler | | `templates/page-find-training.php` | Add equipment/amenities badges, contact form | | `assets/js/find-training-map.js` | Render badges, bind contact form handler | | `assets/css/find-training-map.css` | Equipment/amenities badge styles | ### Issue Resolved: Venues Now Displaying on Map โœ… **Root Cause:** `venue_type` taxonomy wasn't being registered when `get_venue_markers()` ran. `HVAC_Venue_Categories::instance()` was instantiated at 'init' priority 5, but then tried to add hooks to 'init' priority 5 for taxonomy registration. Since WordPress was already processing priority 5 handlers, the hook never fired. **Fix Applied:** 1. **`includes/class-hvac-venue-categories.php`** - Added `did_action('init')` check in constructor - If 'init' has already fired, call `register_taxonomies()` and `create_default_terms()` directly - Otherwise, use the standard hook approach 2. **`includes/find-training/class-hvac-training-map-data.php`** - Fixed HTML entity encoding - Venue names now use `html_entity_decode()` to properly display `&` and `โ€“` characters - Event titles also fixed **Result:** - โœ… All 9 approved training labs now display as orange venue markers on the map - โœ… Venue names display correctly (e.g., "Auer Steel & Heating Supply" not "Auer Steel &...") - โœ… Marker clustering works with mixed trainer/venue markers --- ## ๐Ÿ“‹ PREVIOUS SESSION - FIND TRAINING PAGE ENHANCEMENTS (Feb 1, 2026) ### Status: โœ… **COMPLETE - Deployed to Production** **Objective:** Improve Find Training page UX with viewport sync and marker hover interactions. ### Changes Made 1. โœ… **Viewport Sync** - Sidebar now shows only trainers visible in current map area - Added `visibleTrainers` array to track filtered trainers - Added `syncSidebarWithViewport()` method filtering by map bounds - Map `idle` event triggers sync on pan/zoom - Count shows "X of Y trainers" when zoomed in 2. โœ… **Marker Hover Interaction** - Info window appears on hover - Added `mouseover` event listener to trainer/venue markers - Set `optimized: false` on markers for reliable hover events - Hover shows info window preview with "View Profile" button - Click on "View Profile" opens full modal with contact form 3. โœ… **Legacy URL Redirects** - `/find-a-trainer/` โ†’ `/find-training/` (301 redirect) - `/find-trainer/` โ†’ `/find-training/` (301 redirect) - Removed old page from Page Manager ### Files Modified | File | Change | |------|--------| | `assets/js/find-training-map.js` | Added viewport sync, hover events, optimized:false | | `assets/js/find-training-filters.js` | Updated filter handler for visibleTrainers | | `includes/class-hvac-route-manager.php` | Added legacy URL redirects | | `includes/class-hvac-page-manager.php` | Removed find-a-trainer page definition | | `includes/class-hvac-plugin.php` | Version bumped to 2.2.4 | ### Verified Behavior - โœ… Hover over marker โ†’ Info window appears immediately - โœ… Click "View Profile" โ†’ Full modal with trainer details + contact form - โœ… Pan/zoom map โ†’ Sidebar updates to show visible trainers only - โœ… Legacy URLs redirect to new page --- ## ๐Ÿ“‹ PREVIOUS SESSION - FIND TRAINING PAGE IMPLEMENTATION (Jan 31 - Feb 1, 2026) ### Status: โœ… **COMPLETE - Deployed to Production** **Objective:** Replace the buggy MapGeo-based `/find-a-trainer` page with a new `/find-training` page built from scratch using Google Maps JavaScript API. ### Why This Change The existing IGM/amCharts implementation had a fundamental bug that corrupted marker coordinates (longitude gets overwritten with latitude). After multiple fix attempts, building fresh with Google Maps API provides: - Full control over marker data - No third-party plugin dependencies - Better long-term maintainability - Ability to show both trainers AND venues ### Files Created (8 new files) | File | Description | |------|-------------| | `includes/find-training/class-hvac-find-training-page.php` | Main page handler (singleton), AJAX endpoints, asset enqueuing | | `includes/find-training/class-hvac-training-map-data.php` | Data provider for trainer/venue markers with caching | | `includes/find-training/class-hvac-venue-geocoding.php` | Auto-geocoding for TEC venues via Google API | | `templates/page-find-training.php` | Page template with map, filters, modals | | `assets/js/find-training-map.js` | Google Maps initialization, markers, clustering | | `assets/js/find-training-filters.js` | Filter handling, geolocation, AJAX | | `assets/css/find-training-map.css` | Complete responsive styling | | `assets/images/marker-trainer.svg` | Teal person icon for trainers | | `assets/images/marker-venue.svg` | Orange building icon for venues | ### Files Modified (3 files) | File | Change | |------|--------| | `includes/class-hvac-page-manager.php` | Added find-training page definition | | `includes/class-hvac-plugin.php` | Load new find-training classes | | `includes/class-hvac-ajax-handlers.php` | Added contact form AJAX handler | ### Multi-Model Code Review Findings & Fixes Ran comprehensive code review using GPT-5, Gemini 3, and Zen MCP tools. Found and fixed 6 issues: | # | Severity | Issue | Fix | |---|----------|-------|-----| | 1 | **CRITICAL** | Missing `hvac_submit_contact_form` AJAX handler | Added full handler with rate limiting, validation, email | | 2 | **HIGH** | XSS risk in InfoWindow onclick handlers | Replaced with DOM creation + addEventListener | | 3 | **MEDIUM** | Uncached filter dropdown SQL queries | Added wp_cache with 1-hour TTL | | 4 | **MEDIUM** | AJAX race condition on rapid filters | Added request abort handling | | 5 | **LOW** | Hardcoded `/trainer/registration/` URL | Changed to `site_url()` | | 6 | **LOW** | `alert()` for geolocation errors | Added inline dismissible notification | ### Features Implemented - โœ… Google Maps with custom trainer/venue markers - โœ… MarkerClusterer for dense areas - โœ… Filter by State, Certification, Training Format - โœ… Search by name/location - โœ… "Near Me" geolocation button - โœ… Trainer/Venue toggle switches - โœ… Trainer profile modal with contact form - โœ… Venue info modal with upcoming events - โœ… Trainer directory grid below map - โœ… 301 redirect from `/find-a-trainer` to `/find-training` - โœ… Auto-geocoding for new venues - โœ… Rate-limited batch geocoding for existing venues ### Deployment Status - โœ… Deployed to staging - โœ… Map loads with markers and clustering - โœ… Filters working (state, certification, format) - โœ… Contact form functional - โœ… Deployed to production --- ## ๐Ÿ“‹ PREVIOUS SESSION - E2E TESTING & BUG FIXES (Feb 1, 2026) ### Status: โœ… **COMPLETE - Deployed to Staging, Ready for Production** **Objective:** Deploy security fixes to staging, run E2E tests, fix discovered bugs, and validate all functionality. ### Deployment & Testing Summary 1. โœ… **Deployed to Staging** - All 12 security fixes from previous session 2. โœ… **E2E Tests Passed** - Master trainer pages, security endpoints verified 3. โœ… **Discovered & Fixed 2 Critical Bugs** - Trainers table, event pages 4. โœ… **Created E2E Testing Skill** - `.claude/commands/e2e-visual-test.md` 5. โœ… **Added Staging Email Filter** - Prevents accidental user spam ### Bugs Found & Fixed | Bug | Severity | Root Cause | Fix | |-----|----------|------------|-----| | **Trainers table empty** | HIGH | `ajax_filter_trainers()` used complex SQL that returned empty; `count_trainers_by_status()` only queried `hvac_trainer` role | Rewrote to use `get_trainers_table_data()` (same as working dashboard); fixed role query to include both roles | | **Event pages blank** | HIGH | Template path mismatch: code referenced `page-trainer-event-manage.php` but file is `page-manage-event.php` | Fixed path in `class-hvac-event-manager.php:138` | ### Files Modified (4 files) 1. **`includes/class-hvac-master-trainers-overview.php`** - Rewrote `ajax_filter_trainers()` to use reliable `get_trainers_table_data()` - Fixed `count_trainers_by_status()` to include `hvac_master_trainer` role - Now shows 53 trainers, 5 active (was showing 0) 2. **`includes/class-hvac-event-manager.php`** - Fixed template path: `page-trainer-event-manage.php` โ†’ `page-manage-event.php` - Event creation form now fully functional 3. **`hvac-community-events.php`** - Added staging email filter (only `ben@tealmaker.com` receives emails) - Protects real users from test emails during development 4. **`.claude/commands/e2e-visual-test.md`** (new) - Created E2E visual testing skill for Playwright MCP browser tools - Documents login procedure, test sequence, credentials ### E2E Test Results | Feature | Status | Notes | |---------|--------|-------| | Master Trainer Login | โœ… PASS | Custom `/training-login/` works | | Master Dashboard | โœ… PASS | Stats, tables, AJAX functional | | Trainers Table | โœ… PASS | 53 trainers displayed correctly | | Announcements | โœ… PASS | Modal opens, form accessible | | Event Creation | โœ… PASS | Full form with all TEC fields | | Certificate Reports | โœ… PASS | Empty state (needs events) | | Security Endpoints | โœ… PASS | 4/4 properly return 401/400 | ### Staging Email Protection Emails on staging are now filtered: - **Allowed:** `ben@tealmaker.com`, `ben@measurequick.com` - **Blocked:** All other recipients (logged for debugging) - **Subject Prefix:** `[STAGING]` added to allowed emails ### Next Steps 1. โณ Deploy to production: `./scripts/deploy.sh production` 2. โณ Verify production functionality 3. โณ Monitor for any issues --- ## ๐Ÿ“‹ PREVIOUS SESSION - MULTI-MODEL SECURITY CODE REVIEW (Jan 31, 2026) ### Status: โœ… **COMPLETE - Deployed to Staging** **Objective:** Comprehensive security and business logic code review using 4 AI models (GPT-5, Gemini 3, Kimi K2.5, Zen MCP) across 11 critical files (~9,000 lines). ### Critical Issues Found & Fixed (12 total) | ID | Severity | Issue | File | |----|----------|-------|------| | C1 | **CRITICAL** | Passwords stored in transients | `class-hvac-registration.php` | | U1 | **CRITICAL** | O(3600) token verification loop (DoS) | `class-hvac-ajax-security.php` | | U2 | **HIGH** | `remove_all_actions()` breaks WP isolation | `class-hvac-plugin.php` | | C2 | **HIGH** | Encryption key in same database as data | `class-hvac-secure-storage.php` | | M3 | **HIGH** | Revoked certificates still downloadable | `class-certificate-manager.php` | | U3 | **HIGH** | Security headers not applied to AJAX | `class-hvac-ajax-security.php` | | C3 | **MEDIUM** | IP spoofing undermines rate limiting | `class-hvac-security.php` | | M1 | **MEDIUM** | Weak CSP with `unsafe-eval` | `class-hvac-ajax-security.php` | | C5 | **MEDIUM** | Duplicate component initialization | `class-hvac-plugin.php` | | U9 | **MEDIUM** | File-scope side-effect initialization | `class-hvac-trainer-profile-manager.php` | | U11 | **LOW** | Timezone inconsistency in cert numbers | `class-certificate-manager.php` | | U4 | **HIGH** | zoho-config.php not in .gitignore | `.gitignore` | ### Deliverables - โœ… **Full Report:** `MULTI-MODEL-CODE-REVIEW-REPORT.md` - โœ… **12 Security Fixes:** All implemented and deployed to staging --- ## ๐Ÿ“‹ PREVIOUS SESSION - MASTER TRAINER PROFILE EDIT ENHANCEMENT (Jan 9, 2026) ### Status: โœ… **COMPLETE - Deployed to Production** **Objective:** Fix broken button styling and add all trainer profile fields to the master trainer profile edit page. **Issues Fixed:** 1. **Button Styling Broken** - "Back to Dashboard" and "Cancel" buttons appeared faded/invisible due to CSS conflicts with theme 2. **Missing Profile Fields** - Only showing basic name fields, needed all trainer profile fields 3. **No Password Reset** - Master trainers couldn't trigger password resets for trainers they manage ### Changes Made 1. โœ… **Fixed Button Styling** (`templates/page-master-trainer-profile-edit-simple.php`) - Added scoped CSS with new class names (`hvac-btn-primary`, `hvac-btn-secondary`, `hvac-btn-outline`) - Avoids theme CSS conflicts by using page-specific selectors - Proper colors, hover states, and responsive behavior 2. โœ… **Added All Profile Fields** (6 complete sections) - **Profile Settings:** Visibility (Public/Private) - **Certification Information:** Status, Type, Date Certified - **Personal Information:** Name, Email, LinkedIn URL, Bio - **Professional Information:** Accreditation, Training Audience/Formats/Locations/Resources (checkboxes) - **Business Information:** Business Type, Revenue Target, Application Details - **Location Information:** City, State, Country, Coordinates with re-geocode button 3. โœ… **Added Password Reset Button** - New "Send Password Reset Email" button in Personal Information section - Uses WordPress built-in `retrieve_password()` function - Shows status feedback (Sending... / Sent! / Error) - Requires master trainer or admin permissions - All actions logged for audit trail 4. โœ… **Added AJAX Handler** (`includes/class-hvac-ajax-handlers.php`) - New `hvac_send_password_reset` endpoint - Nonce verification, permission checks, input validation - Secure implementation using WordPress core functions ### Files Modified - `templates/page-master-trainer-profile-edit-simple.php` - Complete rewrite with all fields - `includes/class-hvac-ajax-handlers.php` - Added password reset handler ### URLs - **Production:** `https://upskillhvac.com/master-trainer/edit-trainer-profile/?user_id=75` - **Staging:** `https://upskill-staging.measurequick.com/master-trainer/edit-trainer-profile/?user_id=75` --- ## ๐Ÿ“‹ PREVIOUS SESSION - TEC COMMUNITY EVENTS DEPENDENCY ANALYSIS (Jan 5, 2026) ### Status: โœ… **COMPLETE - Documented as Technical Debt** **Objective:** Analyze whether "The Events Calendar: Community" (TEC CE) plugin is still being used after recent refactoring. **Findings:** - The plugin **still actively relies on TEC CE** for event creation/editing - Core shortcode `[tribe_community_events]` is used in 7 template/class files - TEC CE hooks are used for field processing and form customization - `HVAC_Event_Manager` has custom CRUD capabilities but production paths use TEC CE **Removal Scope:** - **Estimated effort:** 9-14 days of development - **Key work:** Custom forms, date pickers, validation, template updates, testing - **Risk:** Recurring events complexity, Event Tickets integration **Decision:** Deferred as technical debt. Current implementation is functional and stable. ### Deliverables 1. โœ… **Analysis Report:** `docs/reports/TEC-COMMUNITY-EVENTS-DEPENDENCY-ANALYSIS.md` 2. โœ… **CLAUDE.md Updated:** Added Technical Debt section 3. โœ… **Status.md Updated:** This entry --- ## ๐Ÿ“‹ PREVIOUS 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 --- ## ๐Ÿ“‹ PREVIOUS SESSION - PUBLIC MAP & DIRECTORY FIX (Dec 21, 2025) ### Status: ๐Ÿ”„ **IN PROGRESS - Deployed to Staging (Strategy H)** **Problem:** Map markers missing. Data analysis reveals markers have identical Latitude and Longitude values (corruption). **Root Cause:** - IGM Plugin's client-side processing corrupts `longitude` by overwriting it with `latitude` immediately before rendering. - Previous PHP Injection strategies (D-G) caused 500 errors due to `WP_Query` timing/context issues in the footer. **Solution (Strategy H):** 1. โœ… **Javascript Interceptor:** Injected a robust interceptor script in `class-hvac-mapgeo-integration.php`. 2. โœ… **Mechanism:** Uses `Object.defineProperty` on `window.iMapsData` to catch the data assignment *before* the map plugin sees it. 3. โœ… **Repair Logic:** Detects corrupted markers (Lat == Lng) and instantly restores correct values from safe `lat`/`lng` backup keys provided by PHP. 4. โœ… **Cleanup:** Removed dangerous PHP query injections that were causing server errors. **Current Status:** - Fix deployed to Staging. - Pending verification of visible markers and "Healed" console logs. **Next Steps:** 1. Verify map renders correctly on Staging. 2. Deploy to Production. --- ## ๐Ÿ“‹ 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`/`trainee` โ†’ `hvac_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:** - **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 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) 5. โœ… **Master Trainer Navigation Dropdown Fix** (Dec 16, 2025) - **Issue:** Green/teal colored boxes appearing in navigation toolbar instead of dropdown arrows - **Root Cause:** Empty `` elements with CSS background styling - **Fix:** Replaced with `โ–ผ` 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_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:** 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:** ```bash # 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:** ```bash ./scripts/deploy.sh staging ``` **Verify Deployment:** ```bash ./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:** ```bash 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:** ```bash ./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*