Files
igny8/v2/V2-Execution-Docs/03B-wp-plugin-connected.md
IGNY8 VPS (Salman) 0570052fec 1
2026-03-23 17:20:51 +00:00

22 KiB

IGNY8 Phase 3: WordPress Plugin — Connected Mode (03B)

IGNY8 SaaS ↔ WordPress Bidirectional Integration

Document Version: 1.0 Date: 2026-03-23 Phase: IGNY8 Phase 3 — WordPress Ecosystem Status: Build Ready Source of Truth: Codebase at /data/app/igny8/ Audience: Claude Code, WordPress Developers, Architects


1. CURRENT STATE

Existing WordPress Bridge

The IGNY8 WordPress Bridge Plugin v1.5.2 at /data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/ provides basic content sync:

  • Content push from IGNY8 → WordPress via POST /wp-json/igny8/v1/sync/push
  • SAG blueprint sync via POST /wp-json/igny8/v1/sag/sync-blueprint
  • Taxonomy creation via POST /wp-json/igny8/v1/sag/create-taxonomies
  • API key authentication using X-IGNY8-API-KEY header

What v2 Connected Mode Replaces

Phase 3 connected mode is part of the new v2 plugin (03A). It replaces and extends all v1.5.2 capabilities with:

  • Full content queue + review workflow (not just raw push)
  • Image downloading and attachment creation
  • SAG blueprint → taxonomy + term → cluster hub page mapping
  • Bidirectional sync events and confirmation callbacks
  • Schema bulk push from IGNY8 backend (02G)
  • GSC status sync from IGNY8 backend (02C)
  • Auto-linking from IGNY8 backend (02D)
  • Social auto-post from IGNY8 backend (02H)

Prerequisites

  • Standalone plugin (03A) must be installed and active
  • IGNY8 SaaS subscription with valid API key
  • Connection established via Setup Wizard Step 5 or Settings → Connect

IGNY8 Backend Models That WordPress Interacts With

  • Content (writer app, db_table=igny8_content) — content_type: post/page/product/taxonomy; content_structure choices
  • Tasks (writer app, db_table=igny8_tasks) — writing tasks, status: queued/completed
  • Images (writer app) — generated images for content
  • Clusters (planner app, db_table=igny8_clusters) — keyword clusters
  • SAGBlueprint, SAGAttribute, SAGCluster (sag app) — Phase 1 SAG models
  • SiteIntegration (integration app) — WordPress connection details
  • SyncEvent (integration app) — sync operation logs
  • PublishingSettings, PublishingRecord (publishing app)
  • All IDs are integers (BigAutoField) — never UUIDs

2. WHAT TO BUILD

Overview

Two connected-mode modules that extend the standalone plugin (03A) when an IGNY8 SaaS subscription is active. These modules are only loaded when igny8_api_connected option is true.

Module 11: Content Sync

Purpose: Receive content from IGNY8 SaaS, queue it, download images, map types, create/update WordPress posts, and confirm back.

Classes:

Class File Purpose
IGNY8_Sync_Module modules/content-sync/class-sync-module.php Module entry, webhook receiver
IGNY8_Content_Puller modules/content-sync/class-content-puller.php Fetch content from IGNY8 SaaS API
IGNY8_Content_Mapper modules/content-sync/class-content-mapper.php Map IGNY8 content_type → WP post_type
IGNY8_Image_Downloader modules/content-sync/class-image-downloader.php Download images → wp_upload_dir(), wp_insert_attachment()
IGNY8_Sync_Queue modules/content-sync/class-sync-queue.php Sync queue DB table management
IGNY8_Publish_Scheduler modules/content-sync/class-publish-scheduler.php Review queue, scheduled publishing

Content Type Mapping:

IGNY8 content_type WP post_type Notes
post post Default blog post
page page Standard page
product product Requires WooCommerce active
service service Requires companion theme CPT (03C)
company_page page Uses page-company template
taxonomy_landing Written to term description (not a post)
cluster_hub page Landing page preset applied
comparison post Standard post with comparison structure
brand_page page Standard page

Content Sync Flow:

1. IGNY8 SaaS publishes content
2. → POST /wp-json/igny8/v1/sync/push (validated via X-IGNY8-API-KEY)
   Payload: {igny8_content_id, content_type, title, content_html, excerpt,
             featured_image, meta: {focus_keyword, secondary_keywords,
             cluster_id, taxonomies: {service_category: [...], cluster: [...]}}}
3. → Plugin creates {prefix}igny8_sync_queue entry (status: pending)
4. → WP Cron job (igny8_process_sync_queue) processes queue:
   a. Download images → wp_upload_dir(), wp_insert_attachment()
   b. Map content_type → WP post_type via IGNY8_Content_Mapper
   c. wp_insert_post() or wp_update_post()
   d. Set post meta (_igny8_content_id, _igny8_cluster_id, _igny8_sync_status)
   e. wp_set_object_terms() for taxonomy assignment
   f. Status: 'review' (manual mode) or 'synced' (auto-publish mode)
5. → Plugin POSTs confirmation to IGNY8: POST /api/v1/integration/sync-events/

Methods:

  • push_content_to_queue($data) — validate payload, insert into sync queue
  • process_sync_queue() — WP Cron handler, batch process pending items
  • map_content_type($igny8_type) — return WP post_type + template
  • create_post_from_content($data)wp_insert_post() + meta + terms
  • download_images($content) — download to wp_upload_dir(), create attachments
  • schedule_publish($post_id, $date) — set future publish date
  • get_review_queue() — list items with status review

Post Meta (Connected Mode):

_igny8_content_id              -- int: links WP post to IGNY8 Content record
_igny8_cluster_id              -- int: links WP post to IGNY8 SAGCluster
_igny8_sync_status             -- string: pending/synced/failed/modified
_igny8_last_sync               -- string: ISO timestamp
_igny8_related_links           -- JSON: [{post_id, anchor_text, priority}]
_igny8_link_suggestions        -- JSON: AI-generated link suggestions from 02D

Hooks:

  • Actions: wp_scheduled_event (igny8_process_sync_queue), rest_api_init
  • Filters: igny8_content_before_sync, igny8_post_mapped, igny8_sync_status_updated

Module 12: SAG Structure (Blueprint Sync)

Purpose: Receive SAG blueprint from IGNY8, create WordPress taxonomies and terms matching SAG dimensions and attributes, map clusters to hub pages, and provide structure visualization.

Classes:

Class File Purpose
IGNY8_SAG_Module modules/sag/class-sag-module.php Module entry
IGNY8_Blueprint_Sync modules/sag/class-blueprint-sync.php Receive + cache blueprint
IGNY8_Taxonomy_Builder modules/sag/class-taxonomy-builder.php register_taxonomy() from SAG attributes
IGNY8_Term_Builder modules/sag/class-term-builder.php wp_insert_term() with hierarchy
IGNY8_Cluster_Manager modules/sag/class-cluster-manager.php Map clusters → hub pages/terms
IGNY8_Structure_Visualizer modules/sag/class-structure-visualizer.php Visual site structure admin page

SAG Blueprint Sync Flow:

1. IGNY8 confirms blueprint (01D setup wizard)
2. → POST /wp-json/igny8/v1/sag/sync-blueprint (validated via X-IGNY8-API-KEY)
   Payload: {blueprint: {dimensions: [{id, name, slug, attributes: [{id, name, slug}]}],
              clusters: [{id, name, dimension_ids, hub_page_id, recommended_content_count}]}}
3. → Plugin stores in option igny8_sag_blueprint
4. → Admin sees "Blueprint Review" notice
5. → User clicks "Approve Blueprint":
   a. Loop dimensions → register_taxonomy() if not exists
   b. Loop attribute values → wp_insert_term() with parent hierarchy
   c. Set term meta (_igny8_term_sag_attribute, _igny8_term_sag_level)
   d. Loop clusters → create/link hub pages
6. → POST confirmation back: {term_ids_map, hub_page_ids_map}

Methods:

  • sync_blueprint($json) — validate, store in option, trigger admin notice
  • create_taxonomies_from_blueprint($bp)register_taxonomy() per dimension
  • create_terms_from_blueprint($bp)wp_insert_term() per attribute value
  • map_cluster_to_page($cluster_id, $page_id) — link SAGCluster to WP hub page
  • get_blueprint() — return cached blueprint from option
  • get_structure_overview() — summary for structure visualizer admin page

Term Meta (Connected Mode):

_igny8_term_content              -- string: rich HTML for term landing page
_igny8_term_faq                  -- JSON: [{question, answer}]
_igny8_term_related_terms        -- JSON: [term_id, term_id, ...]
_igny8_term_sag_attribute        -- string: attribute name from SAG
_igny8_term_sag_level            -- string: primary/secondary/tertiary
_igny8_term_cluster_id           -- int: linked SAGCluster ID
_igny8_term_igny8_id             -- int: ID in IGNY8 platform
_igny8_term_seo_title            -- string: SEO title for term archive
_igny8_term_meta_description     -- string: meta description for term archive
_igny8_term_robots_index         -- string: index/noindex
_igny8_term_og_image             -- int: OG image attachment ID

3. DATA MODELS & APIS

Database Table

The sync queue table is created by 03A's class-installer.php (table 6), used here:

{prefix}igny8_sync_queue

CREATE TABLE {prefix}igny8_sync_queue (
  id              BIGINT AUTO_INCREMENT PRIMARY KEY,
  igny8_content_id VARCHAR(100) NOT NULL,
  content_type    VARCHAR(50) NOT NULL,
  sync_status     VARCHAR(20) NOT NULL DEFAULT 'pending',
  wp_post_id      BIGINT NULL,
  wp_term_id      BIGINT NULL,
  data            LONGTEXT NULL,
  created_at      DATETIME NOT NULL,
  synced_at       DATETIME NULL,
  error_message   TEXT NULL,
  INDEX idx_status (sync_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Options (Connected Mode)

Option Key Purpose
igny8_api_key API key for IGNY8 SaaS (encrypted via wp_encrypt() or openssl)
igny8_api_connected Boolean — is connected mode active
igny8_api_url Base URL (default: https://api.igny8.com/api/v1/)
igny8_site_id IGNY8 Site record ID (integer)
igny8_last_sync ISO timestamp of last successful sync
igny8_sag_blueprint JSON: full blueprint data from IGNY8

API Client (class-api-client.php)

Outbound requests from WordPress to IGNY8 SaaS API:

Property Value
Base URL From igny8_api_url option (default: https://api.igny8.com/api/v1/)
Auth Header Authorization: Bearer {igny8_api_key}
Methods get($endpoint, $params), post($endpoint, $data), put($endpoint, $data), delete($endpoint)
Error Handling WP_Error wrapping, log failures via error_log()
Rate Limiting Respect 429 responses with exponential backoff (1s → 2s → 4s → 8s)
Connection Test GET /api/v1/system/status/

IGNY8 Backend Endpoints Consumed by Plugin:

GET  /api/v1/writer/content/?site_id=X&status=approved     -- content ready for sync
GET  /api/v1/writer/content/{id}/                           -- single content with HTML, images, taxonomy data
GET  /api/v1/planner/clusters/?site_id=X                    -- cluster data
GET  /api/v1/sag/blueprints/?site_id=X                      -- SAG blueprint (Phase 1)
POST /api/v1/integration/sync-events/                       -- log sync results
POST /api/v1/publishing/records/                            -- log publishing

REST Endpoints (Inbound from IGNY8)

All endpoints validate X-IGNY8-API-KEY header. Under /wp-json/igny8/v1/:

Method Endpoint Purpose Payload
POST /sync/push Content push from IGNY8 {igny8_content_id, content_type, title, content, excerpt, featured_image, meta: {...}}
POST /sag/sync-blueprint Blueprint sync {blueprint: {dimensions: [...], clusters: [...]}}
POST /sag/create-taxonomies Taxonomy creation {taxonomies: [{name, slug, hierarchical, post_types}]}
POST /terms/{id}/content Term content push {term_id, content, faq, related_terms, meta: {...}}
POST /schema/bulk-update Schema JSON-LD bulk push {schemas: [{post_id, schema_type, schema_data}]}
POST /gsc/status-sync GSC index statuses {statuses: [{url, index_status, coverage_state, last_checked}]}
POST /event Webhook events {event_type, data: {...}}

Endpoint Payload Examples

POST /sync/push:

{
  "igny8_content_id": 12345,
  "content_type": "post",
  "title": "Content Title",
  "content": "<p>HTML content...</p>",
  "excerpt": "Short excerpt",
  "featured_image": "https://cdn.igny8.com/image.jpg",
  "meta": {
    "focus_keyword": "main keyword",
    "secondary_keywords": ["kw2", "kw3"],
    "cluster_id": 123,
    "taxonomies": {
      "service_category": ["emergency-plumbing"],
      "cluster": ["drain-services"]
    }
  }
}

POST /sag/sync-blueprint:

{
  "blueprint": {
    "dimensions": [
      {
        "id": 1,
        "name": "Service Type",
        "slug": "service_type",
        "attributes": [
          {"id": 1, "name": "Emergency Plumbing", "slug": "emergency-plumbing"}
        ]
      }
    ],
    "clusters": [
      {
        "id": 1,
        "name": "Emergency Drain Cleaning",
        "dimension_ids": [1, 2],
        "hub_page_id": null,
        "recommended_content_count": 12
      }
    ]
  }
}

POST /terms/{id}/content:

{
  "term_id": 1001,
  "content": "<p>HTML content for term landing page</p>",
  "faq": [{"question": "Q1?", "answer": "A1"}],
  "related_terms": [1002, 1003],
  "meta": {
    "seo_title": "Custom title",
    "meta_description": "Custom description"
  }
}

POST /schema/bulk-update:

{
  "schemas": [
    {
      "post_id": 123,
      "schema_type": "Article",
      "schema_data": {"@context": "https://schema.org", "@type": "Article"}
    }
  ]
}

POST /gsc/status-sync:

{
  "statuses": [
    {
      "url": "https://example.com/post",
      "index_status": "Indexed",
      "coverage_state": "Submitted and indexed",
      "last_checked": "2026-03-22T12:00:00Z"
    }
  ]
}

4. IMPLEMENTATION STEPS

Admin UI Additions (Connected Mode)

When connected, two new submenus appear:

IGNY8 (top-level)
├── ... (all standalone modules from 03A)
├── Content Sync     — Sync queue, review queue, settings, sync log
└── SAG Structure    — Blueprint review, cluster manager, structure visualizer

Build Sequence

Phase 8: Content Sync Module (Days 21-24)

  1. Build IGNY8_Sync_Module — module entry, register REST endpoints
  2. Build IGNY8_Content_Mapper — content_type → post_type mapping table
  3. Build IGNY8_Image_Downloader — download remote images, create WP attachments
  4. Build IGNY8_Sync_Queue — queue management, status transitions
  5. Build IGNY8_Content_Puller — fetch content from IGNY8 API
  6. Build IGNY8_Publish_Scheduler — review queue UI, scheduled publishing
  7. Register WP Cron event: igny8_process_sync_queue (every 5 minutes)

Phase 9: SAG Structure Module (Days 25-27)

  1. Build IGNY8_SAG_Module — module entry, register REST endpoints
  2. Build IGNY8_Blueprint_Sync — receive, validate, store blueprint
  3. Build IGNY8_Taxonomy_Builderregister_taxonomy() from blueprint dimensions
  4. Build IGNY8_Term_Builderwp_insert_term() from attribute values
  5. Build IGNY8_Cluster_Manager — map clusters → hub pages
  6. Build IGNY8_Structure_Visualizer — admin page with visual site structure
  7. Build class-api-client.php — outbound IGNY8 API client with rate limiting

Security Considerations

  1. API Key Validation: Every inbound REST endpoint validates X-IGNY8-API-KEY header against stored igny8_api_key option using hash_equals() for timing-safe comparison
  2. Payload Sanitization: All incoming content HTML sanitized via wp_kses_post(). All text fields via sanitize_text_field(). All URLs via sanitize_url(). All integers via absint()
  3. API Key Storage: Encrypted at rest. Never exposed in admin UI after initial entry. Use wp_options with obfuscated display (****...last4)
  4. Rate Limiting: API client respects 429 responses. Exponential backoff: 1s → 2s → 4s → 8s max
  5. Nonce Bypass for REST: Inbound webhooks use API key auth, not nonce. WordPress REST permission callbacks enforce X-IGNY8-API-KEY validation

5. ACCEPTANCE CRITERIA

Content Sync (Module 11)

  • POST /wp-json/igny8/v1/sync/push receives content and creates sync queue entry
  • WP Cron processes sync queue — creates/updates WordPress posts
  • Content type mapping works for all 9 IGNY8 → WP type combinations
  • Images downloaded from IGNY8 CDN, created as WP attachments, set as featured
  • Post meta set: _igny8_content_id, _igny8_cluster_id, _igny8_sync_status
  • Taxonomy terms assigned via wp_set_object_terms()
  • Review mode: items land in review queue (status review) for manual approval
  • Auto-publish mode: items publish directly (status synced)
  • Confirmation callback POSTs to POST /api/v1/integration/sync-events/
  • Sync queue admin page shows all items with status, errors, retry button

SAG Structure (Module 12)

  • POST /wp-json/igny8/v1/sag/sync-blueprint receives and stores blueprint
  • Admin sees "Blueprint Review" notice after blueprint sync
  • "Approve Blueprint" creates taxonomies from SAG dimensions
  • Terms created from attribute values with correct hierarchy
  • Term meta set: _igny8_term_sag_attribute, _igny8_term_sag_level, _igny8_term_cluster_id
  • Clusters mapped to hub pages
  • POST /wp-json/igny8/v1/terms/{id}/content pushes rich content to term meta
  • POST /wp-json/igny8/v1/schema/bulk-update updates schema meta on posts
  • POST /wp-json/igny8/v1/gsc/status-sync updates GSC status display
  • Structure visualizer admin page renders site taxonomy/cluster hierarchy

API Client

  • Connection test via GET /api/v1/system/status/ returns success
  • All outbound requests include Authorization: Bearer {api_key} header
  • 429 responses trigger exponential backoff (1s → 2s → 4s → 8s)
  • Failed requests wrapped in WP_Error and logged

Security

  • All inbound REST endpoints validate X-IGNY8-API-KEY via hash_equals()
  • Incoming HTML sanitized via wp_kses_post()
  • API key stored encrypted, displayed as ****...last4 in admin
  • No API key exposed in client-side JavaScript or HTML source

6. CLAUDE CODE INSTRUCTIONS

Context Requirements

Before starting implementation:

  1. Read 03A (standalone plugin) — understand module manager, admin menu, DB tables
  2. Read existing WP Bridge v1.5.2 at /data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/
  3. Read 01A (SAG Data Foundation) for SAGBlueprint, SAGAttribute, SAGCluster models
  4. Read 01D (Setup Wizard) for blueprint generation flow that triggers sync
  5. Read 02B (Taxonomy Term Content) for term content that pushes via /terms/{id}/content
  6. Read 01G (SAG Health Monitoring) for health scoring context

Execution Order

Content Sync module (6 files) → SAG Structure module (6 files) → API Client → Admin UI views

Critical Rules

  1. All IGNY8 IDs are integersigny8_content_id, cluster_id, term_id are all integer (BigAutoField), never UUIDs
  2. IGNY8 model names are PLURAL — Clusters, Keywords, Tasks, ContentIdeas, Images, Content (stays singular)
  3. Connected modules only load when igny8_api_connected is true
  4. REST security — every inbound endpoint validates X-IGNY8-API-KEY with hash_equals()
  5. No blocking — all API calls and sync processing via WP Cron, never on page load
  6. Image downloads — use wp_remote_get() for fetching, wp_handle_sideload() for attachment creation
  7. Taxonomy registration — use register_taxonomy() with proper show_in_rest => true for block editor support
  8. Term creation — use wp_insert_term(), not direct DB insert

File Creation Order

1. includes/modules/content-sync/class-sync-module.php
2. includes/modules/content-sync/class-content-mapper.php
3. includes/modules/content-sync/class-image-downloader.php
4. includes/modules/content-sync/class-sync-queue.php
5. includes/modules/content-sync/class-content-puller.php
6. includes/modules/content-sync/class-publish-scheduler.php
7. includes/modules/sag/class-sag-module.php
8. includes/modules/sag/class-blueprint-sync.php
9. includes/modules/sag/class-taxonomy-builder.php
10. includes/modules/sag/class-term-builder.php
11. includes/modules/sag/class-cluster-manager.php
12. includes/modules/sag/class-structure-visualizer.php
13. includes/class-api-client.php
14. includes/admin/views/sync-queue.php
15. includes/admin/views/blueprint-review.php
16. includes/admin/views/structure-visualizer.php

Cross-References

Doc Relationship
03A WP Plugin Standalone Base plugin — module manager, DB tables, admin menu, igny8() singleton
01A SAG Data Foundation SAGBlueprint, SAGAttribute, SAGCluster models — data source for Module 12
01B SAG Blueprint Engine Blueprint generation that produces data synced to WordPress
01D Setup Wizard Blueprint generation triggers POST /sag/sync-blueprint to WordPress
01G SAG Health Monitoring Health scoring data available in connected mode intelligence module
02B Taxonomy Term Content Generates term content pushed via POST /terms/{id}/content
02C GSC Integration GSC metrics pushed via POST /gsc/status-sync
02D Linker Internal SAGLink data feeds connected mode auto-linker in Module 6
02G Rich Schema SERP Schema data pushed via POST /schema/bulk-update
02H Socializer SocialAccount OAuth feeds connected mode auto-poster in Module 8
03C Companion Theme Theme consumes blueprint data, term meta, cluster navigation