36 KiB
36 KiB
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