upskill-event-manager/docs/DEVELOPMENT-GUIDE.md
bengizmo 40274d98ad feat: Implement comprehensive user role field and certification tracking system
• Add user role field to registration, profile display, and profile edit
  - 10 role options: technician, installer, supervisor, manager, trainer, consultant, sales rep, engineer, business owner, other
  - Required field with server-side validation
  - Radio buttons in registration, dropdown in profile edit
  - Displays in profile with proper capitalization

• Implement advanced certification tracking system
  - Date Certified: HTML5 date picker with validation (no future dates)
  - Certification Type: dropdown with "Certified measureQuick Trainer" and "Certified measureQuick Champion"
  - Certification Status: color-coded status badges (Active/Expired/Pending/Disabled)

• Add sophisticated role-based access control
  - Regular trainers: read-only access to certification fields
  - Administrators & master trainers: full edit access to certification fields
  - Visual indicators for read-only fields
  - Server-side permission validation

• Enhance plugin activation system
  - Initialize all 36 user meta fields for existing users
  - Smart default assignment based on user capabilities
  - Backward compatibility maintained

• Add professional UI styling
  - Blue-bordered certification section with trophy icon
  - Color-coded status badges with proper contrast
  - Read-only field styling with visual indicators
  - Enhanced form controls with focus states

• Comprehensive testing and documentation
  - E2E test coverage with visual verification
  - Updated API reference with new meta fields
  - Access control patterns documented
  - 100% test pass rate on staging environment

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 10:52:11 -03:00

13 KiB

HVAC Plugin Development Guide

Table of Contents

Development Setup

Prerequisites

  • PHP 7.4+ (8.0+ recommended)
  • Node.js 16+ and npm
  • Composer
  • WP-CLI
  • Git

Local Environment Setup

  1. Clone Repository
git clone <repository-url>
cd upskill-event-manager
  1. Install Dependencies
# PHP dependencies
composer install

# Node dependencies
npm install

# Create .env file
cp .env.example .env
# Edit .env with your environment details
  1. Configure WordPress
  • Install WordPress locally
  • Create database
  • Configure wp-config.php
  • Install The Events Calendar plugin
  1. Activate Plugin
wp plugin activate hvac-community-events

Coding Standards

PHP Standards

  1. Follow WordPress Coding Standards
// Good
function hvac_get_trainer_events( $trainer_id ) {
    $args = array(
        'post_type'      => 'tribe_events',
        'posts_per_page' => -1,
        'meta_query'     => array(
            array(
                'key'     => '_EventTrainerID',
                'value'   => $trainer_id,
                'compare' => '='
            )
        )
    );
    
    return get_posts( $args );
}

// Bad
function getTrainerEvents($trainerId) {
    $args = [
        'post_type' => 'tribe_events',
        'posts_per_page' => -1,
        'meta_query' => [
            ['key' => '_EventTrainerID', 'value' => $trainerId, 'compare' => '=']
        ]
    ];
    return get_posts($args);
}
  1. Namespace Usage
// Use prefixes instead of PHP namespaces for WordPress compatibility
class HVAC_Event_Manager {
    // Class implementation
}
  1. Security First
// Always escape output
echo esc_html( $trainer_name );
echo esc_url( $profile_url );
echo esc_attr( $css_class );

// Sanitize input
$trainer_id = absint( $_GET['trainer_id'] );
$search = sanitize_text_field( $_POST['search'] );

// Verify nonces
if ( ! wp_verify_nonce( $_POST['hvac_nonce'], 'hvac_action' ) ) {
    wp_die( 'Security check failed' );
}

JavaScript Standards

  1. jQuery Usage
// Always use jQuery in no-conflict mode
jQuery(document).ready(function($) {
    // $ is now safe to use
    $('.hvac-button').on('click', function(e) {
        e.preventDefault();
        // Handle click
    });
});
  1. AJAX Requests
jQuery.ajax({
    url: hvac_ajax.ajax_url,
    type: 'POST',
    data: {
        action: 'hvac_update_profile',
        nonce: hvac_ajax.nonce,
        data: formData
    },
    success: function(response) {
        if (response.success) {
            // Handle success
        } else {
            // Handle error
            console.error(response.data.message);
        }
    }
});

CSS Standards

  1. BEM Methodology
/* Block */
.hvac-trainer-card {}

/* Element */
.hvac-trainer-card__header {}
.hvac-trainer-card__content {}

/* Modifier */
.hvac-trainer-card--featured {}
  1. Specificity Rules
/* Avoid overly specific selectors */
/* Bad */
body.logged-in .hvac-wrapper div.container .hvac-trainer-card {}

/* Good */
.hvac-trainer-card {}

/* When specificity is needed for theme overrides */
.hvac-astra-integrated .hvac-trainer-card {}

Architecture Principles

1. Single Responsibility Principle

Each class should have one primary responsibility:

// Good - Focused classes
class HVAC_Certificate_Generator {}  // Only handles PDF generation
class HVAC_Event_Manager {}         // Only manages events
class HVAC_Email_Sender {}          // Only sends emails

// Bad - Kitchen sink class
class HVAC_Everything {}  // Does certificates, events, emails, etc.

2. Dependency Injection

class HVAC_Certificate_Service {
    private $generator;
    private $emailer;
    
    public function __construct( $generator, $emailer ) {
        $this->generator = $generator;
        $this->emailer = $emailer;
    }
}

3. Hook-Driven Architecture

// Use WordPress hooks for extensibility
do_action( 'hvac_before_event_save', $event_data );
$event_data = apply_filters( 'hvac_event_data', $event_data );
do_action( 'hvac_after_event_save', $event_id );

4. Singleton Pattern (where appropriate)

class HVAC_Plugin {
    private static $instance = null;
    
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        // Initialize
    }
}

Development Workflow

1. Feature Development

# Create feature branch
git checkout -b feature/new-trainer-dashboard

# Make changes
# Test thoroughly
# Commit with meaningful messages
git add .
git commit -m "feat: Add advanced filtering to trainer dashboard

- Add date range picker
- Add event status filter
- Add export functionality"

# Push and create PR
git push origin feature/new-trainer-dashboard

2. Git Commit Messages

Follow conventional commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • style: Formatting changes
  • refactor: Code restructuring
  • test: Test additions/changes
  • chore: Maintenance tasks

3. Code Review Checklist

  • Follows WordPress coding standards
  • Security measures implemented (escaping, sanitization)
  • Performance impact considered
  • Backward compatibility maintained
  • Documentation updated
  • Tests written/updated

Testing Guidelines

1. Unit Testing

class Test_HVAC_Event_Manager extends WP_UnitTestCase {
    public function test_create_event() {
        $event_data = array(
            'post_title' => 'Test Event',
            'EventStartDate' => '2025-08-15 09:00:00'
        );
        
        $event_id = HVAC_Event_Manager::create_event( $event_data );
        
        $this->assertIsInt( $event_id );
        $this->assertGreaterThan( 0, $event_id );
    }
}

2. E2E Testing with Playwright

test('Trainer can create event', async ({ page }) => {
    // Login
    await loginAsTrainer(page);
    
    // Navigate to event creation
    await page.goto('/trainer/event/manage/');
    
    // Fill form
    await page.fill('#event-title', 'HVAC Training Session');
    await page.selectOption('#event-venue', 'Main Campus');
    
    // Submit
    await page.click('button[type="submit"]');
    
    // Verify
    await expect(page).toHaveURL(/event-created/);
});

3. Manual Testing Checklist

  • Test on staging before production
  • Test with different user roles
  • Test on mobile devices
  • Test with different themes (especially Astra)
  • Test with caching enabled

Deployment Process

1. Pre-Deployment Checks

# Run validation
bin/pre-deployment-check.sh

# Run tests
npm test
phpunit

2. Staging Deployment

# Deploy to staging
scripts/deploy.sh staging

# Verify deployment
scripts/verify-plugin-fixes.sh

3. Production Deployment

# Only when explicitly requested
scripts/deploy.sh production
# Requires double confirmation

4. Post-Deployment

  • Monitor error logs
  • Check critical functionality
  • Be ready to rollback if needed

Security Best Practices

1. Data Validation

// Input validation
if ( ! is_email( $email ) ) {
    wp_die( 'Invalid email address' );
}

// Type checking
$event_id = absint( $_POST['event_id'] );
if ( ! $event_id ) {
    wp_die( 'Invalid event ID' );
}

2. SQL Queries

// Always use prepared statements
global $wpdb;
$results = $wpdb->get_results( 
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_type = %s",
        $user_id,
        'tribe_events'
    )
);

3. File Uploads

// Validate file types
$allowed_types = array( 'jpg', 'jpeg', 'png', 'pdf' );
$file_type = wp_check_filetype( $file['name'] );

if ( ! in_array( $file_type['ext'], $allowed_types ) ) {
    wp_die( 'Invalid file type' );
}

4. Capability Checks

// Always verify user permissions
if ( ! current_user_can( 'manage_own_events' ) ) {
    wp_die( 'Insufficient permissions' );
}

Performance Optimization

1. Database Queries

// Cache expensive queries
$cache_key = 'hvac_trainer_events_' . $trainer_id;
$events = wp_cache_get( $cache_key );

if ( false === $events ) {
    $events = get_posts( $args );
    wp_cache_set( $cache_key, $events, '', 3600 ); // 1 hour
}

2. Asset Loading

// Load assets only where needed
public function enqueue_scripts() {
    if ( ! $this->is_plugin_page() ) {
        return;
    }
    
    wp_enqueue_script( 'hvac-dashboard' );
}

3. AJAX Optimization

// Debounce search requests
let searchTimeout;
$('#search').on('keyup', function() {
    clearTimeout(searchTimeout);
    searchTimeout = setTimeout(function() {
        performSearch();
    }, 300);
});

4. Image Optimization

  • Use appropriate image sizes
  • Lazy load images
  • Compress before upload
  • Use WebP format when possible

Common Patterns

1. AJAX Handler Pattern

class HVAC_Ajax_Handler {
    public function __construct() {
        add_action( 'wp_ajax_hvac_action', array( $this, 'handle_request' ) );
    }
    
    public function handle_request() {
        // Verify nonce
        if ( ! wp_verify_nonce( $_POST['nonce'], 'hvac_nonce' ) ) {
            wp_send_json_error( 'Invalid nonce' );
        }
        
        // Check capabilities
        if ( ! current_user_can( 'required_capability' ) ) {
            wp_send_json_error( 'Insufficient permissions' );
        }
        
        // Process request
        $result = $this->process_data( $_POST['data'] );
        
        // Return response
        if ( $result ) {
            wp_send_json_success( $result );
        } else {
            wp_send_json_error( 'Processing failed' );
        }
    }
}

2. Settings Page Pattern

class HVAC_Settings {
    public function __construct() {
        add_action( 'admin_menu', array( $this, 'add_menu' ) );
        add_action( 'admin_init', array( $this, 'register_settings' ) );
    }
    
    public function add_menu() {
        add_options_page(
            'HVAC Settings',
            'HVAC Events',
            'manage_options',
            'hvac-settings',
            array( $this, 'render_page' )
        );
    }
    
    public function register_settings() {
        register_setting( 'hvac_settings', 'hvac_options' );
    }
}

Access Control Patterns

Role-Based Field Access

The plugin implements sophisticated role-based access control for sensitive data:

// Check permissions for certification field editing
$can_edit_certifications = current_user_can('administrator') || current_user_can('hvac_master_trainer');

if ( $can_edit_certifications ) {
    // Allow editing certification fields
    update_user_meta($user_id, 'certification_status', sanitize_text_field($_POST['certification_status']));
} else {
    // Show read-only display for regular trainers
    echo '<div class="hvac-read-only-field">' . esc_html($certification_status) . '</div>';
}

Field-Level Access Control Implementation

// Different access levels for different user types
if ( current_user_can('hvac_trainer') && ! current_user_can('hvac_master_trainer') ) {
    // Trainer: read-only access to certification fields
    echo '<input type="hidden" name="certification_type" value="' . esc_attr($certification_type) . '" />';
    echo '<div class="hvac-read-only-field">' . esc_html($certification_type) . '</div>';
} else if ( current_user_can('administrator') || current_user_can('hvac_master_trainer') ) {
    // Admin/Master Trainer: full edit access
    echo '<select name="certification_type">';
    // ... render editable dropdown
    echo '</select>';
}

Access Control Best Practices

  1. Always validate permissions server-side - Never rely on frontend-only restrictions
  2. Use capability checks - Check specific capabilities rather than user roles when possible
  3. Implement graceful degradation - Show read-only versions rather than hiding fields entirely
  4. Visual indicators - Clearly indicate when fields are read-only
  5. Consistent patterns - Use the same access control patterns throughout the plugin

Resources