# HVAC Trainer System API Reference This document provides detailed API reference for developers working with the HVAC Trainer system, including PHP classes, JavaScript APIs, AJAX endpoints, and database schemas. ## Table of Contents 1. [PHP Classes](#php-classes) 2. [AJAX Endpoints](#ajax-endpoints) 3. [JavaScript APIs](#javascript-apis) 4. [Database Schema](#database-schema) 5. [Hooks & Filters](#hooks--filters) 6. [Constants & Configuration](#constants--configuration) 7. [Error Codes](#error-codes) ## PHP Classes ### HVAC_Trainer_Profile_Manager **File**: `includes/class-hvac-trainer-profile-manager.php` **Purpose**: Core trainer profile management functionality #### Class Methods ##### `get_instance()` Returns singleton instance of the profile manager. ```php $manager = HVAC_Trainer_Profile_Manager::get_instance(); ``` **Returns**: `HVAC_Trainer_Profile_Manager` - Singleton instance ##### `create_profile($data)` Creates a new trainer profile. ```php $profile_data = [ 'trainer_first_name' => 'John', 'trainer_last_name' => 'Smith', 'trainer_city' => 'Chicago', 'trainer_state' => 'Illinois', 'user_id' => 123, 'certification_type' => 'Certified measureQuick Trainer' ]; $profile_id = $manager->create_profile($profile_data); ``` **Parameters**: - `$data` (array) - Profile data array **Returns**: `int|false` - Profile post ID on success, false on failure **Data Fields**: - `trainer_first_name` (string) - First name - `trainer_last_name` (string) - Last name - `trainer_display_name` (string) - Display name - `trainer_city` (string) - City - `trainer_state` (string) - State/Province - `trainer_country` (string) - Country - `profile_image_url` (string) - Profile image URL - `certification_type` (string) - Certification level - `user_id` (int) - WordPress user ID - `is_public_profile` (string) - Public visibility ('1' or '0') ##### `update_profile($profile_id, $data)` Updates an existing trainer profile. ```php $updated_data = [ 'trainer_city' => 'New York', 'trainer_state' => 'New York', 'certification_type' => 'Certified measureQuick Champion' ]; $success = $manager->update_profile(5840, $updated_data); ``` **Parameters**: - `$profile_id` (int) - Profile post ID - `$data` (array) - Updated profile data **Returns**: `bool` - Success status ##### `get_profile($profile_id)` Retrieves a trainer profile. ```php $profile = $manager->get_profile(5840); ``` **Parameters**: - `$profile_id` (int) - Profile post ID **Returns**: `array|false` - Profile data array or false if not found **Return Structure**: ```php [ 'profile_id' => 5840, 'user_id' => 31, 'name' => 'John Smith', 'city' => 'Chicago', 'state' => 'Illinois', 'certification_type' => 'Certified measureQuick Trainer', 'profile_image' => 'https://...', 'business_type' => 'Independent Contractor', 'event_count' => 5, 'training_formats' => 'In-Person, Virtual', 'training_locations' => 'On-site, Remote' ] ``` ##### `get_public_profiles($args = [])` Retrieves all public trainer profiles. ```php $profiles = $manager->get_public_profiles([ 'posts_per_page' => 20, 'meta_query' => [ [ 'key' => 'trainer_state', 'value' => 'Illinois', 'compare' => '=' ] ] ]); ``` **Parameters**: - `$args` (array) - WP_Query arguments **Returns**: `array` - Array of profile data ##### `delete_profile($profile_id)` Deletes a trainer profile. ```php $success = $manager->delete_profile(5840); ``` **Parameters**: - `$profile_id` (int) - Profile post ID **Returns**: `bool` - Success status ##### `migrate_certification_colors()` Migrates existing profiles to add certification color fields. ```php $manager->migrate_certification_colors(); ``` **Returns**: `void` ##### `get_certification_color($certification_type)` Gets the color code for a certification type. ```php $color = $manager->get_certification_color('Certified measureQuick Trainer'); // Returns: '#5077bb' ``` **Parameters**: - `$certification_type` (string) - Certification type **Returns**: `string` - Hex color code **Color Mapping**: - `'Certified measureQuick Champion'` → `'#f19a42'` - `'Certified measureQuick Trainer'` → `'#5077bb'` - Default → `'#f0f7e8'` ### HVAC_Find_Trainer_Page **File**: `includes/find-trainer/class-hvac-find-trainer-page.php` **Purpose**: Find A Trainer page functionality #### Class Methods ##### `get_instance()` Returns singleton instance. ```php $page = HVAC_Find_Trainer_Page::get_instance(); ``` ##### `render_page()` Renders the complete Find A Trainer page. ```php $page->render_page(); ``` **Returns**: `void` - Outputs HTML directly ##### `get_filter_options()` Gets available filter options for the directory. ```php $options = $page->get_filter_options(); ``` **Returns**: `array` - Filter options structure **Return Structure**: ```php [ 'states' => ['Illinois', 'New York', 'California'], 'business_types' => ['Contractor', 'Distributor', 'Consultant'], 'training_formats' => ['In-person', 'Virtual', 'Hybrid'], 'training_resources' => ['Classroom', 'Training Lab', 'Online'] ] ``` ##### `build_query_args($filters, $page = 1, $per_page = 12)` Builds WP_Query arguments from filter criteria. ```php $filters = [ 'state' => 'Illinois', 'business_type' => ['Contractor', 'Consultant'], 'search' => 'John' ]; $args = $page->build_query_args($filters, 1, 20); ``` **Parameters**: - `$filters` (array) - Filter criteria - `$page` (int) - Page number - `$per_page` (int) - Results per page **Returns**: `array` - WP_Query arguments ##### `render_trainer_cards($trainers)` Renders HTML for trainer cards. ```php $trainers = $page->get_filtered_trainers($filters); $page->render_trainer_cards($trainers); ``` **Parameters**: - `$trainers` (array) - Array of trainer data **Returns**: `void` - Outputs HTML directly ### HVAC_MapGeo_Integration **File**: `includes/find-trainer/class-hvac-mapgeo-integration.php` **Purpose**: MapGeo plugin integration for interactive maps #### Class Methods ##### `get_instance()` Returns singleton instance. ```php $integration = HVAC_MapGeo_Integration::get_instance(); ``` ##### `modify_map_layout($meta, $map_id = null)` Modifies MapGeo map layout to add trainer profile data. ```php add_filter('igm_add_meta', [$integration, 'modify_map_layout'], 10, 2); ``` **Parameters**: - `$meta` (array) - MapGeo metadata - `$map_id` (string) - Map ID **Returns**: `array` - Modified metadata ##### `ajax_get_trainer_profile()` AJAX handler for retrieving complete trainer profile data. ```php add_action('wp_ajax_hvac_get_trainer_profile', [$integration, 'ajax_get_trainer_profile']); add_action('wp_ajax_nopriv_hvac_get_trainer_profile', [$integration, 'ajax_get_trainer_profile']); ``` **Expected POST Data**: - `profile_id` (int) - Trainer profile ID - `nonce` (string) - Security nonce **Response Format**: ```json { "success": true, "data": { "profile_id": 5840, "user_id": "31", "name": "John Smith", "city": "Chicago", "state": "Illinois", "certification_type": "Certified measureQuick Trainer", "profile_image": "https://...", "business_type": "Independent Contractor", "event_count": 5, "training_formats": "In-Person, Virtual", "training_locations": "On-site, Remote", "upcoming_events": [] } } ``` ##### `ajax_get_trainer_certification()` AJAX handler for getting trainer certification information. ```php add_action('wp_ajax_hvac_get_trainer_certification', [$integration, 'ajax_get_trainer_certification']); ``` **Expected POST Data**: - `profile_id` (int) - Trainer profile ID - `nonce` (string) - Security nonce **Response Format**: ```json { "success": true, "data": { "certification_type": "Certified measureQuick Trainer", "certification_color": "#5077bb" } } ``` ## AJAX Endpoints ### Trainer Profile Management #### `hvac_save_trainer_profile` Saves trainer profile changes. **URL**: `wp-admin/admin-ajax.php` **Method**: POST **Auth**: Required (logged in user) **Parameters**: ```php [ 'action' => 'hvac_save_trainer_profile', 'profile_id' => 5840, 'nonce' => 'security_nonce', 'trainer_first_name' => 'John', 'trainer_last_name' => 'Smith', 'trainer_city' => 'Chicago', // ... other profile fields ] ``` **Response**: ```json { "success": true, "data": { "message": "Profile saved successfully", "profile_id": 5840 } } ``` #### `hvac_auto_save_profile` Auto-saves profile during editing. **Parameters**: Same as `hvac_save_trainer_profile` **Response**: Same format with auto-save confirmation ### Find A Trainer Directory #### `hvac_filter_trainers` Filters trainers by multiple criteria. **URL**: `wp-admin/admin-ajax.php` **Method**: POST **Auth**: Not required (public) **Parameters**: ```php [ 'action' => 'hvac_filter_trainers', 'nonce' => 'security_nonce', 'filters' => [ 'state' => ['Illinois', 'New York'], 'business_type' => ['Contractor'], 'training_format' => ['In-person', 'Virtual'] ], 'page' => 1, 'per_page' => 12 ] ``` **Response**: ```json { "success": true, "data": { "html": "
...
", "pagination": "
...
", "count": 25, "page": 1, "max_pages": 3 } } ``` #### `hvac_search_trainers` Searches trainers by text query. **Parameters**: ```php [ 'action' => 'hvac_search_trainers', 'nonce' => 'security_nonce', 'search' => 'John Smith', 'page' => 1, 'per_page' => 12 ] ``` **Response**: Same format as filter trainers #### `hvac_get_filter_options` Gets available filter options. **Parameters**: ```php [ 'action' => 'hvac_get_filter_options', 'nonce' => 'security_nonce' ] ``` **Response**: ```json { "success": true, "data": { "states": ["Illinois", "New York", "California"], "business_types": ["Contractor", "Distributor", "Consultant"], "training_formats": ["In-person", "Virtual", "Hybrid"], "training_resources": ["Classroom", "Training Lab", "Online"] } } ``` ### Contact Forms #### `hvac_submit_contact_form` Submits contact form to trainer. **Parameters**: ```php [ 'action' => 'hvac_submit_contact_form', 'nonce' => 'security_nonce', 'trainer_id' => 5840, 'contact_name' => 'Jane Doe', 'contact_email' => 'jane@example.com', 'contact_phone' => '555-1234', 'message' => 'I would like to inquire about training...' ] ``` **Response**: ```json { "success": true, "data": { "message": "Your message has been sent successfully" } } ``` ## JavaScript APIs ### HVAC_FindTrainer Object **File**: `assets/js/find-trainer.js` **Purpose**: Client-side Find A Trainer functionality #### Configuration ```javascript var HVAC_FindTrainer = { config: { ajax_url: hvac_find_trainer.ajax_url, nonce: hvac_find_trainer.nonce, filters: {}, current_page: 1, per_page: 12 } }; ``` #### Methods ##### `init(options)` Initializes the Find A Trainer system. ```javascript HVAC_FindTrainer.init({ ajax_url: '/wp-admin/admin-ajax.php', nonce: 'security_nonce', filters: { state: [], business_type: [], training_format: [] } }); ``` **Parameters**: - `options` (object) - Configuration options ##### `performSearch(query)` Performs text search for trainers. ```javascript HVAC_FindTrainer.performSearch('John Smith'); ``` **Parameters**: - `query` (string) - Search query ##### `applyFilters()` Applies current filter settings. ```javascript HVAC_FindTrainer.config.filters.state = ['Illinois']; HVAC_FindTrainer.applyFilters(); ``` ##### `updateResults(response)` Updates the display with new results. ```javascript HVAC_FindTrainer.updateResults({ success: true, data: { html: '
...
', pagination: '
...
', count: 25 } }); ``` **Parameters**: - `response` (object) - AJAX response object ##### `showTrainerProfile(profileId)` Shows trainer profile modal. ```javascript HVAC_FindTrainer.showTrainerProfile(5840); ``` **Parameters**: - `profileId` (int) - Trainer profile ID ### MapGeo Integration JavaScript **File**: Embedded in `class-hvac-mapgeo-integration.php` **Purpose**: MapGeo map interaction handling #### Global Functions ##### `window.hvac_show_trainer_modal(markerData)` Custom MapGeo action handler for trainer markers. ```javascript window.hvac_show_trainer_modal({ hvac_profile_id: 5840, id: 'trainer_5840', title: 'John Smith' }); ``` **Parameters**: - `markerData` (object) - Marker data from MapGeo #### Global Variables ##### `window.hvacTrainerDataCache` Cache object for trainer profile data. ```javascript // Cache structure window.hvacTrainerDataCache = { '5840': { profile_id: 5840, name: 'John Smith', certification_type: 'Certified measureQuick Trainer' // ... other profile data } }; ``` ##### `window.hvacPendingRequests` Tracking object for pending AJAX requests. ```javascript // Pending requests structure window.hvacPendingRequests = { '5840': true // Profile ID 5840 has pending request }; ``` ##### `window.lastMapGeoTrainerData` Stores the most recent trainer data logged by MapGeo. ```javascript window.lastMapGeoTrainerData = { id: 'trainer_5840', title: 'John Smith', latitude: 41.8781, longitude: -87.6298 }; ``` ## Database Schema ### Custom Post Type: trainer_profile #### wp_posts Table Fields ```sql -- Core post fields for trainer_profile CREATE TABLE wp_posts ( ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, post_title tinytext NOT NULL, -- Trainer display name post_content longtext NOT NULL, -- Profile description post_status varchar(20) NOT NULL, -- 'publish', 'draft', 'pending' post_type varchar(20) NOT NULL, -- 'trainer_profile' post_date datetime NOT NULL, post_modified datetime NOT NULL, PRIMARY KEY (ID), KEY type_status_date (post_type, post_status, post_date, ID) ); ``` #### wp_postmeta Table Fields ```sql -- Profile metadata structure INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES -- Personal Information (5840, 'trainer_first_name', 'John'), (5840, 'trainer_last_name', 'Smith'), (5840, 'trainer_display_name', 'John Smith'), (5840, 'trainer_city', 'Chicago'), (5840, 'trainer_state', 'Illinois'), (5840, 'trainer_country', 'USA'), (5840, 'profile_image_url', 'https://...'), (5840, 'linkedin_profile_url', 'https://linkedin.com/...'), -- Certification Information (5840, 'certification_type', 'Certified measureQuick Trainer'), (5840, 'certification_status', 'Active'), (5840, 'certification_color', '#5077bb'), (5840, 'date_certified', '2024-01-15'), (5840, 'personal_accreditation', 'Additional certifications'), -- System Fields (5840, 'user_id', '31'), (5840, 'is_public_profile', '1'), (5840, '_last_geocode_attempt', '1691234567'), (5840, 'geocoded_lat', '41.8781136'), (5840, 'geocoded_lng', '-87.6297982'), -- Business Information (5840, 'annual_revenue_target', '100000'), (5840, 'application_details', 'Registration details...'); ``` #### Taxonomy Tables ##### Business Type Taxonomy ```sql -- wp_terms entries for business_type taxonomy INSERT INTO wp_terms (term_id, name, slug) VALUES (1, 'Manufacturer', 'manufacturer'), (2, 'Distributor', 'distributor'), (3, 'Contractor', 'contractor'), (4, 'Consultant', 'consultant'), (5, 'Educator', 'educator'), (6, 'Government', 'government'), (7, 'Other', 'other'); -- wp_term_taxonomy entries INSERT INTO wp_term_taxonomy (term_taxonomy_id, term_id, taxonomy, parent, count) VALUES (1, 1, 'business_type', 0, 5), (2, 2, 'business_type', 0, 8), (3, 3, 'business_type', 0, 12); -- wp_term_relationships entries (linking posts to terms) INSERT INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES (5840, 3, 0); -- Profile 5840 is linked to Contractor business type ``` ### Database Indexes #### Recommended Indexes for Performance ```sql -- Optimize meta queries CREATE INDEX idx_postmeta_profile_queries ON wp_postmeta (meta_key, meta_value(50), post_id); -- Optimize trainer profile queries CREATE INDEX idx_posts_trainer_profile ON wp_posts (post_type, post_status, post_date); -- Optimize geocoded trainer queries CREATE INDEX idx_geocoded_trainers ON wp_postmeta (meta_key, post_id) WHERE meta_key IN ('geocoded_lat', 'geocoded_lng', 'is_public_profile'); ``` ### Common Database Queries #### Get All Public Trainers ```sql SELECT p.ID, p.post_title, lat.meta_value as latitude, lng.meta_value as longitude, cert.meta_value as certification_type FROM wp_posts p LEFT JOIN wp_postmeta pub ON p.ID = pub.post_id AND pub.meta_key = 'is_public_profile' LEFT JOIN wp_postmeta lat ON p.ID = lat.post_id AND lat.meta_key = 'geocoded_lat' LEFT JOIN wp_postmeta lng ON p.ID = lng.post_id AND lng.meta_key = 'geocoded_lng' LEFT JOIN wp_postmeta cert ON p.ID = cert.post_id AND cert.meta_key = 'certification_type' WHERE p.post_type = 'trainer_profile' AND p.post_status = 'publish' AND pub.meta_value = '1' AND lat.meta_value IS NOT NULL AND lng.meta_value IS NOT NULL; ``` #### Get Trainers by State ```sql SELECT p.ID, p.post_title, state.meta_value as state FROM wp_posts p INNER JOIN wp_postmeta state ON p.ID = state.post_id AND state.meta_key = 'trainer_state' INNER JOIN wp_postmeta pub ON p.ID = pub.post_id AND pub.meta_key = 'is_public_profile' WHERE p.post_type = 'trainer_profile' AND p.post_status = 'publish' AND pub.meta_value = '1' AND state.meta_value = 'Illinois' ORDER BY p.post_title; ``` ## Hooks & Filters ### Action Hooks #### `hvac_trainer_profile_created` Fired when a new trainer profile is created. ```php add_action('hvac_trainer_profile_created', function($profile_id, $profile_data) { // Custom logic after profile creation error_log("New trainer profile created: " . $profile_id); }, 10, 2); ``` **Parameters**: - `$profile_id` (int) - Created profile ID - `$profile_data` (array) - Profile data used for creation #### `hvac_trainer_profile_updated` Fired when a trainer profile is updated. ```php add_action('hvac_trainer_profile_updated', function($profile_id, $old_data, $new_data) { // Custom logic after profile update if ($old_data['trainer_city'] !== $new_data['trainer_city']) { // Location changed - trigger geocoding do_action('hvac_trigger_geocoding', $profile_id); } }, 10, 3); ``` **Parameters**: - `$profile_id` (int) - Updated profile ID - `$old_data` (array) - Previous profile data - `$new_data` (array) - New profile data #### `hvac_trainer_profile_geocoded` Fired when a trainer profile is successfully geocoded. ```php add_action('hvac_trainer_profile_geocoded', function($profile_id, $lat, $lng) { // Custom logic after geocoding error_log("Profile {$profile_id} geocoded to: {$lat}, {$lng}"); }, 10, 3); ``` **Parameters**: - `$profile_id` (int) - Profile ID - `$lat` (float) - Latitude - `$lng` (float) - Longitude ### Filter Hooks #### `hvac_trainer_profile_data` Filters profile data before saving. ```php add_filter('hvac_trainer_profile_data', function($data, $profile_id) { // Modify profile data before saving if (empty($data['trainer_display_name'])) { $data['trainer_display_name'] = $data['trainer_first_name'] . ' ' . $data['trainer_last_name']; } return $data; }, 10, 2); ``` **Parameters**: - `$data` (array) - Profile data - `$profile_id` (int) - Profile ID (0 for new profiles) **Returns**: `array` - Modified profile data #### `hvac_trainer_query_args` Filters WP_Query arguments for trainer queries. ```php add_filter('hvac_trainer_query_args', function($args, $context) { // Modify query arguments if ($context === 'find_trainer_page') { $args['posts_per_page'] = 20; // Show more results } return $args; }, 10, 2); ``` **Parameters**: - `$args` (array) - WP_Query arguments - `$context` (string) - Query context ('find_trainer_page', 'admin_list', etc.) **Returns**: `array` - Modified query arguments #### `hvac_trainer_card_data` Filters trainer card display data. ```php add_filter('hvac_trainer_card_data', function($card_data, $profile_id) { // Add custom fields to card display $card_data['custom_field'] = get_post_meta($profile_id, 'custom_field', true); return $card_data; }, 10, 2); ``` **Parameters**: - `$card_data` (array) - Card display data - `$profile_id` (int) - Profile ID **Returns**: `array` - Modified card data #### `hvac_mapgeo_marker_data` Filters MapGeo marker data for trainers. ```php add_filter('hvac_mapgeo_marker_data', function($marker_data, $profile_id) { // Customize marker appearance $cert_type = get_post_meta($profile_id, 'certification_type', true); if ($cert_type === 'Certified measureQuick Champion') { $marker_data['icon'] = 'champion_icon'; $marker_data['fill'] = '#f19a42'; } return $marker_data; }, 10, 2); ``` **Parameters**: - `$marker_data` (array) - Marker data - `$profile_id` (int) - Profile ID **Returns**: `array` - Modified marker data ## Constants & Configuration ### Plugin Constants ```php // Plugin version define('HVAC_PLUGIN_VERSION', '1.0.0'); // Plugin paths define('HVAC_PLUGIN_PATH', plugin_dir_path(__FILE__)); define('HVAC_PLUGIN_URL', plugin_dir_url(__FILE__)); // MapGeo configuration define('HVAC_MAPGEO_MAP_ID', '5872'); // Performance settings define('HVAC_TRAINER_CACHE_TIMEOUT', HOUR_IN_SECONDS); define('HVAC_TRAINER_GEOCODING_TIMEOUT', 30); // seconds // Debug mode define('HVAC_DEBUG', false); ``` ### Configuration Options #### WordPress Options ```php // Google Maps API key for geocoding update_option('hvac_google_maps_api_key', 'your_api_key_here'); // Default trainer profile settings update_option('hvac_trainer_default_settings', [ 'auto_geocode' => true, 'public_by_default' => false, 'require_approval' => true ]); // Find A Trainer page settings update_option('hvac_find_trainer_settings', [ 'results_per_page' => 12, 'enable_map' => true, 'enable_contact_forms' => true, 'cache_timeout' => 3600 ]); ``` ## Error Codes ### AJAX Error Codes | Code | Constant | Description | |------|----------|-------------| | 1001 | `HVAC_ERROR_INVALID_NONCE` | Nonce verification failed | | 1002 | `HVAC_ERROR_INSUFFICIENT_PERMISSIONS` | User lacks required permissions | | 1003 | `HVAC_ERROR_PROFILE_NOT_FOUND` | Trainer profile not found | | 1004 | `HVAC_ERROR_INVALID_DATA` | Invalid or missing data | | 1005 | `HVAC_ERROR_SAVE_FAILED` | Profile save operation failed | | 1006 | `HVAC_ERROR_GEOCODING_FAILED` | Geocoding service error | | 1007 | `HVAC_ERROR_EMAIL_FAILED` | Email delivery failed | ### Error Handling Example ```php // In AJAX handler public function ajax_save_trainer_profile() { // Verify nonce if (!wp_verify_nonce($_POST['nonce'], 'hvac_trainer_profile')) { wp_send_json_error([ 'code' => 1001, 'message' => 'Security verification failed' ]); return; } // Check permissions if (!current_user_can('edit_hvac_profile')) { wp_send_json_error([ 'code' => 1002, 'message' => 'Insufficient permissions' ]); return; } // Validate profile ID $profile_id = intval($_POST['profile_id']); if (!$profile_id || get_post_type($profile_id) !== 'trainer_profile') { wp_send_json_error([ 'code' => 1003, 'message' => 'Trainer profile not found' ]); return; } // Process save operation $result = $this->save_profile($profile_id, $_POST); if (is_wp_error($result)) { wp_send_json_error([ 'code' => 1005, 'message' => $result->get_error_message() ]); return; } wp_send_json_success([ 'message' => 'Profile saved successfully', 'profile_id' => $profile_id ]); } ``` ### JavaScript Error Handling ```javascript // Client-side error handling function handleAjaxError(response) { if (!response.success && response.data.code) { switch (response.data.code) { case 1001: // Nonce error - refresh page location.reload(); break; case 1002: // Permission error alert('You do not have permission to perform this action.'); break; case 1003: // Profile not found alert('Trainer profile not found.'); break; default: // Generic error alert('An error occurred: ' + response.data.message); } } } // Usage in AJAX calls jQuery.ajax({ url: hvac_trainer.ajax_url, method: 'POST', data: requestData, success: function(response) { if (response.success) { // Handle success } else { handleAjaxError(response); } }, error: function(jqXHR, textStatus, errorThrown) { console.error('AJAX Error:', textStatus, errorThrown); alert('Network error occurred. Please try again.'); } }); ``` This API reference provides comprehensive technical documentation for developers working with the HVAC Trainer system. For additional examples and use cases, refer to the main system documentation.