# WordPress Integration Management

**Last Updated:** January 10, 2026  
**Version:** 1.7.0  
**Status:** Production  
**Scope:** App-side management of WordPress plugin distribution and site integrations

---

## Table of Contents

1. [Overview](#1-overview)
2. [Architecture](#2-architecture)
3. [Plugin Distribution System](#3-plugin-distribution-system)
4. [Database Models](#4-database-models)
5. [API Endpoints](#5-api-endpoints)
6. [Django Admin Management](#6-django-admin-management)
7. [Frontend Integration](#7-frontend-integration)
8. [Site Integration Flow](#8-site-integration-flow)
9. [Recent Updates (v1.7.0)](#9-recent-updates-v170)
10. [Troubleshooting](#10-troubleshooting)

---

## 1. Overview

### What This Document Covers

This document covers the **app-side** management of WordPress integration:

- How the IGNY8 app distributes the WordPress plugin
- How site integrations are tracked in the database
- API endpoints that WordPress plugins call
- Admin interface for managing plugins and versions
- Frontend components for plugin download
- Plugin distribution infrastructure (v1.7.0)
- Automated versioning and packaging system

### What This Document Does NOT Cover

- Internal plugin PHP code and functions (see `/plugins/wordpress/source/igny8-wp-bridge/docs/`)
- WordPress-side setup and configuration
- Plugin installation on WordPress sites

### Current Status (v1.7.0)

- ✅ WordPress Plugin: v1.3.3 (Production)
- ✅ Distribution System: Fully operational
- ✅ Auto-update Mechanism: Active
- ✅ Template Design: Updated with image layout fixes
- ✅ API Endpoints: All operational
- ✅ Security Features: Checksums, signed URLs, rate limiting

---

## 2. Architecture

### System Components

```
┌─────────────────────────────────────────────────────────────────────────┐
│                           IGNY8 App Server                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  │
│  │  Django Backend  │    │    PostgreSQL    │    │   Plugin Files   │  │
│  │                  │    │                  │    │                  │  │
│  │  - API Views     │◄──►│  - Plugin        │    │  /plugins/       │  │
│  │  - Admin         │    │  - PluginVersion │    │  └─wordpress/    │  │
│  │  - Signals       │    │  - Installation  │    │    ├─source/     │  │
│  │                  │    │  - Downloads     │    │    └─dist/       │  │
│  └────────┬─────────┘    └──────────────────┘    └────────┬─────────┘  │
│           │                                                │            │
│           │  API Routes: api.igny8.com                    │            │
│           ▼                                                ▼            │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                         API Endpoints                             │  │
│  │                                                                   │  │
│  │  /api/plugins/{slug}/download/      → Serve ZIP file             │  │
│  │  /api/plugins/{slug}/check-update/  → Return update info         │  │
│  │  /api/plugins/{slug}/info/          → Return plugin metadata     │  │
│  │  /api/plugins/{slug}/register/      → Register installation      │  │
│  │  /api/plugins/{slug}/health-check/  → Report plugin status       │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    │ HTTPS
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        WordPress Sites                                   │
│                                                                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │
│  │   Site A    │  │   Site B    │  │   Site C    │  │   Site N    │    │
│  │  v1.1.1     │  │  v1.1.0     │  │  v1.1.1     │  │  v1.0.0     │    │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘
```

### URL Routing

| Domain | Service | Purpose |
|--------|---------|---------|
| `app.igny8.com` | Frontend (Vite) | User interface |
| `api.igny8.com` | Backend (Django) | API endpoints |

**Important**: WordPress plugins must call `api.igny8.com`, not `app.igny8.com`.

---

## 3. Plugin Distribution System

### Directory Structure

```
/data/app/igny8/
├── plugins/
│   └── wordpress/
│       ├── source/                          # Development source
│       │   └── igny8-wp-bridge/
│       │       ├── igny8-bridge.php         # Main plugin file
│       │       ├── includes/                # PHP classes
│       │       ├── admin/                   # Admin interface
│       │       │   ├── class-admin.php      # Menu registration
│       │       │   ├── layout-header.php    # Layout wrapper + sidebar
│       │       │   ├── layout-footer.php    # Footer
│       │       │   ├── settings.php         # Settings handler
│       │       │   └── pages/               # Admin pages (3 pages)
│       │       │       ├── connection.php   # Dashboard (connection + stats)
│       │       │       ├── settings.php     # Post types, taxonomies, sync
│       │       │       └── logs.php         # Webhook activity logs
│       │       ├── sync/                    # Sync functionality
│       │       ├── templates/               # Frontend templates
│       │       └── docs/                    # Plugin-internal docs
│       └── dist/                            # Distribution files
│           ├── igny8-wp-bridge-v1.x.x.zip   # Version ZIP
│           ├── igny8-wp-bridge-v1.x.x.sha256
│           └── igny8-wp-bridge-latest.zip   # Symlink to latest
│
└── backend/
    └── igny8_core/
        └── plugins/                         # Django app
            ├── models.py                    # Database models
            ├── views.py                     # API endpoints
            ├── signals.py                   # Auto-build triggers
            ├── utils.py                     # ZIP creation utilities
            ├── admin.py                     # Django admin config
            └── urls.py                      # URL routing
```

### Plugin Admin Pages

The WordPress plugin provides 3 admin pages:

| Page | File | Purpose |
|------|------|---------|
| Dashboard | `connection.php` | Connection status, Site ID, API key, content stats |
| Settings | `settings.php` | Post types, default post status, taxonomies, sync toggle |
| Logs | `logs.php` | Webhook activity with timestamps, event types, status |

**Layout:** 
- Dashboard: 2-column grid (Connection Status + Content Stats)
- Settings: 3-column top row (Post Types + Default Post Status + IGNY8 Sync) + dynamic taxonomy cards
- Logs: Full-width table with search

### How ZIP Files Are Created

#### Automatic Build (Recommended)

When a `PluginVersion` status changes to `released` or `update_ready`, the system **automatically**:

1. Reads source files from `/plugins/wordpress/source/igny8-wp-bridge/`
2. Updates version numbers in PHP files
3. Removes development files (tests, .git, __pycache__)
4. Creates ZIP in `/plugins/wordpress/dist/`
5. Calculates SHA256 checksum
6. Updates database with `file_path`, `file_size`, `checksum`
7. Updates `*-latest.zip` symlink

This is handled by `signals.py`:

```python
# backend/igny8_core/plugins/signals.py

@receiver(pre_save, sender=PluginVersion)
def auto_build_plugin_on_release(sender, instance, **kwargs):
    """Automatically build ZIP when version is released."""
    # Triggered on status change to 'released' or 'update_ready'
```

#### Manual Build (If Needed)

```bash
# From project root
cd /data/app/igny8/plugins/wordpress/source

# Create ZIP manually
zip -r ../dist/igny8-wp-bridge-v1.2.0.zip igny8-wp-bridge/ \
    -x "*.git*" -x "*__pycache__*" -x "*.DS_Store" -x "*tester*"

# Update checksum
sha256sum ../dist/igny8-wp-bridge-v1.2.0.zip > ../dist/igny8-wp-bridge-v1.2.0.sha256

# Update symlink
ln -sf igny8-wp-bridge-v1.2.0.zip ../dist/igny8-wp-bridge-latest.zip
```

---

## 4. Database Models

### Plugin

Represents a plugin type (WordPress, Shopify, etc.).

```python
class Plugin(models.Model):
    name = models.CharField(max_length=100)      # "IGNY8 WordPress Bridge"
    slug = models.SlugField(unique=True)          # "igny8-wp-bridge"
    platform = models.CharField(...)              # "wordpress", "shopify", "custom"
    description = models.TextField()
    homepage_url = models.URLField()
    is_active = models.BooleanField(default=True)
```

**Current Records:**

| ID | Name | Slug | Platform |
|----|------|------|----------|
| 1 | IGNY8 WordPress Bridge | igny8-wp-bridge | wordpress |

### PluginVersion

Tracks each version of a plugin.

```python
class PluginVersion(models.Model):
    plugin = models.ForeignKey(Plugin, ...)
    version = models.CharField(max_length=20)     # "1.1.1"
    version_code = models.IntegerField()          # 10101 (for comparison)
    status = models.CharField(...)                # "draft", "released", "update_ready"
    
    # File info (auto-populated on release)
    file_path = models.CharField(...)             # "igny8-wp-bridge-v1.1.1.zip"
    file_size = models.IntegerField()             # 167589 (bytes)
    checksum = models.CharField(max_length=64)    # SHA256
    
    # Release info
    changelog = models.TextField()
    min_php_version = models.CharField(default='7.4')
    released_at = models.DateTimeField(null=True)
    force_update = models.BooleanField(default=False)
```

**Version Status Flow:**

```
draft → testing → staged → released → update_ready → deprecated
                              │              │
                              │              └─ Notifies WP sites
                              └─ Available for download
```

### PluginInstallation

Tracks where plugins are installed.

```python
class PluginInstallation(models.Model):
    site = models.ForeignKey('Site', ...)
    plugin = models.ForeignKey(Plugin, ...)
    current_version = models.ForeignKey(PluginVersion, ...)
    is_active = models.BooleanField(default=True)
    last_health_check = models.DateTimeField(null=True)
    health_status = models.CharField(...)  # "healthy", "outdated", "error"
```

### PluginDownload

Tracks download analytics.

```python
class PluginDownload(models.Model):
    plugin = models.ForeignKey(Plugin, ...)
    version = models.ForeignKey(PluginVersion, ...)
    ip_address = models.GenericIPAddressField()
    user_agent = models.CharField(max_length=500)
    download_type = models.CharField(...)  # "manual", "auto_update"
    created_at = models.DateTimeField(auto_now_add=True)
```

---

## 5. API Endpoints

### Public Endpoints (No Auth Required)

#### Download Plugin

```
GET /api/plugins/{slug}/download/
```

Returns the latest released ZIP file.

**Response:** Binary ZIP file download

**Example:**
```bash
curl -O https://api.igny8.com/api/plugins/igny8-wp-bridge/download/
```

#### Check for Updates

```
GET /api/plugins/{slug}/check-update/?current_version=1.0.0
```

Called by installed WordPress plugins to check for updates.

**Response:**
```json
{
    "update_available": true,
    "current_version": "1.0.0",
    "latest_version": "1.1.1",
    "latest_version_code": 10101,
    "download_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/download/",
    "changelog": "Bug fixes and improvements",
    "info_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/info/",
    "force_update": false,
    "checksum": "6b9e231c07434df1dcfe81596b57f3571c30b6c2..."
}
```

#### Plugin Info

```
GET /api/plugins/{slug}/info/
```

Returns plugin metadata for WordPress update modal.

**Response:**
```json
{
    "name": "IGNY8 WordPress Bridge",
    "slug": "igny8-wp-bridge",
    "version": "1.1.1",
    "author": "IGNY8",
    "homepage": "https://igny8.com",
    "description": "Lightweight bridge plugin...",
    "changelog": "Bug fixes and improvements",
    "download_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/download/",
    "file_size": 167589,
    "requires_php": "7.4",
    "tested_wp": "6.7"
}
```

### Authenticated Endpoints

#### Register Installation

```
POST /api/plugins/{slug}/register/
Headers: Authorization: Api-Key {site_api_key}
```

Called when plugin is activated on a WordPress site.

**Request Body:**
```json
{
    "site_id": 123,
    "version": "1.1.1",
    "wp_version": "6.7",
    "php_version": "8.2"
}
```

#### Health Check

```
POST /api/plugins/{slug}/health-check/
Headers: Authorization: Api-Key {site_api_key}
```

Periodic status report from installed plugins.

**Request Body:**
```json
{
    "site_id": 123,
    "version": "1.1.1",
    "status": "active",
    "last_sync": "2026-01-09T12:00:00Z"
}
```

---

## 6. Django Admin Management

### Accessing Plugin Admin

1. Go to: `https://api.igny8.com/backend/`
2. Login with admin credentials
3. Navigate to **Plugin Distribution** section

### Admin Sections

#### Plugins

View and manage plugin registry.

| Field | Description |
|-------|-------------|
| Name | Display name |
| Slug | URL identifier (cannot change after creation) |
| Platform | wordpress, shopify, custom |
| Is Active | Whether available for download |

#### Plugin Versions

Manage versions and trigger releases.

**Required Fields Only:**
- Plugin
- Version (e.g., 1.2.0)
- Changelog
- Status

**Auto-Filled Fields:**
- Min API/Platform/PHP versions (copied from previous version)
- File path, size, checksum (generated on release)
- Version code (calculated from version number)

**To Release a New Version:**

1. Click **Add Plugin Version**
2. Select plugin
3. Enter version number (e.g., 1.2.0)
4. Write changelog
5. Set status to `draft`
6. Save
7. Change status to `released` (or use bulk action "✅ Release selected versions")
8. ZIP is automatically built with all file info populated

**Bulk Actions:**
- **✅ Release selected versions** - Builds ZIP and releases
- **📢 Mark as update ready** - Notifies WordPress sites  
- **🗑️ Mark as deprecated** - Deprecates old versions

#### Plugin Installations

View where plugins are installed.

| Field | Description |
|-------|-------------|
| Site | IGNY8 site record |
| Plugin | Which plugin |
| Current Version | Installed version |
| Health Status | healthy, outdated, error |
| Last Health Check | Timestamp |

#### Plugin Downloads

View download analytics.

| Field | Description |
|-------|-------------|
| Plugin | Which plugin |
| Version | Which version |
| Download Type | manual, auto_update |
| IP Address | Client IP |
| User Agent | Browser/client info |
| Created At | Timestamp |

---

## 7. Frontend Integration

### Download Button Location

**Page:** Site Settings → Integrations → WordPress

**Component:** `frontend/src/components/sites/WordPressIntegrationForm.tsx`

### How Download Works

```typescript
// WordPressIntegrationForm.tsx

import { API_BASE_URL } from '../../services/api';

const handleDownloadPlugin = () => {
    // Uses API_BASE_URL which resolves to https://api.igny8.com/api
    const pluginUrl = `${API_BASE_URL}/plugins/igny8-wp-bridge/download/`;
    window.open(pluginUrl, '_blank');
    toast.success('Plugin download started');
};
```

### Plugin Information Display

The frontend shows:

- Plugin name and version
- File size
- PHP requirements
- Download button
- Changelog (expandable)

---

## 8. Site Integration Flow

### Integration Creation Flow

```
┌─────────────────────────────────────────────────────────────────────────┐
│                        WordPress Site Setup                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. User downloads plugin from IGNY8 app                                │
│     └─ GET /api/plugins/igny8-wp-bridge/download/                       │
│                                                                          │
│  2. User installs and activates plugin in WordPress                     │
│                                                                          │
│  3. User enters Site ID and API Key in WP plugin settings               │
│     └─ These are generated in IGNY8 app                                 │
│                                                                          │
│  4. WP Plugin calls IGNY8 to register                                   │
│     └─ POST /api/plugins/igny8-wp-bridge/register/                      │
│                                                                          │
│  5. IGNY8 creates SiteIntegration record                                │
│     └─ Links WordPress site to IGNY8 site                               │
│                                                                          │
│  6. Integration is now active                                           │
│     └─ Content can be published from IGNY8 to WordPress                 │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘
```

### Integration Data Model

**Authentication (Source of Truth):**

```python
# Site model (in auth/models.py) - SINGLE source of truth for API auth

class Site(models.Model):
    wp_api_key = models.CharField(max_length=255)  # API key for WP authentication
    # Used by: PublisherService, test connection, plugin verification
```

**Sync Tracking (SiteIntegration):**

```python
# SiteIntegration model (in auth/models.py) - Tracks sync status, NOT auth

class SiteIntegration(models.Model):
    site = models.ForeignKey(Site, ...)           # IGNY8 site
    platform = models.CharField(...)               # "wordpress", "shopify"
    external_site_url = models.URLField()          # WordPress URL
    sync_enabled = models.BooleanField()
    sync_status = models.CharField(...)            # "pending", "syncing", "completed"
    last_sync_at = models.DateTimeField()
    sync_error = models.TextField(null=True)
    connection_status = models.CharField(...)      # "connected", "error"
```

**Key Architecture Points:**
- `Site.wp_api_key` is the **SINGLE source of truth** for API authentication
- `SiteIntegration` provides sync tracking but NOT authentication
- Publishing uses `Site.wp_api_key` via `X-IGNY8-API-KEY` header
- SiteIntegration kept for future multi-platform support (Shopify, custom)

---

## 9. Troubleshooting

### Common Issues

#### "404 Not Found" on Download

**Cause:** Using wrong domain (app.igny8.com instead of api.igny8.com)

**Solution:** Ensure URL is `https://api.igny8.com/api/plugins/igny8-wp-bridge/download/`

#### "Plugin file not found" Error

**Cause:** ZIP file doesn't exist in dist/ directory

**Solution:**
```bash
# Check if file exists
ls -la /data/app/igny8/plugins/wordpress/dist/

# If missing, rebuild manually or change version status to trigger auto-build
```

#### Updates Not Showing in WordPress

**Cause 1:** WordPress caches plugin update checks

**Solution:** In WordPress admin, go to Dashboard → Updates → Check Again

**Cause 2:** Version status is not `released` or `update_ready`

**Solution:** Check PluginVersion status in Django admin

#### Wrong File Size/Checksum

**Cause:** Database values don't match actual file

**Solution:**
```bash
# Get actual values
stat -c %s /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip
sha256sum /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip

# Update in Django admin or shell
```

### Verification Commands

```bash
# Test download endpoint
curl -I https://api.igny8.com/api/plugins/igny8-wp-bridge/download/

# Test check-update endpoint
curl "https://api.igny8.com/api/plugins/igny8-wp-bridge/check-update/?current_version=1.0.0"

# Test info endpoint
curl https://api.igny8.com/api/plugins/igny8-wp-bridge/info/

# Check ZIP contents
unzip -l /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip

# Verify API URL in plugin
unzip -p /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip \
    igny8-wp-bridge/igny8-bridge.php | grep "api.igny8.com"
```

### Log Locations

| Log | Location |
|-----|----------|
| Django Logs | `/data/app/igny8/backend/logs/` |
| Plugin API Logs | Check Django logs for `/api/plugins/` requests |
| WordPress Plugin Logs | WP site's debug.log if WP_DEBUG enabled |

---

## 9. Recent Updates (v1.7.0)

### Plugin Distribution System Implemented

**Infrastructure:**
- ✅ Complete plugin distribution system operational
- ✅ Multi-platform support (WordPress, Shopify, Custom sites)
- ✅ Automated ZIP packaging with versioning
- ✅ Security features: checksums (MD5/SHA256), signed URLs, rate limiting
- ✅ Monitoring and analytics dashboard

**Database Models:**
- `Plugin` - Platform-agnostic plugin registry
- `PluginVersion` - Full version lifecycle management
- `PluginInstallation` - Per-site installation tracking
- `PluginDownload` - Download analytics and monitoring

**API Endpoints:**
- All 5 endpoints operational and tested
- `/download/` - Serve plugin ZIP files
- `/check-update/` - WordPress update mechanism
- `/info/` - Plugin metadata
- `/register/` - Installation registration
- `/health-check/` - Plugin health monitoring

### WordPress Plugin Updates (v1.3.0 → v1.5.1)

**v1.5.1 - Admin UI Consolidation:**
- Reduced admin pages from 6 to 3: Dashboard, Settings, Logs
- Renamed Connection page to Dashboard with content stats
- Removed redundant pages: Data, Sync, old Dashboard
- Settings redesigned with 3-column layout (Post Types + Default Post Status + IGNY8 Sync)
- Fixed header alignment across all pages with proper width styling
- Cleaned up orphaned code and functions

**v1.5.0 - Authentication Simplification:**
- Simplified authentication to use Site.wp_api_key as single source of truth
- Removed redundant access_token handling
- Improved test connection flow using authenticated /verify-key endpoint

**v1.3.3 - Template Design Improvements:**
- Fixed square images displaying in 2 rows (now side-by-side)
- Fixed landscape images in sections 4+ displaying incorrectly
- Removed card wrapper for images without descriptions
- Applied border-radius and shadow directly to images
- Landscape images now appear after first paragraph
- Consistent CSS classes for all image types

**v1.3.2 - Template Fixes:**
- Template rendering improvements in app and plugin
- Image layout enhancements
- Content section fixes

**v1.3.1 - Plugin Updates:**
- Versioning system improvements
- WordPress plugin compatibility updates

**v1.3.0 - Initial Distribution System:**
- First release with automated distribution
- Update mechanism implementation
- Base template system

### Version Progression Timeline

```
v1.7.0 (Jan 10, 2026) - App infrastructure + plugin v1.5.1
   ├── Plugin admin UI consolidation (6→3 pages)
   ├── Authentication simplification
   ├── Plugin distribution system complete
   ├── Template design overhaul
   └── Pre-launch cleanup complete

v1.6.2 (Jan 8, 2026) - Design refinements
   └── Marketing site updates

v1.6.0 (Jan 8, 2026) - Payment system refactor
   └── Stripe, PayPal, Bank Transfer

v1.4.0 (Jan 5, 2026) - AI model architecture overhaul
   └── IntegrationProvider, AIModelConfig
```

### Infrastructure Improvements

**Security:**
- Signed URLs with expiration for downloads
- Checksum verification (MD5 + SHA256)
- Rate limiting per IP/site
- API authentication for sensitive operations
- Production environment protection

**Automation:**
- Auto-build on version status change
- Automatic checksum calculation
- File size tracking
- Version number updates in ZIP contents
- Released timestamp tracking

**Monitoring:**
- Installation tracking per site
- Download analytics
- Health check endpoints
- Version distribution monitoring
- Error logging and alerts

### Documentation Updates

- Added comprehensive plugin distribution plan
- Updated API endpoint documentation
- Enhanced troubleshooting guides
- Added version progression tracking
- Updated architecture diagrams

---

## 10. Troubleshooting
|-----|----------|
| Django logs | `/data/app/logs/django.log` |
| Plugin build logs | Check Django log for `"Created plugin ZIP"` messages |
| Download tracking | `PluginDownload` model in database |

---

## Related Documentation

- [PLUGIN-UPDATE-WORKFLOW.md](PLUGIN-UPDATE-WORKFLOW.md) - Post-update checklist
- `/plugins/wordpress/source/igny8-wp-bridge/docs/` - Plugin internal documentation
- [docs/plans/PLUGIN-DISTRIBUTION-SYSTEM.md](/docs/plans/PLUGIN-DISTRIBUTION-SYSTEM.md) - Original implementation plan
