# WordPress Integration & Publishing Flow - Complete Technical Documentation

**Last Updated:** January 10, 2026  
**Version:** 1.7.0  
**Status:** Production Active

---

## Table of Contents

1. [System Overview](#1-system-overview)
2. [Integration Setup Flow](#2-integration-setup-flow)
3. [Manual Publishing Flow](#3-manual-publishing-flow)
4. [Automation Publishing Flow](#4-automation-publishing-flow)
5. [Webhook Sync Flow (WordPress → IGNY8)](#5-webhook-sync-flow-wordpress--igny8)
6. [Metadata Sync Flow](#6-metadata-sync-flow)
7. [Data Models & Storage](#7-data-models--storage)
8. [Plugin Distribution System](#8-plugin-distribution-system)
9. [Current Implementation](#9-current-implementation)
10. [Flow Diagrams](#10-flow-diagrams)

---

## 1. System Overview

### Architecture Summary

IGNY8 integrates with WordPress sites through a **custom WordPress plugin** (`igny8-wp-bridge`) that:
- Receives content from IGNY8 via a custom REST endpoint (`/wp-json/igny8/v1/publish`)
- Sends status updates back to IGNY8 via webhooks
- **Authenticates using API key ONLY** (stored in Site.wp_api_key - single source of truth)
- Auto-updates via IGNY8 plugin distribution system (v1.7.0+)
- Supports advanced template rendering with image layouts
- **No WordPress admin credentials required** (username/password authentication deprecated)

### Communication Pattern

```
IGNY8 App ←→ WordPress Site
   │              │
   │  HTTP POST   │
   ├─────────────→│  Publish content via /wp-json/igny8/v1/publish
   │              │
   │  HTTP POST   │
   │←─────────────┤  Webhook status updates via /api/v1/integration/webhooks/wordpress/status/
   │              │
   │  HTTP GET    │
   ├─────────────→│  Check plugin updates via /wp-json/igny8/v1/check-update
   │              │
```

### Key Components

| Component | Location | Purpose |
|-----------|----------|---------|
| SiteIntegration Model | `business/integration/models.py` | Stores WordPress credentials & config |
| SyncEvent Model | `business/integration/models.py` | Logs all sync operations |
| Plugin Models | `plugins/models.py` | Plugin versioning and distribution |
| Celery Task | `tasks/wordpress_publishing.py` | Background publishing worker |
| Webhook Handler | `modules/integration/webhooks.py` | Receives WordPress status updates |
| Frontend Form | `components/sites/WordPressIntegrationForm.tsx` | User setup UI |

### Recent Updates (v1.7.0)

**Plugin Distribution System:**
- ✅ Automated plugin distribution and updates
- ✅ WordPress plugin v1.3.3 with template improvements
- ✅ Image layout fixes (square/landscape positioning)
- ✅ Auto-update mechanism via WordPress hooks
- ✅ Health check and monitoring endpoints

---

## 2. Integration Setup Flow

### 2.1 Pre-requisites (WordPress Side)

1. WordPress 5.6+ with REST API enabled
2. Pretty permalinks enabled (Settings → Permalinks)
3. IGNY8 WordPress Bridge plugin v1.3.0+ installed and activated
4. No security plugins blocking REST API

### 2.2 Plugin Installation (Updated v1.7.0)

**Option 1: Manual Download & Install**
- User downloads latest plugin from IGNY8 app
- Frontend: Site Settings → WordPress Integration → Download Plugin
- Download endpoint: `https://api.igny8.com/api/plugins/igny8-wp-bridge/download/`
- Installs in WordPress: Plugins → Add New → Upload ZIP

**Option 2: Direct URL Install**
- WordPress admin → Plugins → Add New → Upload Plugin
- Paste ZIP URL with signed download token
- Plugin installs and auto-registers with IGNY8

**Plugin Auto-Update:**
- WordPress checks for updates every 12 hours
- Plugin hooks into `pre_set_site_transient_update_plugins`
- Compares current version with latest from IGNY8 API
- Notifies admin if update available
- Can be updated via WordPress admin (one-click)

### 2.3 Setup Steps (User Flow)

**Step 1: User navigates to Site Settings**
- Frontend: `/sites/{id}/settings` → WordPress Integration section
- Component: `WordPressIntegrationForm.tsx`

**Step 2: User clicks "Generate API Key"**
- Frontend calls: `POST /v1/integration/integrations/generate-api-key/`
- Body: `{ "site_id": 123 }`
- Backend stores API key in `Site.wp_api_key` field (SINGLE source of truth)
- Creates/updates `SiteIntegration` record with empty credentials_json

**Step 3: User configures WordPress plugin**
- Configures plugin with:
  - IGNY8 API URL: `https://api.igny8.com`
  - Site API Key: (copied from IGNY8)
  - Site ID: (shown in IGNY8)
- **Note:** No WordPress admin credentials needed

**Step 4: Test Connection**
- Plugin calls: `POST https://api.igny8.com/api/v1/integration/integrations/test-connection/`
- Headers: `Authorization: Bearer {api_key}`
- Body: `{ "site_id": 123, "api_key": "...", "site_url": "https://..." }`
- Backend validates API key against `Site.wp_api_key`
- Success: SiteIntegration created with empty credentials_json, plugin registers installation
- Failure: Error message displayed

### 2.4 Data Created During Setup

**SiteIntegration Record:**
```json
{
  "id": 1,
  "site_id": 123,
  "account_id": 456,
  "platform": "wordpress",
  "platform_type": "cms",
  "config_json": {
    "site_url": "https://example.com"
  },
  "credentials_json": {
    "plugin_version": "1.3.4",
    "debug_enabled": false
  },
  "is_active": true,
  "sync_enabled": true,
  "sync_status": "pending",
  "_note": "API key stored in Site.wp_api_key, not in credentials_json"
}
```

**Site Model (API Key Storage):**
```json
{
  "id": 123,
  "name": "Example Site",
  "url": "https://example.com",
  "wp_api_key": "igny8_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "hosting_type": "wordpress"
}
```

---

## 2.5 Authentication Architecture (v1.3.4+)

### API Key as Single Source of Truth

**Storage:**
- API key stored in `Site.wp_api_key` field (Django backend)
- Plugin stores same API key in WordPress options table: `igny8_api_key`
- SiteIntegration.credentials_json does NOT contain API key

**Authentication Flow (IGNY8 → WordPress):**
```python
# Backend: publisher_service.py
destination_config = {
    'site_url': integration.config_json.get('site_url'),
    'api_key': integration.site.wp_api_key  # From Site model
}

# WordPress Adapter: wordpress_adapter.py
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}
requests.post(f"{site_url}/wp-json/igny8/v1/publish", headers=headers, json=payload)
```

**Authentication Flow (WordPress → IGNY8):**
```php
// Plugin: class-igny8-api.php
$api_key = get_option('igny8_api_key');
$headers = array(
    'Authorization' => 'Bearer ' . $api_key,
    'Content-Type' => 'application/json'
);
wp_remote_post('https://api.igny8.com/api/v1/...', array('headers' => $headers));
```

**Validation (WordPress Side):**
```php
// Plugin: class-igny8-rest-api.php
public function check_permission($request) {
    // Check X-IGNY8-API-KEY header
    $header_api_key = $request->get_header('x-igny8-api-key');
    
    // Check Authorization Bearer header
    $auth_header = $request->get_header('Authorization');
    
    $stored_api_key = get_option('igny8_api_key');
    
    if (hash_equals($stored_api_key, $header_api_key) || 
        strpos($auth_header, 'Bearer ' . $stored_api_key) !== false) {
        return true;
    }
    
    return new WP_Error('rest_forbidden', 'Invalid API key', array('status' => 401));
}
```

### Deprecated Authentication Methods

**No Longer Supported (removed in v1.3.4):**
- ❌ Username/password authentication
- ❌ App passwords via WordPress REST API
- ❌ OAuth/token exchange
- ❌ Webhook signature validation (webhooks deprecated)
- ❌ Storing API key in SiteIntegration.credentials_json

**Legacy Fields (do not use):**
- `Site.wp_username` - deprecated
- `Site.wp_app_password` - deprecated  
- `Site.wp_url` - deprecated (use SiteIntegration.config_json.site_url)

---

## 3. Manual Publishing Flow

### 3.1 Trigger Points

1. **Content Review Page** - "Publish to WordPress" button
2. **Content Approved Page** - Publish action in context menu
3. **Bulk Actions** - Select multiple, publish all

### 3.2 Detailed Flow

**Step 1: User clicks "Publish to WordPress"**
- Frontend: `ContentViewSet.publish` action called
- Endpoint: `POST /api/v1/writer/content/{id}/publish/`
- Optional body: `{ "site_integration_id": 123 }`

**Step 2: Backend validates content**
- Checks content exists and belongs to user's site
- Checks content not already published (`external_id` must be null)
- Finds active WordPress integration for the site
- Error if no integration found

**Step 3: Optimistic status update**
- Content status changed to `published` immediately
- User sees success message
- Actual WordPress publishing happens async

**Step 4: Celery task queued**
- Task: `publish_content_to_wordpress.delay(content_id, site_integration_id)`
- Task name: `igny8_core.tasks.wordpress_publishing`

**Step 5: Celery task execution (Background)**

The task performs these steps:

1. **Load data** - Get Content and SiteIntegration from database
2. **Check if already published** - Skip if `external_id` exists
3. **Generate excerpt** - Strip HTML, take first 150 chars
4. **Load taxonomy terms** - Categories from `taxonomy_terms` M2M field, fallback to cluster name
5. **Load tags** - From `taxonomy_terms` + primary/secondary keywords
6. **Load images** - Featured image and gallery images, convert paths to URLs
7. **Build payload:**
   ```json
   {
     "content_id": 123,
     "title": "Post Title",
     "content_html": "<p>Full HTML content...</p>",
     "excerpt": "Short excerpt...",
     "status": "publish",
     "seo_title": "SEO Title",
     "seo_description": "Meta description",
     "primary_keyword": "main keyword",
     "secondary_keywords": ["kw1", "kw2"],
     "featured_image_url": "https://app.igny8.com/images/...",
     "gallery_images": [{ "url": "...", "alt": "", "caption": "" }],
     "categories": ["Category Name"],
     "tags": ["tag1", "tag2"]
   }
   ```
8. **Send to WordPress:**
   - URL: `{site_url}/wp-json/igny8/v1/publish`
   - Headers: `X-IGNY8-API-Key: {api_key}`
   - Method: POST
   - Timeout: 30 seconds

**Step 6: Process WordPress response**

| HTTP Code | Meaning | Action |
|-----------|---------|--------|
| 201 | Created | Update content with `external_id`, `external_url`, log success |
| 409 | Already exists | Update content with existing WordPress post data |
| 4xx/5xx | Error | Log failure, retry up to 3 times with exponential backoff |

**Step 7: Update IGNY8 content record**
```python
content.external_id = str(wp_post_id)
content.external_url = wp_post_url
content.status = 'published'
content.metadata['wordpress_status'] = 'publish'
content.save()
```

**Step 8: Create SyncEvent record**
```python
SyncEvent.objects.create(
    integration=site_integration,
    site=content.site,
    account=content.account,
    event_type='publish',
    action='content_publish',
    description=f"Published content '{title}' to WordPress",
    success=True,
    content_id=content.id,
    external_id=external_id,
    details={...}
)
```

### 3.3 Error Handling

- **Timeout**: Retry after 60 seconds (first attempt), then exponentially
- **Connection Error**: Same retry logic
- **Max Retries**: 3 attempts total
- **Final Failure**: SyncEvent created with `success=False`, error logged

---

## 4. Automation Publishing Flow

### 4.1 Automation Stage 7: Review → Published

Automation Stage 7 handles auto-approval and publishing:

**Current Implementation:**
- Content in `review` status is changed to `published` status
- Status change only - **NO automatic WordPress push currently implemented**
- Lock released, automation run marked complete

**What DOES NOT happen automatically:**
- No `publish_content_to_wordpress` task is triggered
- Content sits in `published` status waiting for manual publish or scheduled task

### 4.2 Scheduled Publishing Task (NOT CURRENTLY SCHEDULED)

There exists a task `process_pending_wordpress_publications()` that:
- Finds content with `status='published'` and `external_id=NULL`
- Queues each item to `publish_content_to_wordpress` task
- Processes max 50 items per run

**CURRENT STATUS: This task is NOT in Celery Beat schedule!**

Looking at `celery.py`, the beat schedule includes:
- `check-scheduled-automations` (hourly)
- `replenish-monthly-credits` (monthly)
- Various maintenance tasks

**Missing:**
- `process_pending_wordpress_publications` is NOT scheduled

### 4.3 To Enable Auto-Publishing After Automation

Two options:

**Option A: Add to Celery Beat Schedule**
```python
'process-pending-wordpress-publications': {
    'task': 'igny8_core.tasks.wordpress_publishing.process_pending_wordpress_publications',
    'schedule': crontab(minute='*/5'),  # Every 5 minutes
},
```

**Option B: Call directly from Stage 7**
Modify `run_stage_7()` to queue publish tasks for each approved content item.

---

## 5. Webhook Sync Flow (WordPress → IGNY8)

### 5.1 Purpose

Keeps IGNY8 in sync when content is modified directly in WordPress:
- Post status changed (published → draft, etc.)
- Post deleted/trashed
- Post metadata updated

### 5.2 Webhook Endpoints

| Endpoint | Purpose |
|----------|---------|
| `POST /api/v1/integration/webhooks/wordpress/status/` | Status changes |
| `POST /api/v1/integration/webhooks/wordpress/metadata/` | Metadata updates |

### 5.3 Status Webhook Flow

**Step 1: WordPress plugin detects status change**
- Hooks into `transition_post_status` action
- Collects: post_id, content_id, new_status, post_url

**Step 2: Plugin sends webhook to IGNY8**
```
POST https://app.igny8.com/api/v1/integration/webhooks/wordpress/status/

Headers:
  X-IGNY8-API-KEY: {api_key}

Body:
{
  "post_id": 123,
  "content_id": 456,
  "post_status": "publish",
  "post_url": "https://example.com/my-post/",
  "post_title": "My Post Title",
  "site_url": "https://example.com"
}
```

**Step 3: IGNY8 validates and processes**

1. Extract API key from header
2. Find Content by `content_id`
3. Find SiteIntegration by site_url + platform
4. Verify API key matches stored key
5. Map WordPress status to IGNY8 status:
   | WordPress | IGNY8 |
   |-----------|-------|
   | publish | published |
   | draft | draft |
   | pending | review |
   | private | published |
   | trash | draft |
   | future | review |
6. Update Content record:
   ```python
   content.external_id = str(post_id)
   content.external_url = post_url
   content.status = mapped_status
   content.metadata['wordpress_status'] = post_status
   content.metadata['last_wp_sync'] = now
   content.save()
   ```
7. Create SyncEvent log

### 5.4 Metadata Webhook Flow

Similar to status webhook but updates `content.metadata['wp_metadata']` with:
- Categories
- Tags
- Author info
- Modified date

---

## 6. Metadata Sync Flow

### 6.1 Manual Sync (User-Initiated)

**Trigger:** User clicks "Sync Now" in Site Settings

**Endpoint:** `POST /api/v1/integration/integrations/{id}/sync/`

**What it does:**
- Calls `SyncMetadataService.sync_wordpress_structure()`
- Fetches from WordPress:
  - Post types and counts
  - Categories list
  - Tags list
  - Site metadata
- Updates integration's `last_sync_at`
- Does NOT push/pull content

### 6.2 Structure Update

**Endpoint:** `POST /api/v1/integration/integrations/{id}/update_structure/`

Refreshes understanding of WordPress site:
- Available post types
- Taxonomy structures
- Capabilities

---

## 7. Data Models & Storage

### 7.1 SiteIntegration

| Field | Type | Purpose |
|-------|------|---------|
| id | AutoField | Primary key |
| account | FK(Account) | Owner account |
| site | FK(Site) | IGNY8 site (contains wp_api_key) |
| platform | CharField | 'wordpress' |
| platform_type | CharField | 'cms' |
| config_json | JSONField | `{ "site_url": "https://..." }` |
| credentials_json | JSONField | `{ "plugin_version": "1.3.4", "debug_enabled": false }` |
| is_active | Boolean | Connection enabled |
| sync_enabled | Boolean | Two-way sync enabled |
| last_sync_at | DateTime | Last successful sync |
| sync_status | CharField | pending/success/failed/syncing |
| sync_error | TextField | Last error message |

**Note:** `credentials_json` no longer stores API key. API key is stored in `Site.wp_api_key` (single source of truth).

### 7.1a Site Model (API Key Storage)

| Field | Type | Purpose |
|-------|------|---------|-------|
| id | AutoField | Primary key |
| account | FK(Account) | Owner account |
| name | CharField | Site display name |
| url | URLField | WordPress site URL |
| wp_api_key | CharField | **API key for WordPress integration (SINGLE source of truth)** |
| wp_url | URLField | Legacy field (deprecated) |
| wp_username | CharField | Legacy field (deprecated) |
| wp_app_password | CharField | Legacy field (deprecated) |
| hosting_type | CharField | 'wordpress', 'shopify', 'igny8_sites', 'multi' |

### 7.2 Plugin Models

#### Plugin

Core plugin registry (platform-agnostic).

| Field | Type | Purpose |
|-------|------|---------|-------|
| id | AutoField | Primary key |
| name | CharField | Plugin display name (e.g., "IGNY8 WordPress Bridge") |
| slug | SlugField | URL-safe identifier (e.g., "igny8-wp-bridge") |
| platform | CharField | Target platform ('wordpress', 'shopify', etc.) |
| description | TextField | Plugin description |
| author | CharField | Plugin author |
| author_url | URLField | Author website |
| plugin_url | URLField | Plugin homepage |
| icon_url | URLField | Plugin icon (256x256) |
| banner_url | URLField | Plugin banner (772x250) |
| is_active | Boolean | Whether plugin is available for download |
| created_at | DateTime | Record creation |
| updated_at | DateTime | Last modified |

**Current WordPress Plugin:**
- Name: "IGNY8 WordPress Bridge"
- Slug: "igny8-wp-bridge"
- Platform: "wordpress"
- Description: "Connect your WordPress site to IGNY8 for AI-powered content publishing, SEO optimization, and seamless automation."
- Author: "IGNY8 Team"

#### PluginVersion

Version tracking with distribution files.

| Field | Type | Purpose |
|-------|------|---------|-------|
| id | AutoField | Primary key |
| plugin | FK(Plugin) | Parent plugin |
| version | CharField | Semantic version (e.g., "1.3.4") |
| status | CharField | 'development', 'beta', 'released', 'deprecated' |
| release_notes | TextField | Changelog/release notes |
| file_path | CharField | Path to ZIP file in /plugins/{platform}/dist/ |
| file_size | BigInteger | ZIP file size in bytes |
| checksum_md5 | CharField | MD5 hash for verification |
| checksum_sha256 | CharField | SHA256 hash for verification |
| requires_version | CharField | Minimum platform version (e.g., WP 5.6+) |
| tested_version | CharField | Tested up to version |
| is_latest | Boolean | Whether this is the latest stable version |
| download_count | Integer | Number of downloads |
| released_at | DateTime | Public release date |
| created_at | DateTime | Record creation |

**Current Latest Version (1.3.4):**
- Status: "released"
- File: `/plugins/wordpress/dist/igny8-wp-bridge-1.3.4.zip`
- Requires: WordPress 5.6+
- Tested: WordPress 6.4
- Features: API key authentication only, template improvements, image layout fixes

#### PluginInstallation

Tracks plugin installations per site.

| Field | Type | Purpose |
|-------|------|---------|-------|
| id | AutoField | Primary key |
| site | FK(Site) | Site where plugin is installed |
| plugin_version | FK(PluginVersion) | Installed version |
| installed_at | DateTime | Installation timestamp |
| last_seen | DateTime | Last health check |
| status | CharField | 'active', 'inactive', 'error' |
| metadata | JSONField | Installation-specific data (PHP version, WP version, etc.) |

#### PluginDownload

Download analytics.

| Field | Type | Purpose |
|-------|------|---------|-------|
| id | AutoField | Primary key |
| plugin_version | FK(PluginVersion) | Downloaded version |
| site | FK(Site, null=True) | Site that downloaded (if authenticated) |
| ip_address | GenericIPAddressField | Downloader IP |
| user_agent | TextField | Browser/client info |
| downloaded_at | DateTime | Download timestamp |

### 7.3 SyncEvent

| Field | Type | Purpose |
|-------|------|---------|
| id | AutoField | Primary key |
| integration | FK(SiteIntegration) | Parent integration |
| site | FK(Site) | Related site |
| account | FK(Account) | Owner account |
| event_type | CharField | publish/sync/error/webhook/metadata_sync |
| action | CharField | content_publish/status_update/etc |
| description | TextField | Human-readable event description |
| success | Boolean | Event outcome |
| content_id | Integer | IGNY8 content ID |
| external_id | CharField | WordPress post ID |
| error_message | TextField | Error details if failed |
| details | JSONField | Additional event data |
| duration_ms | Integer | Operation duration |
| created_at | DateTime | Event timestamp |

### 7.3 Content Fields (Publishing Related)

| Field | Purpose |
|-------|---------|
| external_id | WordPress post ID (string) |
| external_url | WordPress post URL |
| status | IGNY8 status (draft/review/published) |
| metadata['wordpress_status'] | WordPress status (publish/draft/etc) |
| metadata['last_wp_sync'] | Last webhook sync timestamp |

---

## 8. Current Implementation Gaps

### 8.1 Missing: Scheduled Auto-Publishing

**Problem:** Content approved by Automation Stage 7 is not automatically pushed to WordPress.

**Current State:**
- `process_pending_wordpress_publications()` task exists
- Task is NOT in Celery Beat schedule
- Content remains in `published` status with `external_id=NULL`

**Impact:** Users must manually publish each content item even after automation completes.

### 8.2 Missing: Pull Sync (WordPress → IGNY8 Content)

**Problem:** No way to import existing WordPress posts into IGNY8.

**Current State:**
- Webhooks only handle status updates for content that originated from IGNY8
- No "Import from WordPress" feature
- No scheduled pull sync

### 8.3 Missing: Content Update Sync

**Problem:** Editing content in IGNY8 after publishing doesn't update WordPress.

**Current State:**
- Only initial publish is supported
- No "republish" or "update" functionality
- `external_id` check prevents re-publishing

### 8.4 Missing: Image Upload to WordPress

**Problem:** Featured images are passed as URLs, not uploaded to WordPress media library.

**Current State:**
- Image URL is sent in payload
- WordPress plugin must download and create attachment
- If plugin doesn't handle this, no featured image

---

## 8. Plugin Distribution System

### 8.1 Architecture (v1.7.0)

**Plugin Distribution Components:**
- `Plugin` model - Multi-platform plugin registry
- `PluginVersion` model - Version tracking with files and checksums
- `PluginInstallation` model - Installation tracking per site
- `PluginDownload` model - Download analytics

**Distribution Endpoints:**
```
GET  /api/plugins/igny8-wp-bridge/download/       - Download latest ZIP
POST /api/plugins/igny8-wp-bridge/check-update/   - Check for updates
GET  /api/plugins/igny8-wp-bridge/info/           - Plugin metadata
POST /api/plugins/igny8-wp-bridge/register/       - Register installation
POST /api/plugins/igny8-wp-bridge/health-check/   - Health monitoring
```

### 8.2 Auto-Update Mechanism

**WordPress Side:**
1. Plugin hooks into `pre_set_site_transient_update_plugins`
2. Calls `/api/plugins/igny8-wp-bridge/check-update/` with current version
3. Receives update info if newer version available
4. WordPress displays update notification
5. User clicks "Update Now" (or auto-update runs)
6. WordPress downloads ZIP from `/download/` endpoint
7. Installs and activates new version

**IGNY8 Side:**
1. Developer updates plugin source code
2. Creates new `PluginVersion` in Django admin
3. Changes status to "released"
4. Signal automatically builds ZIP with checksums
5. Files stored in `/plugins/wordpress/dist/`
6. WordPress sites can now download/update

### 8.3 Version History (Recent)

| Version | Date | Changes |
|---------|------|---------|| 1.3.4 | Jan 12, 2026 | **API key authentication only** (removed username/password support), webhooks deprecated, Bearer token auth, simplified integration || 1.3.3 | Jan 10, 2026 | Template design: Square image grid fixes, landscape positioning, direct styling for images without captions |
| 1.3.2 | Jan 9, 2026 | Template rendering improvements, image layout enhancements |
| 1.3.1 | Jan 9, 2026 | Plugin versioning updates |
| 1.3.0 | Jan 8, 2026 | Distribution system release, auto-update mechanism |

### 8.4 Security Features

- **Signed URLs:** Download links expire after configurable time
- **Checksums:** MD5 and SHA256 verification
- **Rate Limiting:** Per IP/site download limits
- **API Authentication:** Required for sensitive operations
- **Version Verification:** WordPress validates plugin before update

### 8.5 Monitoring

**Installation Tracking:**
- Total installations per version
- Active installations by site
- Version distribution analytics

**Download Analytics:**
- Download counts per version
- Geographic distribution
- Failed download attempts

**Health Checks:**
- Plugin health status per installation
- Error reporting from WordPress sites
- Version compatibility tracking

---

## 9. Current Implementation

### 9.1 Production Status (v1.7.0)

**✅ Fully Operational:**
- WordPress plugin distribution system
- Auto-update mechanism
- Template rendering with advanced layouts
- Image positioning (square/landscape)
- Content publishing (manual + automation)
- Webhook status sync
- API authentication
- Health monitoring

**✅ Template Features (v1.3.3):**
- Square images: Side-by-side layout (left/right aligned)
- Landscape images: Full-width with max 1024px
- Images appear after first paragraph in sections
- Direct border-radius/shadow on images without captions
- Responsive design for mobile/tablet

### 9.2 Known Limitations

**Missing Features:**
- Bi-directional content sync (WordPress → IGNY8 editing)
- Conflict resolution for dual edits
- Advanced metadata sync beyond basics
- Multi-site WordPress network support
- Custom post type publishing

### 9.3 Future Enhancements

**Planned:**
- Image regeneration feature (Phase 9)
- Advanced template customization
- Custom field mapping
- Bulk publishing operations
- Real-time sync notifications

---

## 10. Flow Diagrams

### 10.1 Integration Setup (API Key Authentication)

```
┌──────────┐     ┌─────────────────┐     ┌───────────────┐
│  User    │     │   IGNY8 API     │     │   WordPress   │
│          │     │  (Backend)      │     │   Site        │
└────┬─────┘     └────────┬────────┘     └───────┬───────┘
     │                    │                      │
     │ 1. Generate API Key (Site Settings)       │
     ├───────────────────>│                      │
     │                    │ Store in Site.wp_api_key
     │<───────────────────┤ (SINGLE source)      │
     │ 2. API Key: igny8_live_xxxxx              │
     │                    │                      │
     │ 3. Download Plugin ZIP                    │
     ├───────────────────>│                      │
     │                    │ GET /api/plugins/    │
     │                    │     igny8-wp-bridge/ │
     │                    │     download/        │
     │<───────────────────┤                      │
     │ 4. igny8-wp-bridge-1.3.4.zip              │
     │                    │                      │
     │ 5. Install & Activate Plugin──────────────┼────────>
     │                    │                      │
     │ 6. Enter API Key + Site ID in WP Settings─┼────────>
     │                    │                      │
     │ 7. Click "Test Connection" in Plugin──────┼────────>
     │                    │                      │
     │                    │ 8. POST /api/v1/     │
     │                    │    integration/      │
     │                    │    integrations/     │
     │                    │    test-connection/  │
     │                    │<─────────────────────┤
     │                    │ Headers:             │
     │                    │   Authorization:     │
     │                    │   Bearer {api_key}   │
     │                    │                      │
     │                    │ Validate against     │
     │                    │ Site.wp_api_key      │
     │                    │                      │
     │                    │ Create/Update        │
     │                    │ SiteIntegration      │
     │                    │ (credentials_json={})│
     │                    │                      │
     │                    │ 9. 200 OK            │
     │                    ├─────────────────────>│
     │                    │ {success: true}      │
     │                    │                      │
     │ 10. Success Message in Plugin─────────────┼────────>
     │                    │                      │
     │                    │ 11. POST /register/  │
     │                    │<─────────────────────┤
     │                    │ Store PluginInstallation
     │                    │                      │
```

**Key Changes in v1.3.4:**
- ✅ API key stored in `Site.wp_api_key` (not in SiteIntegration)
- ✅ `credentials_json` is empty (only stores plugin_version, debug_enabled)
- ✅ Authentication via `Authorization: Bearer {api_key}` header
- ✅ No WordPress admin username/password needed
- ✅ Simplified setup - single API key for all communication

### 10.2 Manual Publishing

```
┌──────────┐     ┌──────────────┐     ┌──────────┐     ┌───────────────┐
│  User    │     │   IGNY8 API  │     │  Celery  │     │   WordPress   │
└────┬─────┘     └──────┬───────┘     └────┬─────┘     └───────┬───────┘
     │                  │                  │                   │
     │ 1. Click Publish │                  │                   │
     ├─────────────────>│                  │                   │
     │                  │                  │                   │
     │                  │ 2. Validate      │                   │
     │                  │ 3. Update status │                   │
     │                  │ 4. Queue task    │                   │
     │                  ├─────────────────>│                   │
     │<─────────────────┤                  │                   │
     │ 5. "Publishing..."                  │                   │
     │                  │                  │                   │
     │                  │                  │ 6. POST /publish  │
     │                  │                  ├──────────────────>│
     │                  │                  │                   │
     │                  │                  │<──────────────────┤
     │                  │                  │ 7. 201 Created    │
     │                  │                  │                   │
     │                  │ 8. Update Content│                   │
     │                  │<─────────────────┤                   │
     │                  │ 9. Create SyncEvent                  │
     │                  │                  │                   │
```

### 10.3 Plugin Auto-Update Flow

```
┌───────────────┐     ┌──────────────┐
│   WordPress   │     │   IGNY8 API  │
└───────┬───────┘     └──────┬───────┘
        │                    │
        │ 1. Check for updates (cron)
        │ POST /check-update/│
        ├───────────────────>│
        │ (current: 1.3.2)   │
        │                    │
        │<───────────────────┤
        │ 2. Update available│
        │ (latest: 1.3.3)    │
        │                    │
        │ 3. User clicks     │
        │    "Update Now"    │
        │                    │
        │ GET /download/     │
        ├───────────────────>│
        │                    │
        │<───────────────────┤
        │ 4. ZIP file        │
        │                    │
        │ 5. Install & Activate
        │                    │
        │ POST /register/    │
        ├───────────────────>│
        │ (new version info) │
        │                    │
        │<───────────────────┤
        │ 6. Registration OK │
        │                    │
```

### 10.4 Webhook Status Sync

```
┌───────────────┐     ┌──────────────┐
│   WordPress   │     │   IGNY8 API  │
└───────┬───────┘     └──────┬───────┘
        │                    │
        │ 1. User changes status in WP
        │                    │
        │ 2. POST /webhooks/wordpress/status/
        ├───────────────────>│
        │                    │
        │                    │ 3. Validate API key
        │                    │ 4. Find Content
        │                    │ 5. Map status
        │                    │ 6. Update Content
        │                    │ 7. Create SyncEvent
        │                    │
        │<───────────────────┤
        │ 8. 200 OK          │
        │                    │
```

---

## Summary

| Flow | Status | Notes |
|------|--------|-------|
| Integration Setup | ✅ Working | API key based |
| Manual Publish | ✅ Working | Via Celery task |
| Automation Publish | ⚠️ Partial | Stage 7 sets status but doesn't trigger WordPress push |
| Webhook Status Sync | ✅ Working | WordPress → IGNY8 status updates |
| Webhook Metadata Sync | ✅ Working | WordPress → IGNY8 metadata |
| Scheduled Auto-Publish | ❌ Not Active | Task exists but not scheduled |
| Content Pull Sync | ❌ Not Implemented | No import from WordPress |
| Content Update Sync | ❌ Not Implemented | No republish capability |

