From 0b033f7f4f23815ad128b63fcaf59cc264addc82 Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 9 Feb 2026 19:27:47 -0400 Subject: [PATCH] docs: condense Status.md from 1348 to 131 lines Compress previous session entries to one-line summaries, remove duplicate info already in CLAUDE.md (guidelines, architecture, testing). Keep current session detail and previous session git hashes. Co-Authored-By: Claude Opus 4.6 --- Status.md | 1345 +++-------------------------------------------------- 1 file changed, 64 insertions(+), 1281 deletions(-) diff --git a/Status.md b/Status.md index 9a7060f1..a6d083b2 100644 --- a/Status.md +++ b/Status.md @@ -1,14 +1,13 @@ # HVAC Community Events - Project Status **Last Updated:** February 9, 2026 -**Current Session:** Marker Visibility Toggle Checkbox Refactor **Version:** 2.2.18 (Deployed to Production) --- -## ๐ŸŽฏ NEXT SESSION - CAPTCHA IMPLEMENTATION +## NEXT SESSION - CAPTCHA IMPLEMENTATION -### Status: ๐Ÿ“‹ **PLANNED** +### Status: PLANNED **Objective:** Add CAPTCHA to all user-facing forms to prevent spam and bot submissions. @@ -20,9 +19,9 @@ --- -## ๐ŸŽฏ CURRENT SESSION - MARKER VISIBILITY TOGGLE CHECKBOX REFACTOR (Feb 9, 2026) +## CURRENT SESSION - MARKER VISIBILITY TOGGLE CHECKBOX REFACTOR (Feb 9, 2026) -### Status: โœ… **COMPLETE - Deployed to Production (v2.2.18)** +### Status: COMPLETE - Deployed to Production (v2.2.18) **Objective:** Refactor the marker visibility toggles on the Find Training page from standalone colored dots into inline checkboxes beside each category tab heading. @@ -32,22 +31,14 @@ - Removed standalone `hvac-visibility-toggles` div with 3 colored dot toggles - Moved each checkbox inline into its corresponding tab button (`Events`, `Trainers`, `Venues`) - `onclick="event.stopPropagation()"` on labels prevents checkbox clicks from triggering tab switches - - Checkbox IDs unchanged (`hvac-show-events`, `hvac-show-trainers`, `hvac-show-venues`) โ€” no JS changes needed + - Checkbox IDs unchanged โ€” no JS changes needed 2. **Custom Checkbox Styling** (`assets/css/find-training-map.css`) - - Replaced old dot-based toggle CSS with custom checkbox styles - - 14x14px checkboxes with rounded corners, white background, CSS checkmark - - Category-specific colors when checked: teal for events (`#0ebaa6`), green for trainers (`#6aad1e`), green for venues (`#89c92e`) - - Unchecked state: grey-bordered empty box - - Tablet: smaller 12px checkboxes - - Mobile (<768px): checkboxes hidden (same behavior as before) + - 14x14px custom checkboxes with category-specific fill colors when checked + - Trainer checkbox uses explicit `#6aad1e` (CSS variable `--hvac-trainer-color` is too light) + - Tablet: 12px checkboxes; Mobile (<768px): hidden -3. **Trainer Checkbox Color Fix** (`assets/css/find-training-map.css`) - - `--hvac-trainer-color` CSS variable is `#f0f7e8` (near-white), too light for checkbox fill - - Overrode trainer checkbox specifically with `#6aad1e` for visible green - -4. **Version Bump** (`includes/class-hvac-plugin.php`) - - Bumped `HVAC_VERSION` and `HVAC_PLUGIN_VERSION` from `2.2.17` to `2.2.18` for CDN cache busting +3. **Version Bump** (`includes/class-hvac-plugin.php`) โ€” `2.2.17` โ†’ `2.2.18` ### Files Modified @@ -57,1291 +48,83 @@ | `assets/css/find-training-map.css` | Replaced dot toggle CSS with checkbox styles, responsive adjustments | | `includes/class-hvac-plugin.php` | Version bump `2.2.17` โ†’ `2.2.18` | -### Verification - -- โœ… All 3 checkboxes render inline beside tab headings with category colors -- โœ… Unchecking a checkbox removes that category's markers from map -- โœ… Re-checking restores markers -- โœ… Tab switching works independently of checkbox state -- โœ… Counts display correctly: Events (8), Trainers (42), Venues (9) -- โœ… No JS changes required โ€” existing event handlers work with unchanged checkbox IDs - ---- - -## ๐Ÿ“‹ PREVIOUS SESSION - FIND TRAINING TAB REORDER, MARKER HIGHLIGHTING & MAP RESET (Feb 9, 2026) - -### Status: โœ… **COMPLETE - Deployed to Production (v2.2.17)** - -**Objective:** Reorder Find Training page tabs to make Events the default, add visual marker highlighting when switching tabs, add a map reset button, and fix mobile overflow caused by the changes. - -### Changes Made - -1. **Tab Reorder: Events First** (`templates/page-find-training.php`, `assets/js/find-training-map.js`) - - Moved Events tab from 3rd to 1st position (default active tab) - - Tab order is now: **Events | Trainers | Venues** - - Updated search placeholder to "Search events..." - - Updated skip link to target `#hvac-event-grid` - - Updated filter bar aria-label for all three categories - - Reordered tab panels to match (Events panel active with loading spinner) - -2. **Marker Highlighting on Tab Selection** (`assets/js/find-training-map.js`) - - Added 4 highlighted icon methods: `getTrainerIconHighlighted()`, `getChampionIconHighlighted()`, `getVenueIconHighlighted()`, `getEventIconHighlighted()` - - Highlighted icons are larger (scale +4) with brighter/thicker strokes (strokeWeight 3) - - URL-based icons scale from 32x32 to 40x40 with adjusted anchors - - Added `highlightMarkersForTab(tab)` method with no-map guard - - Highlighted markers get `zIndex: 100` (vs default `1`) to render on top - - Called from both `switchTab()` and `updateMarkers()` - -3. **Map Reset Button** (`templates/page-find-training.php`, `assets/js/find-training-map.js`, `assets/css/find-training-map.css`) - - Added reset button (rotate icon) positioned bottom-right of map container - - Calls `fitBounds()` to restore original zoom encompassing all markers - - Styled to match Google Maps UI controls (white, rounded, shadow) - -4. **Mobile Overflow Fix** (`assets/css/find-training-map.css`) - - **Symptom:** Making Events the default tab exposed long event titles (e.g., "measureQuick 101: Cooling and Heat Pump Commissioning") that pushed sidebar beyond viewport width - - **Root Cause:** Tablet media query had `overflow: visible !important` on `.hvac-sidebar`, overriding base `overflow: hidden` - - **Fix:** Changed to `overflow-x: hidden !important; overflow-y: visible !important;` - - Also added `overflow: hidden` and `min-width: 0; text-overflow: ellipsis` to tab buttons - -5. **Version Bump** (`includes/class-hvac-plugin.php`) - - Bumped `HVAC_VERSION` and `HVAC_PLUGIN_VERSION` from `2.2.14` to `2.2.17` - - Intermediate bumps (2.2.15, 2.2.16) needed during debugging to bust CSS cache - -### Files Modified - -| File | Change | -|------|--------| -| `templates/page-find-training.php` | Reorder tabs/panels (Events first), update placeholder/skip link/aria, add reset button | -| `assets/js/find-training-map.js` | Default to `'events'`, 4 highlighted icon methods, `highlightMarkersForTab()`, `resetMapView()`, dynamic `showLoading()` | -| `assets/css/find-training-map.css` | Reset button styles, mobile overflow fix (`overflow-x: hidden`), tab overflow protection | -| `includes/class-hvac-plugin.php` | Version bump `2.2.14` โ†’ `2.2.17` | - ### Git Commit -- `9dbe472c` - feat(find-training): Reorder tabs (Events first), add marker highlighting and map reset - -### Verification - -- โœ… Events tab active and first on page load, placeholder says "Search events..." -- โœ… Event markers highlighted (larger, brighter) by default -- โœ… Switching tabs highlights corresponding marker category, others revert to normal -- โœ… Highlighted markers render on top (zIndex 100) -- โœ… Reset button restores original zoom/bounds after zooming in -- โœ… Mobile (375px): no horizontal overflow, sidebar fits viewport -- โœ… Keyboard tab navigation still works (arrow keys) +- `95382ac3` - feat(find-training): Refactor marker visibility dots into inline tab checkboxes --- -## ๐Ÿ“‹ PREVIOUS SESSION - MOBILE FIND TRAINING SCROLL FIX (Feb 9, 2026) +## PREVIOUS SESSIONS (Reverse Chronological) -### Status: โœ… **COMPLETE - Deployed to Production (v2.2.14)** +### Find Training Tab Reorder, Marker Highlighting & Map Reset โ€” Feb 9, 2026 (v2.2.17) +Reordered tabs to Events first (default), added marker highlighting on tab switch (larger/brighter icons, zIndex 100), added map reset button, fixed mobile overflow from long event titles. `9dbe472c` -**Objective:** Fix mobile scrolling on the Find Training page โ€” users could not scroll down to see the trainer, venue, and event lists. +### Mobile Find Training Scroll Fix โ€” Feb 9, 2026 (v2.2.14) +Fixed mobile scrolling: switched from fixed-viewport (`100vh; overflow: hidden`) to natural page scrolling on screens โ‰ค991px. Sticky filter bar. `4104c806` -### Issue Found & Fixed +### Map Tile Drift Fix & Event Cost Display โ€” Feb 9, 2026 (v2.2.13) +Fixed Google Maps tile/marker drift at zoom 1-2 by setting `minZoom: 3`. Fixed event cost HTML entities (`$50` โ†’ `$50`) via `html_entity_decode()`. `f123c7a5` -1. **Mobile Page Not Scrollable** (`assets/css/find-training-map.css`) - - **Symptom:** On mobile, the Find Training page rendered correctly but users could not scroll down past the map to browse trainer/venue/event cards - - **Root Cause:** The page used a fixed-viewport layout (`height: 100vh; overflow: hidden`) with nested scrolling. On mobile, the sidebar content area was only 158px tall (out of 940px of content) โ€” touch scrolling in such a tiny nested region was unreliable/impossible on real phones - - **Fix:** On screens โ‰ค991px, switched from fixed-viewport to natural page scrolling: - - Page container: `height: auto; overflow: visible` (was `100vh; hidden`) - - Map layout grid: `overflow: visible`, sidebar row `auto` (was `1fr`) - - Sidebar: `overflow: visible; max-height: none` (was `hidden; 50vh`) - - Filter bar: `position: sticky` so it stays visible while scrolling - - Desktop layout (>991px) unchanged +### Zoho CRM Sync Production Fix โ€” Feb 6, 2026 (v2.2.11) +Fixed silent sync failure: search criteria not sent to Zoho API (GET ignores `$data`), error reporting priority, phone validation, Last_Name fallback. Result: 64/64 trainers syncing. `4c22b9db` -2. **Version Bump for Cache Busting** (`includes/class-hvac-plugin.php`) - - Bumped `HVAC_VERSION` and `HVAC_PLUGIN_VERSION` from `2.2.13` to `2.2.14` +### Zoho CRM Sync Architecture Fix โ€” Feb 6, 2026 +Fixed "silent failure" architecture: added `validate_api_response()`, hash-only-on-success for all 5 sync methods, staging mode detection via hostname parsing, admin hash reset button. `03b9bce5` -### Files Modified +### Near Me Button Mobile Fix โ€” Feb 6, 2026 +Fixed `.hvac-btn-text` wrapper missing from Near Me button state changes (5 locations). Added empty results notification for Near Me filter. -| File | Change | -|------|--------| -| `assets/css/find-training-map.css` | Mobile layout: natural page scrolling, sticky filter bar, removed overflow constraints | -| `includes/class-hvac-plugin.php` | Version bump `2.2.13` โ†’ `2.2.14` | +### Champion Differentiation on Find Training โ€” Feb 2, 2026 +Added `is_champion` flag, distinct white-outline marker icon, non-clickable sidebar cards (state only), sorted to end of list. 18 champions differentiated from trainers. -### Verification +### Tabbed Interface for Find Training โ€” Feb 1, 2026 +Refactored sidebar from single trainer list to Trainers | Venues | Events tabs with ARIA accessibility, venue/event cards, info modal, context-aware search, visibility toggle dots. -- โœ… Production mobile (375x812): page scrollable, all 42 trainer cards accessible -- โœ… Production mobile: filter bar stays sticky at top while scrolling -- โœ… Production mobile: sidebar content 940px fully visible (was 158px) -- โœ… Production desktop (1400x900): side-by-side layout unchanged, no regression +### measureQuick Approved Training Labs โ€” Feb 1, 2026 +Created venue taxonomies (`venue_type`, `venue_equipment`, `venue_amenities`), configured 9 approved labs, filtered map data by taxonomy, enhanced venue modal with equipment/amenities badges and contact form. + +### Find Training Page Enhancements โ€” Feb 1, 2026 +Added viewport sync (sidebar shows only visible-in-map trainers), marker hover info windows, legacy URL redirects (`/find-a-trainer/` โ†’ `/find-training/`). + +### Find Training Page Implementation โ€” Jan 31โ€“Feb 1, 2026 +Built `/find-training` from scratch with Google Maps API replacing buggy MapGeo. 8 new files. Features: markers, clustering, filters, geolocation, modals, contact form, auto-geocoding. Multi-model code review fixed 6 issues (1 critical, 1 high). + +### E2E Testing & Bug Fixes โ€” Feb 1, 2026 +Deployed 12 security fixes, ran E2E tests, fixed empty trainers table (SQL rewrite) and blank event pages (template path mismatch). Added staging email filter. + +### Multi-Model Security Code Review โ€” Jan 31, 2026 +4-model review (GPT-5, Gemini 3, Kimi K2.5, Zen MCP) across 11 files. Found and fixed 12 issues: 2 critical (password transients, O(3600) DoS loop), 4 high, 4 medium, 2 low. + +### Master Trainer Profile Edit Enhancement โ€” Jan 9, 2026 +Fixed button styling, added all 6 profile field sections, added password reset button with AJAX handler. + +### TEC Community Events Dependency Analysis โ€” Jan 5, 2026 +Plugin still relies on TEC CE for event creation. Removal estimated 9-14 days. Deferred as technical debt. + +### Zoho Scheduled Sync, Batch Sync, Attendee Sync โ€” Dec 17-20, 2025 +WP-Cron scheduled sync with configurable intervals, batch pagination with progress bar, attendee/RSVP sync to Zoho Contacts + Campaign Members. 64/64 trainers, 50/50 attendees syncing. + +### Earlier Sessions (Nov-Dec 2025) +Nonce fix (v2.1.7), technical debt cleanup (v2.1.6), z-index fix (v2.1.5), Gemini environment setup, PHP 8+ compatibility, nav dropdown fix, MapGeo interceptor strategy. --- -## ๐Ÿ“‹ PREVIOUS SESSION - MAP TILE DRIFT FIX & EVENT COST DISPLAY (Feb 9, 2026) +## ENVIRONMENTS -### Status: โœ… **COMPLETE - Deployed to Production (v2.2.13)** +| Environment | URL | Version | +|-------------|-----|---------| +| **Production** | https://upskillhvac.com | 2.2.18 | +| **Staging** | https://upskill-staging.measurequick.com | 2.2.18 | -**Objective:** Fix Google Maps tile/marker drift at low zoom levels on the Find Training page, and fix event cost display showing HTML entities. - -### Issues Found & Fixed - -1. **Map Tile/Marker Drift at Low Zoom** (`assets/js/find-training-map.js`) - - **Symptom:** When zooming out to zoom 1-2, map tiles shifted ~190px right, placing markers over the ocean instead of over the US - - **Root Cause:** Google Maps WebGL renderer reads viewport width (1400px) instead of container width (1020px) in CSS Grid layouts. Tile drift = exactly `(1400 - 1020) / 2 = 190px` - - **Attempted fixes that did NOT work:** `google.maps.event.trigger(map, 'resize')`, CSS `contain: layout`, body `display: block` override, map destroy/recreate, `requestAnimationFrame` timing - - **Fix:** Added `minZoom: 3` to map options - drift is invisible at zoom 3+ but severe at zoom 1-2. Users searching for US HVAC training have no need for world-view zoom levels - - **Also added:** CSS `max-width: none !important` on Google Maps tile images to prevent theme CSS interference - -2. **Event Cost HTML Entities** (`includes/find-training/class-hvac-training-map-data.php`) - - **Symptom:** Event costs displayed as `$50` instead of `$50` in sidebar cards - - **Root Cause:** `tribe_get_formatted_cost()` returns HTML-encoded entities, which JS doesn't decode - - **Fix:** Added `html_entity_decode()` before passing cost to JavaScript - -3. **Version Bump for Cache Busting** (`includes/class-hvac-plugin.php`) - - Bumped `HVAC_VERSION` and `HVAC_PLUGIN_VERSION` from `2.2.11` to `2.2.13` - - Required because CDN/server-side caching served old JS even after deployment - - Script enqueue uses `HVAC_VERSION` as query string parameter for cache invalidation - -### Files Modified - -| File | Change | -|------|--------| -| `assets/js/find-training-map.js` | Added `minZoom: 3` to Google Maps options | -| `assets/css/find-training-map.css` | Added `max-width: none !important` for Google Maps tile images | -| `includes/find-training/class-hvac-training-map-data.php` | Added `html_entity_decode()` for event cost display | -| `includes/class-hvac-plugin.php` | Version bump `2.2.11` โ†’ `2.2.13` | - -### Verification - -- โœ… Staging: `setZoom(1)` correctly clamped to zoom 3 -- โœ… Production: `minZoom` option confirmed as 3, zoom clamping verified -- โœ… Production: Map loads at zoom 4 with all 42 trainers, 9 venues, 8 events correctly positioned -- โœ… Production: Zoom out button disables at zoom 3 +**Deploy:** `./scripts/deploy.sh staging` or `./scripts/deploy.sh production` --- -## ๐Ÿ“‹ PREVIOUS SESSION - ZOHO CRM SYNC PRODUCTION FIX (Feb 6, 2026) +## KNOWN ISSUES (Minor) -### 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 +1. Playwright headless login requires headed mode with correct selectors +2. Brief "jQuery is not defined" console error on page load (non-blocking) +3. Minor responsive layout issue on dashboard (cosmetic) --- -## ๐Ÿ“‹ 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(' Near Me'); - -// After (correct): -$button.html('Near Me'); -``` - -**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 `` 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.2.17 (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* +*For detailed session history, see git log and previous Status.md versions.*