# WordPress Integration Management **Last Updated:** January 9, 2026 **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. [Troubleshooting](#9-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 ### 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 --- ## 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 │ │ ├── sync/ # Sync functionality │ │ ├── templates/ # Frontend templates │ │ └── docs/ # Plugin-internal docs │ └── dist/ # Distribution files │ ├── igny8-wp-bridge-v1.1.1.zip # Version ZIP │ ├── igny8-wp-bridge-v1.1.1.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 ``` ### 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. | Field | Description | |-------|-------------| | Plugin | Parent plugin | | Version | Semantic version (e.g., 1.1.1) | | Status | draft, testing, staged, released, update_ready, deprecated | | File Path | Auto-set on release | | File Size | Auto-calculated on release | | Checksum | Auto-calculated on release | | Changelog | What's new (shown to users) | | Force Update | Set true for critical security fixes | **To Release a New Version:** 1. Create new PluginVersion record with status `draft` 2. Enter version number, changelog 3. Change status to `released` or `update_ready` 4. Save → ZIP is automatically built #### 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 ```python # SiteIntegration model (in auth/models.py) class SiteIntegration(models.Model): site = models.ForeignKey(Site, ...) # IGNY8 site platform = models.CharField(...) # "wordpress" external_site_url = models.URLField() # WordPress URL api_key = models.CharField(...) # Encrypted key sync_enabled = models.BooleanField() last_sync = models.DateTimeField() connection_status = models.CharField(...) # "connected", "error" ``` --- ## 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/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