# WordPress Plugin ↔ IGNY8 Backend Sync - Data Flow Diagram ## Complete Sync Journey ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ WORDPRESS ADMIN - Connection Setup │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ User Input: │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ Email: dev@igny8.com │ │ │ │ Password: **** │ │ │ │ API Key: **** │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ WORDPRESS PLUGIN - Authentication (class-admin.php handle_connection()) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. POST /auth/login/ (with email + password) │ │ ↓ │ │ 2. Store: access_token, refresh_token │ │ ↓ │ │ 3. GET /system/sites/ (authenticated) │ │ ↓ │ │ 4. Store: site_id (extracted from first site) │ │ ↓ │ │ ✅ Connection complete! User sees success message │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ WORDPRESS PLUGIN - Gather Site Structure (igny8_sync_site_structure_to_backend) ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ Step 1: Query for Integration ID │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ GET /v1/integration/integrations/ │ │ │ │ ?site={site_id} │ │ │ │ &platform=wordpress ← NEW: Platform filter │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ ↓ │ │ Step 2: Extract Integration ID (handle multiple response formats) │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ Response Format Handling: │ │ │ │ • Paginated: data.results[0] ← Django REST Framework │ │ │ │ • Array: data[0] ← Alternative format │ │ │ │ • Object: data ← Direct single object │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ ↓ │ │ Step 3: Gather WordPress Content Structure │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ Post Types (igny8_get_site_structure): │ │ │ │ ├─ post → "Posts" (count: 50) │ │ │ │ ├─ page → "Pages" (count: 10) │ │ │ │ └─ product → "Products" (count: 100) │ │ │ │ │ │ │ │ Taxonomies: │ │ │ │ ├─ category → "Categories" (count: 12) │ │ │ │ ├─ post_tag → "Tags" (count: 89) │ │ │ │ └─ product_cat → "Product Categories" (count: 15) │ │ │ │ │ │ │ │ Metadata: │ │ │ │ ├─ timestamp (ISO 8601 format) ← NEW │ │ │ │ ├─ site_url (WordPress domain) ← NEW │ │ │ │ └─ wordpress_version (e.g., 6.4) ← NEW │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ With Enhanced Debug Logging (if WP_DEBUG or IGNY8_DEBUG enabled): │ │ • Log: Integration ID retrieved │ │ • Log: Structure gathered successfully │ │ • Log: Ready to sync │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ WORDPRESS → IGNY8 BACKEND - Push Structure (class-igny8-api.php post()) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ POST /v1/integration/integrations/{integration_id}/update-structure/ │ │ │ │ Headers: │ │ ├─ Authorization: Bearer {access_token} │ │ └─ Content-Type: application/json │ │ │ │ Request Body: │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ { │ │ │ │ "post_types": { │ │ │ │ "post": { │ │ │ │ "label": "Posts", │ │ │ │ "count": 50, │ │ │ │ "enabled": true, │ │ │ │ "fetch_limit": 100 │ │ │ │ }, │ │ │ │ "page": {...}, │ │ │ │ "product": {...} │ │ │ │ }, │ │ │ │ "taxonomies": { │ │ │ │ "category": { │ │ │ │ "label": "Categories", │ │ │ │ "count": 12, │ │ │ │ "enabled": true, │ │ │ │ "fetch_limit": 100 │ │ │ │ }, │ │ │ │ "post_tag": {...}, │ │ │ │ "product_cat": {...} │ │ │ │ }, │ │ │ │ "timestamp": "2025-11-22T10:15:30+00:00", │ │ │ │ "plugin_connection_enabled": true, │ │ │ │ "two_way_sync_enabled": true │ │ │ │ } │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ Debug Logging (NEW - Post Request Logging): │ │ ├─ Log: Request URL │ │ ├─ Log: Request payload (sanitized) │ │ ├─ Log: Response status code │ │ ├─ Log: Response body (first 500 chars) │ │ └─ Log: Success/error with integration ID │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ IGNY8 BACKEND - Store Structure (modules/integration/views.py │ │ update_site_structure action) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. Authenticate request │ │ ├─ Check Bearer token │ │ └─ Verify user owns this integration │ │ │ │ 2. Extract payload │ │ ├─ post_types │ │ ├─ taxonomies │ │ ├─ timestamp (optional, defaults to now) │ │ ├─ plugin_connection_enabled │ │ └─ two_way_sync_enabled │ │ │ │ 3. Store in SiteIntegration.config_json │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ config_json = { │ │ │ │ "content_types": { │ │ │ │ "post_types": {...}, │ │ │ │ "taxonomies": {...}, │ │ │ │ "last_structure_fetch": "2025-11-22T10:15:30+00:00" │ │ │ │ }, │ │ │ │ "plugin_connection_enabled": true, │ │ │ │ "two_way_sync_enabled": true, │ │ │ │ ... other config fields ... │ │ │ │ } │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ 4. Return Success Response │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ { │ │ │ │ "success": true, │ │ │ │ "data": { │ │ │ │ "message": "Site structure updated successfully", │ │ │ │ "post_types_count": 3, │ │ │ │ "taxonomies_count": 3, │ │ │ │ "last_structure_fetch": "2025-11-22T10:15:30+00:00" │ │ │ │ } │ │ │ │ } │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ 5. Database save │ │ └─ SiteIntegration record updated │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ WORDPRESS PLUGIN - Confirm Success & Update Options │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. Response Received (success == true) │ │ ├─ Show success message to user │ │ ├─ Log: "Site structure synced successfully" │ │ └─ Update option: igny8_last_structure_sync = timestamp │ │ │ │ 2. New Options Created: │ │ ├─ igny8_structure_synced = 1 (flag for status checking) │ │ └─ igny8_last_structure_sync = unix timestamp │ │ │ │ 3. User Feedback: │ │ ├─ "Successfully connected to IGNY8 API" │ │ ├─ "Site structure synced successfully" ← NEW MESSAGE │ │ └─ Or: "Connected but structure sync will be retried" (non-blocking) │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────────┐ │ IGNY8 FRONTEND - Fetch & Display Content Types │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. User navigates to Site Settings → Content Types Tab │ │ │ │ 2. Frontend queries backend: │ │ GET /v1/integration/integrations/{integration_id}/content-types/ │ │ │ │ 3. Backend processes request (content_types_summary action): │ │ ├─ Get stored content_types from config_json │ │ ├─ Count synced items in Content model │ │ ├─ Count synced items in ContentTaxonomy model │ │ ├─ Compute synced_count for each post type │ │ └─ Compute synced_count for each taxonomy │ │ │ │ 4. Backend Response: │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ { │ │ │ │ "success": true, │ │ │ │ "data": { │ │ │ │ "post_types": { │ │ │ │ "post": { │ │ │ │ "label": "Posts", │ │ │ │ "count": 50, ← Total in WordPress │ │ │ │ "synced_count": 30, ← Synced to IGNY8 │ │ │ │ "enabled": true, │ │ │ │ "fetch_limit": 100 │ │ │ │ }, │ │ │ │ "page": {...}, │ │ │ │ "product": {...} │ │ │ │ }, │ │ │ │ "taxonomies": { │ │ │ │ "category": { │ │ │ │ "label": "Categories", │ │ │ │ "count": 12, ← Total in WordPress │ │ │ │ "synced_count": 12, ← Synced to IGNY8 │ │ │ │ "enabled": true, │ │ │ │ "fetch_limit": 100 │ │ │ │ }, │ │ │ │ "post_tag": {...}, │ │ │ │ "product_cat": {...} │ │ │ │ }, │ │ │ │ "last_structure_fetch": "2025-11-22T10:15:30+00:00", │ │ │ │ "plugin_connection_enabled": true, │ │ │ │ "two_way_sync_enabled": true │ │ │ │ } │ │ │ │ } │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ 5. Frontend Renders: │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ Content Types │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ │ │ Post Types │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Posts 50 total · 30 synced │ │ │ │ │ │ │ │ Enabled Limit: 100 │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Pages 10 total · 8 synced │ │ │ │ │ │ │ │ Enabled Limit: 100 │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Products 100 total · 45 synced │ │ │ │ │ │ │ │ Enabled Limit: 100 │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ │ │ Taxonomies │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Categories 12 total · 12 synced │ │ │ │ │ │ │ │ Enabled Limit: 100 │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Tags 89 total · 60 synced │ │ │ │ │ │ │ │ Enabled Limit: 100 │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ Structure last fetched: 2025-11-22 10:15:30 UTC │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Daily Cron Job - Automatic Updates ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ WordPress Cron - Daily Schedule (igny8_sync_site_structure) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ Every 24 hours: │ │ ├─ Trigger: do_action('igny8_sync_site_structure') │ │ ├─ Call: igny8_sync_site_structure_to_backend() │ │ ├─ Same flow as above (Get structure → Push to backend) │ │ ├─ Updates counts and structure if changed │ │ └─ Ensures frontend always has current data │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Error Handling & Logging Flow ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ Error Detection & Logging │ ├──────────────────────────────────────────────────────────────────────────┤ │ │ │ If query fails: │ │ ├─ Log: "Failed to fetch integrations. Error: [details]" │ │ └─ Return: false (non-blocking) │ │ │ │ If integration not found: │ │ ├─ Log: "Could not find valid WordPress integration for site {id}" │ │ ├─ Log: "Response data: [full response]" │ │ └─ Return: false (non-blocking) │ │ │ │ If POST fails: │ │ ├─ Log: "Failed to sync site structure to integration {id}" │ │ ├─ Log: "Error: [error message]" │ │ ├─ Log: "Full response: [response JSON]" │ │ └─ Return: false (non-blocking) │ │ │ │ If successful: │ │ ├─ Log: "Site structure synced successfully to integration {id}" │ │ ├─ Update: igny8_structure_synced option │ │ ├─ Update: igny8_last_structure_sync timestamp │ │ └─ Return: true │ │ │ │ All logs go to: wp-content/debug.log │ │ To enable: define('WP_DEBUG_LOG', true) in wp-config.php │ │ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Summary ✅ **Reliable bidirectional data flow** - WordPress → Backend: Structure pushed on connection and daily - Backend → Frontend: Structure retrieved and displayed with sync counts - All steps logged and error-handled - Non-blocking approach ensures connection always succeeds ✅ **User visibility** - Clear success/failure messages - Debug logs provide troubleshooting info - Frontend shows current status and counts ✅ **Maintenance** - Automatic daily updates keep data fresh - Error handling prevents sync failures from breaking the system - Complete audit trail in logs