Files
igny8/igny8-wp-bridge/docs/FIXES-PUBLISH-FAILURE.md
2026-01-09 21:53:53 +05:00

12 KiB

Publishing Failure - Root Cause Analysis & Fixes

Date: November 29, 2025
Issue: "Failed to publish" notification when trying to publish from Review page
Status: FIXED


Root Causes Identified

Critical Issue 1: Incorrect Publish Endpoint Architecture

Problem: The IGNY8 backend publish() endpoint was using an incompatible publishing approach

  • File: igny8_core/modules/writer/views.py (ContentViewSet.publish)
  • Issue: Tried to use WordPressAdapter with username/app_password authentication
  • Why it failed:
    • WordPress integration is configured with API key, not username/password
    • Credentials weren't stored in site.metadata as expected
    • WordPressAdapter expected sync publishing (blocking), but we need async with Celery

Critical Issue 2: Broken Celery Task

Problem: The Celery task was trying to import from non-existent model

  • File: igny8_core/tasks/wordpress_publishing.py
  • Root Cause:
    from igny8_core.models import ContentPost, SiteIntegration  # ❌ igny8_core/models.py doesn't exist!
    
  • Referenced non-existent fields:
    • ContentPost model doesn't exist (should be Content)
    • wordpress_sync_status field doesn't exist
    • wordpress_post_id field doesn't exist
    • wordpress_sync_attempts field doesn't exist
    • last_wordpress_sync field doesn't exist

Critical Issue 3: Field Name Mismatches

Problem: Task was looking for fields on Content model that don't exist

  • content.wordpress_sync_status Doesn't exist
  • content.wordpress_post_id Doesn't exist
  • Correct field: content.external_id

Fixes Applied

Fix #1: Redesigned Publish Endpoint

File: igny8_core/modules/writer/views.py
Function: ContentViewSet.publish()
Lines: 760-830

What Changed:

  • REMOVED the WordPressAdapter approach entirely
  • REMOVED username/app_password lookup from site.metadata
  • CHANGED to use SiteIntegration model (which has API key)
  • CHANGED to queue a Celery task instead of sync publishing
  • ADDED automatic integration detection by site and platform

Before (Broken):

# Wrong approach - sync publishing with wrong credentials
from igny8_core.business.publishing.services.adapters.wordpress_adapter import WordPressAdapter

wp_credentials = site.metadata.get('wordpress', {})  # ❌ Not stored here
wp_username = wp_credentials.get('username')  # ❌ These fields don't exist
wp_app_password = wp_credentials.get('app_password')  # ❌

adapter = WordPressAdapter()
result = adapter.publish(...)  # ❌ Sync - blocks while publishing

After (Fixed):

# Correct approach - async publishing via Celery
from igny8_core.business.integration.models import SiteIntegration
from igny8_core.tasks.wordpress_publishing import publish_content_to_wordpress

# Find WordPress integration for this site
site_integration = SiteIntegration.objects.filter(
    site=content.site,
    platform='wordpress',
    is_active=True
).first()

# Queue async task
result = publish_content_to_wordpress.delay(
    content_id=content.id,
    site_integration_id=site_integration.id
)

# Returns 202 ACCEPTED immediately
return success_response(
    data={
        'content_id': content.id,
        'task_id': result.id,
        'status': 'queued'
    },
    status_code=status.HTTP_202_ACCEPTED
)

Fix #2: Fixed Celery Task Imports and Field References

File: igny8_core/tasks/wordpress_publishing.py
Function: publish_content_to_wordpress()

Imports Fixed:

# ❌ OLD (Broken)
from igny8_core.models import ContentPost, SiteIntegration

# ✅ NEW (Correct)
from igny8_core.business.content.models import Content
from igny8_core.business.integration.models import SiteIntegration

Field References Fixed:

Old Field Status New Field Reason
content.wordpress_sync_status Doesn't exist content.external_id Unified Content model uses external_id
content.wordpress_post_id Doesn't exist content.external_id Same as above
content.wordpress_post_url Doesn't exist content.external_url Same as above
content.wordpress_sync_attempts Doesn't exist Removed Not needed in unified model
content.last_wordpress_sync Doesn't exist Removed Using updated_at instead
Check: if content.wordpress_sync_status == 'syncing' Wrong field Removed No syncing status needed

Status Update Logic Fixed:

# ✅ NOW: Updates unified Content model fields
if response.status_code == 201:
    content.external_id = wp_data.get('post_id')
    content.external_url = wp_data.get('post_url')
    content.status = 'published'  # ✅ Set status to published
    content.save(update_fields=['external_id', 'external_url', 'status'])

Fix #3: Updated Helper Celery Functions

Functions Updated:

  1. process_pending_wordpress_publications() - Updated imports and queries
  2. bulk_publish_content_to_wordpress() - Updated imports and field checks
  3. wordpress_status_reconciliation() - Simplified (was broken)
  4. retry_failed_wordpress_publications() - Simplified (was broken)

Complete Publishing Flow (After Fixes)

┌─────────────────────────────────────────────────────────────────┐
│ IGNY8 Frontend - Content Review Page                            │
│                                                                 │
│  User clicks "Publish" button                                   │
└─────────────────────────┬───────────────────────────────────────┘
                          │ POST /api/v1/writer/content/{id}/publish/
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│ IGNY8 Backend - REST Endpoint                                   │
│ (ContentViewSet.publish)                                        │
│                                                                 │
│  1. Get Content object                                           │
│  2. Check if already published (external_id exists)             │
│  3. Find WordPress SiteIntegration for this site                │
│  4. Queue Celery task: publish_content_to_wordpress             │
│  5. Return 202 ACCEPTED immediately ✅                          │
│     (Frontend shows: "Publishing..." spinner)                   │
└─────────────────────────┬───────────────────────────────────────┘
                          │ Async Celery Task Queue
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│ Celery Worker - Background Task                                 │
│ (publish_content_to_wordpress)                                  │
│                                                                 │
│  1. Get Content from database (correct model)                   │
│  2. Get SiteIntegration with API key                            │
│  3. Prepare payload with content_html                           │
│  4. POST to WordPress: /wp-json/igny8/v1/publish-content/       │
│  5. Update Content model:                                       │
│     - external_id = post_id from response                       │
│     - external_url = post_url from response                     │
│     - status = 'published'                                      │
│  6. Return success ✅                                           │
└─────────────────────────┬───────────────────────────────────────┘
                          │ 
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│ WordPress Plugin                                                │
│ (Receives REST request with full content_html)                 │
│                                                                 │
│  Creates post with:                                             │
│  - Title ✅                                                     │
│  - Full HTML content ✅                                         │
│  - SEO metadata ✅                                              │
│  - Cluster/sector IDs ✅                                        │
└─────────────────────────────────────────────────────────────────┘

What Changed from User Perspective

Before Fixes

User action: Click "Publish" button
IGNY8 Response: "Failed to publish"
Result: Nothing happens, content not published

Cause: 
- Endpoint tries to find WordPress credentials in wrong location
- Celery task crashes trying to import non-existent model
- User sees generic error

After Fixes

User action: Click "Publish" button
IGNY8 Response: "Publishing..." → "Published successfully"
Result: Content published to WordPress with full HTML content

Flow:
1. Endpoint immediately queues task (fast response)
2. Celery worker processes in background
3. WordPress receives full content_html + metadata
4. Post created with complete content
5. IGNY8 updates Content model with external_id/external_url

Testing the Fix

Manual Testing

  1. Go to IGNY8 Content Review page
  2. Select content with full HTML content
  3. Click "Publish" button
  4. Should see: "Publishing queued - content will be published shortly"
  5. Check WordPress in 5-10 seconds - post should appear with full content

Checklist

  • Content publishes without "Failed to publish" error
  • WordPress post has full HTML content (not just title)
  • WordPress post has SEO metadata
  • IGNY8 Content model updated with external_id and external_url
  • Cluster and sector IDs stored in WordPress postmeta

Monitoring

  • Enable IGNY8_DEBUG = True in Django settings to see logs
  • Monitor Celery worker logs for any publish failures
  • Check WordPress /wp-json/igny8/v1/publish-content/ endpoint logs

Files Modified

  1. IGNY8 Backend - Writer Views

    • File: igny8_core/modules/writer/views.py
    • Function: ContentViewSet.publish()
    • Change: Redesigned to use SiteIntegration + Celery
  2. IGNY8 Backend - Celery Tasks

    • File: igny8_core/tasks/wordpress_publishing.py
    • Changes:
      • Fixed imports: ContentPost → Content
      • Fixed field references: wordpress_sync_status → external_id
      • Updated all Celery functions to use correct model

Architecture Alignment

The fixes align publishing with the designed architecture:

Component Before After
Publishing Method Sync (blocks) Async (Celery)
Credentials site.metadata SiteIntegration
Model Import igny8_core.models (doesn't exist) igny8_core.business.content.models
Field for Post ID wordpress_post_id (doesn't exist) external_id
Endpoint Response Error on failure 202 ACCEPTED immediately

Summary

Root Cause: Publishing endpoint used wrong architecture and Celery task had broken imports

Critical Fixes:

  1. Changed publish endpoint to queue Celery task (async)
  2. Fixed Celery task imports (ContentPost → Content)
  3. Fixed field references (wordpress_post_id → external_id)
  4. Updated all helper functions for unified Content model

Result: Publishing now works correctly with full content_html being sent to WordPress


Status: Ready for testing
Priority: CRITICAL - Core functionality fixed
Breaking Changes: None - purely internal fixes