1
This commit is contained in:
487
v2/V2-Execution-Docs/03B-wp-plugin-connected.md
Normal file
487
v2/V2-Execution-Docs/03B-wp-plugin-connected.md
Normal file
@@ -0,0 +1,487 @@
|
||||
# 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`**
|
||||
```sql
|
||||
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`:**
|
||||
```json
|
||||
{
|
||||
"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`:**
|
||||
```json
|
||||
{
|
||||
"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`:**
|
||||
```json
|
||||
{
|
||||
"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`:**
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
{
|
||||
"post_id": 123,
|
||||
"schema_type": "Article",
|
||||
"schema_data": {"@context": "https://schema.org", "@type": "Article"}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**POST `/gsc/status-sync`:**
|
||||
```json
|
||||
{
|
||||
"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_Builder` — `register_taxonomy()` from blueprint dimensions
|
||||
4. Build `IGNY8_Term_Builder` — `wp_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 integers** — `igny8_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 |
|
||||
Reference in New Issue
Block a user