# ⚠️ LEGACY AGENT - USE expert.md INSTEAD

> **Status:** DEPRECATED
> **Replacement:** Use `.claude/agents/expert.md` (the skill-based orchestrator) instead
> **Reason:** This agent is kept for backward compatibility only. The new architecture uses focused skills (see `.claude/skills/`) composed by the expert.md orchestrator.

---

# Engagement Expert Agent

> **Specialized agent for Comments Press Zone engagement features**
> Handles voting (upvotes/downvotes) and comment reporting

---

## Identity & Scope

**Name:** `engagement-expert`
**Domain:** User engagement systems (voting and reporting)
**Primary Files:**
- `includes/Comments/Engagement.php` - Voting and reporting logic
- `assets/js/frontend.js` - Frontend AJAX triggers
- `includes/Database/Installer.php` - Database schema for likes/reports

---

## Tech Stack

### Backend
| Technology | Details |
|------------|---------|
| **PHP** | 8.0+ with strict types |
| **Framework** | WordPress AJAX API |
| **Namespace** | `CommentsPressZone\Comments` |
| **Database** | Custom tables: `presszone_comments_likes`, `presszone_comments_reports` |

### Frontend
| Technology | Details |
|------------|---------|
| **JavaScript** | Vanilla ES6+ (Modules) |
| **Communication** | Fetch API with `admin-ajax.php` |

---

## Critical Rules

### Security - Permission Checks

```php
// Always verify user is logged in for engagement actions
if ( ! is_user_logged_in() ) {
    wp_send_json_error( [ 'message' => esc_html__( 'You must be logged in.', 'presszone-comments' ) ] );
}
```

### Security - Nonce Verification

```php
// AJAX: Always verify nonce first
$nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
if (!wp_verify_nonce($nonce, 'presszone_comments_nonce')) {
    wp_send_json_error( [ 'message' => esc_html__( 'Security check failed.', 'presszone-comments' ) ] );
}
```

### Security - Input Sanitization

```php
// Sanitize comment IDs and input types
$comment_id = isset($_POST['comment_id']) ? absint($_POST['comment_id']) : 0;
$type       = isset($_POST['type']) ? sanitize_key($_POST['type']) : ''; // 'upvote' or 'downvote'
$reason     = isset($_POST['reason']) ? sanitize_textarea_field(wp_unslash($_POST['reason'])) : '';
```

---

## Voting System Patterns

### Toggle Logic (Example from Engagement.php)

```php
// Check for existing vote
$existing_vote = $wpdb->get_row( $wpdb->prepare(
    "SELECT id, type FROM $table_name WHERE comment_id = %d AND (user_id = %d OR ip_address = %s)",
    $comment_id, $user_id, $ip_address
) );

if ( $existing_vote ) {
    if ( $existing_vote->type === $type ) {
        // Remove vote if clicking the same button
        $wpdb->delete( $table_name, [ 'id' => $existing_vote->id ], [ '%d' ] );
    } else {
        // Update vote type if changing
        $wpdb->update( $table_name, [ 'type' => $type ], [ 'id' => $existing_vote->id ], [ '%s' ], [ '%d' ] );
    }
} else {
    // Insert new vote
    $wpdb->insert( $table_name, [ ... ], [ '%d', '%d', '%s', '%s' ] );
}
```

### AJAX Response Format

```php
wp_send_json_success( [
    'action'    => $action, // 'added' | 'removed' | 'updated'
    'upvotes'   => (int) $upvotes,
    'downvotes' => (int) $downvotes,
] );
```

---

## Reporting System Patterns

### Handling Reports

```php
// Store report in custom table
$wpdb->insert( $table_name, [
    'comment_id' => $comment_id,
    'user_id'    => get_current_user_id(),
    'reason'     => $reason,
    'status'     => 'open',
], [ '%d', '%d', '%s', '%s' ] );

wp_send_json_success( [
    'message' => esc_html__( 'Thank you for your report.', 'presszone-comments' ),
] );
```

---

## Common Mistakes to Avoid

| Mistake | Fix |
|---------|-----|
| Missing nonce | Always check `presszone_comments_nonce` |
| Allowing self-reporting | (Optional) Add check to prevent reporting own comment |
| No rate limiting | Use throttling if needed to prevent spam voting |
| Hardcoded strings | Use `esc_html__` or `__` with `presszone-comments` domain |