Some checks failed
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1156 lines
48 KiB
Markdown
1156 lines
48 KiB
Markdown
# HVAC Community Events - Project Status
|
||
|
||
**Last Updated:** February 6, 2026
|
||
**Current Session:** Zoho CRM Sync Production Fix
|
||
**Version:** 2.2.11 (Deployed to Production)
|
||
|
||
---
|
||
|
||
## 🎯 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 - ZOHO CRM SYNC PRODUCTION FIX (Feb 6, 2026)
|
||
|
||
### Status: ✅ **COMPLETE - Deployed to Production (v2.2.11) - 64/64 Trainers Syncing**
|
||
|
||
**Objective:** Fix Zoho CRM user sync that was silently failing on production - 0/65 users syncing despite "connection successful" status.
|
||
|
||
### Issues Found & Fixed (iterative production debugging)
|
||
|
||
1. **Version Constant Mismatch** (`includes/class-hvac-plugin.php`)
|
||
- `HVAC_PLUGIN_VERSION` stuck at `'2.0.0'` while `HVAC_VERSION` was `'2.2.10'`
|
||
- Admin JS used `HVAC_PLUGIN_VERSION` for cache busting, so browser served old JS without reset handler
|
||
- Fix: Bumped both constants to `'2.2.11'`
|
||
|
||
2. **GET Request Search Criteria Ignored** (`includes/zoho/class-zoho-sync.php`)
|
||
- `sync_users()` passed search criteria as `$data` parameter to `make_api_request()`
|
||
- But `make_api_request()` ignores `$data` for GET requests (line 345 only includes body for POST/PUT/PATCH)
|
||
- Every Zoho contact search returned unfiltered results, causing all syncs to fail
|
||
- Fix: Moved criteria into URL query string: `/Contacts/search?criteria=(Email:equals:...)`
|
||
|
||
3. **Error Reporting Priority** (`includes/zoho/class-zoho-sync.php`)
|
||
- `validate_api_response()` checked generic `error` key before Zoho-specific `data[0]` errors
|
||
- Users saw "API error with status code 400" instead of actionable field-level errors
|
||
- Fix: Reordered to check Zoho `data[0]` errors first, added field-level detail (api_name, expected_data_type, info)
|
||
|
||
4. **Phone Field Validation** (`includes/zoho/class-zoho-sync.php`)
|
||
- Zoho rejects invalid phone formats with HTTP 400
|
||
- Fix: Strip non-digit chars, require 10+ digits, only include Phone field when valid
|
||
|
||
5. **Last_Name Required Field** (`includes/zoho/class-zoho-sync.php`)
|
||
- Zoho Contacts module requires Last_Name but some WP users had empty last names
|
||
- Fix: Fallback chain: `last_name` meta → `display_name` → `user_login`
|
||
|
||
6. **Spam Account Cleanup** (production WP-CLI)
|
||
- User 14 (`rigobertohugo19`, `info103@noreply0.com`) was a spam/bot registration with no name
|
||
- Demoted from `hvac_trainer` to `subscriber`
|
||
|
||
### Production Sync Results (iterative)
|
||
|
||
| Attempt | Synced | Failed | Issue |
|
||
|---------|--------|--------|-------|
|
||
| 1st (pre-fix) | 0 | 65 | Search criteria not sent to Zoho API |
|
||
| 2nd (search fix) | 63 | 2 | Generic "status code 400" errors |
|
||
| 3rd (error detail) | 0 | 2 | User 57: invalid Phone, User 14: missing Last_Name |
|
||
| 4th (data validation) | 31 | 1 | User 57 phone still failing (7-digit threshold too low) |
|
||
| 5th (10-digit threshold) | 26 | 0 | **All 65 trainers synced** |
|
||
| Final (User 14 demoted) | **64/64** | **0** | All active trainers syncing |
|
||
|
||
### Files Modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `includes/class-hvac-plugin.php` | Synced `HVAC_PLUGIN_VERSION` to `'2.2.11'` (was stuck at `'2.0.0'`) |
|
||
| `includes/zoho/class-zoho-sync.php` | Search criteria in URL, error priority fix, phone sanitization, Last_Name fallback |
|
||
|
||
### Git Commits
|
||
- `03b9bce5` - fix(zoho): Fix silent sync failures with API response validation and hash reset
|
||
- `4c22b9db` - fix(zoho): Fix user sync search criteria and improve data validation
|
||
|
||
---
|
||
|
||
## 📋 PREVIOUS SESSION - ZOHO CRM SYNC ARCHITECTURE FIX (Feb 6, 2026)
|
||
|
||
### Status: ✅ **COMPLETE - Deployed to Production**
|
||
|
||
**Objective:** Fix Zoho CRM integration that appeared connected but was silently failing to sync data (events, attendees, ticket sales not appearing in Zoho CRM).
|
||
|
||
### Root Cause Analysis (4-model consensus: GPT-5, Gemini 3, Zen Code Review, Zen Debug)
|
||
|
||
The sync pipeline had a "silent failure" architecture:
|
||
1. **Connection test only uses GET** - bypasses staging write block, giving false confidence
|
||
2. **Staging mode returned fake `'status' => 'success'`** for blocked writes - appeared successful
|
||
3. **Sync methods unconditionally updated `_zoho_sync_hash`** after any "sync" - poisoned hashes
|
||
4. **Subsequent syncs compared hashes, found matches, skipped all records** - permanent data loss
|
||
5. **No API response validation** - even real Zoho errors were silently ignored
|
||
|
||
### Fixes Implemented
|
||
|
||
1. **API Response Validation** (`includes/zoho/class-zoho-sync.php`)
|
||
- Added `validate_api_response()` helper method
|
||
- Checks for WP_Error, staging mode blocks, HTTP errors, Zoho error codes
|
||
- Confirms success with ID extraction before treating a sync as successful
|
||
|
||
2. **Hash-Only-On-Success** (`includes/zoho/class-zoho-sync.php`)
|
||
- All 5 sync methods (events, users, attendees, rsvps, purchases) rewritten
|
||
- `_zoho_sync_hash` only updates when Zoho API confirms the write succeeded
|
||
- Failed syncs increment `$results['failed']` with error details
|
||
- Changed `catch (Exception)` to `catch (\Throwable)` for comprehensive error handling
|
||
|
||
3. **Staging Mode Detection Fix** (`includes/zoho/class-zoho-crm-auth.php`)
|
||
- Replaced fragile `strpos()` substring matching with `wp_parse_url()` hostname comparison
|
||
- Production (`upskillhvac.com` / `www.upskillhvac.com`) explicitly whitelisted
|
||
- All other hostnames default to staging mode
|
||
- `HVAC_ZOHO_PRODUCTION_MODE` / `HVAC_ZOHO_STAGING_MODE` constants can override
|
||
- Staging fake responses now return `'skipped_staging'` instead of misleading `'success'`
|
||
|
||
4. **Admin UI: Hash Reset & Staging Warning** (`includes/admin/class-zoho-admin.php`, `assets/js/zoho-admin.js`)
|
||
- Added `reset_sync_hashes()` AJAX handler - clears all `_zoho_sync_hash` from postmeta and usermeta
|
||
- Added "Force Full Re-sync (Reset Hashes)" button with confirmation dialog
|
||
- Connection test now surfaces staging warning when staging mode is active
|
||
|
||
5. **Staging Environment Fix** (staging `wp-config.php`)
|
||
- Removed `HVAC_ZOHO_PRODUCTION_MODE` constant from staging wp-config.php
|
||
- Staging now correctly blocks all Zoho write operations via hostname detection
|
||
- GET requests (reads) still pass through for testing
|
||
|
||
### Files Modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `includes/zoho/class-zoho-sync.php` | Added `validate_api_response()`, rewrote all 5 sync methods for validated hashing |
|
||
| `includes/zoho/class-zoho-crm-auth.php` | Rewrote `is_staging_mode()` with hostname parsing, changed fake response status |
|
||
| `includes/admin/class-zoho-admin.php` | Added `reset_sync_hashes()` handler, reset button HTML, staging warning in connection test |
|
||
| `assets/js/zoho-admin.js` | Added reset hashes button handler, staging warning display in connection test |
|
||
|
||
---
|
||
|
||
## 📋 PREVIOUS SESSION - NEAR ME BUTTON MOBILE FIX (Feb 6, 2026)
|
||
|
||
### Status: ✅ **COMPLETE - Deployed to Staging**
|
||
|
||
**Objective:** Fix mobile layout issue where the "Near Me" button caused the search bar to shrink when location was granted.
|
||
|
||
### Issues Found & Fixed
|
||
|
||
1. ✅ **CSS/HTML Button Structure Bug** (`assets/js/find-training-filters.js`)
|
||
- When the Near Me button state changed, the HTML was replaced without the `.hvac-btn-text` wrapper class
|
||
- On mobile, CSS hides `.hvac-btn-text`, but unwrapped text was visible causing layout issues
|
||
- Fixed in 5 locations: loading state, success state, error reset, clear filters, remove location filter
|
||
|
||
2. ✅ **No Feedback for Empty Results** (`assets/js/find-training-filters.js`)
|
||
- When "Near Me" filter returned no results within 100km, user saw empty map with no explanation
|
||
- Added notification: "No trainers, venues, or events found within 100km of your location. Try removing the 'Near Me' filter to see all results."
|
||
|
||
### Files Modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `assets/js/find-training-filters.js` | Fixed button HTML to preserve `.hvac-btn-text` wrapper; added empty results notification |
|
||
|
||
### Code Changes
|
||
|
||
**Button HTML Fix (5 locations):**
|
||
```javascript
|
||
// Before (broken on mobile):
|
||
$button.html('<span class="dashicons dashicons-yes-alt"></span> Near Me');
|
||
|
||
// After (correct):
|
||
$button.html('<span class="dashicons dashicons-yes-alt"></span><span class="hvac-btn-text">Near Me</span>');
|
||
```
|
||
|
||
**Empty Results Notification:**
|
||
```javascript
|
||
if (self.userLocation) {
|
||
const totalResults = HVACTrainingMap.trainers.length +
|
||
HVACTrainingMap.venues.length +
|
||
HVACTrainingMap.events.length;
|
||
if (totalResults === 0) {
|
||
self.showLocationError('No trainers, venues, or events found within 100km...');
|
||
}
|
||
}
|
||
```
|
||
|
||
### Mobile Testing Performed
|
||
- ✅ 375x812 (iPhone X) - Map and markers display correctly
|
||
- ✅ 320x568 (iPhone SE) - Map and markers display correctly
|
||
- ✅ Cluster markers expand on click
|
||
- ✅ Individual trainer markers clickable
|
||
- ✅ Info windows display correctly
|
||
- ✅ Profile modal opens and displays correctly
|
||
|
||
---
|
||
|
||
## 📋 PREVIOUS SESSION - CHAMPION DIFFERENTIATION ON FIND TRAINING (Feb 2, 2026)
|
||
|
||
### Status: ✅ **COMPLETE - Deployed to Production**
|
||
|
||
**Objective:** Differentiate measureQuick Certified Champions from Trainers on the Find Training map. Champions do not offer public training, so they should be displayed differently.
|
||
|
||
### Changes Made
|
||
|
||
1. ✅ **Backend Data** (`includes/find-training/class-hvac-training-map-data.php`)
|
||
- Added `is_champion` flag for trainers with "Certified measureQuick Champion" certification
|
||
- Champions return empty `city` field (only state shown)
|
||
|
||
2. ✅ **Champion Marker Icon** (`assets/js/find-training-map.js`)
|
||
- Added `getChampionIcon()` method with white outline (vs green for Trainers)
|
||
- Champions use distinct visual appearance on map
|
||
|
||
3. ✅ **Sidebar Cards** (`assets/js/find-training-map.js`)
|
||
- Champions show only state (e.g., "Ohio" not "Canton, Ohio")
|
||
- Champions have non-clickable cards (no modal popup)
|
||
- Added `hvac-champion-card` CSS class
|
||
|
||
4. ✅ **Info Windows** (`assets/js/find-training-map.js`)
|
||
- Champions show only state in location
|
||
- No "View Profile" button for Champions
|
||
- Fixed location formatting to handle empty city gracefully
|
||
|
||
5. ✅ **Sorting** (`assets/js/find-training-map.js`)
|
||
- Champions sorted to end of trainer list
|
||
- Secondary sort by name for stable ordering
|
||
- Applied to both `loadMapData` and `loadTrainerDirectory`
|
||
|
||
6. ✅ **CSS Styling** (`assets/css/find-training-map.css`)
|
||
- Champion cards have non-clickable appearance
|
||
- No hover effects (cursor: default, no transform/shadow)
|
||
|
||
### Files Modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `includes/find-training/class-hvac-training-map-data.php` | Added `is_champion` flag, empty city for champions |
|
||
| `assets/js/find-training-map.js` | Champion icon, card display, click prevention, sorting |
|
||
| `assets/css/find-training-map.css` | Champion card non-clickable styling |
|
||
|
||
### Verification (Staging)
|
||
- ✅ API returns `is_champion: true` for 18 champions
|
||
- ✅ Champions have empty city in API response
|
||
- ✅ Champions sorted to end of list
|
||
- ✅ Champion cards show only state
|
||
- ✅ Clicking champion card does NOT open modal
|
||
- ✅ Clicking trainer card DOES open modal (regression test)
|
||
|
||
### Code Review Findings (Gemini 3)
|
||
- **Fixed:** Location formatting bug - empty city could show ", California"
|
||
- **Fixed:** Unstable sort order - added secondary sort by name
|
||
|
||
---
|
||
|
||
## 📋 PREVIOUS SESSION - TABBED INTERFACE FOR FIND TRAINING (Feb 1, 2026)
|
||
|
||
### Status: ✅ **COMPLETE - Deployed to Production**
|
||
|
||
**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 `<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_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.2.11 (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*
|