830 lines
25 KiB
Markdown
830 lines
25 KiB
Markdown
# Strategic Analysis & Implementation Plan
|
|
|
|
## Current State Assessment
|
|
|
|
### What Works Well
|
|
- **Unidirectional flow**: IGNY8 → WordPress (correct approach)
|
|
- **Comprehensive data mapping**: All fields documented
|
|
- **Multiple trigger points**: Manual + scheduled
|
|
- **API authentication**: Solid security model
|
|
- **Retry mechanism**: Celery handles failures
|
|
|
|
### What's Actually Broken/Missing
|
|
|
|
---
|
|
|
|
## Critical Gaps (Real Functional Issues)
|
|
|
|
### **GAP 1: Incomplete Data Transfer**
|
|
**Problem**: The audit shows fields are mapped, but doesn't confirm ALL data actually transfers in one atomic operation.
|
|
|
|
**Current Risk**:
|
|
- Featured image might fail → rest of content publishes anyway
|
|
- Gallery images fail → content published without visuals
|
|
- SEO meta fails → content has no SEO optimization
|
|
- Categories fail to create → content published orphaned
|
|
- Sectors/clusters fail → no IGNY8 relationship tracking
|
|
|
|
**What's Missing**:
|
|
- **Pre-flight validation** before starting publish
|
|
- **Atomic transaction pattern** (all-or-nothing)
|
|
- **Dependency chain verification** (e.g., author must exist before publishing)
|
|
- **Rollback on partial failure**
|
|
|
|
---
|
|
|
|
### **GAP 2: No Publish Count Tracking Back to IGNY8**
|
|
**Problem**: You stated requirement #4 isn't implemented anywhere in the audit.
|
|
|
|
**What's Missing**:
|
|
- After successful WordPress publish, WordPress must call IGNY8 API to increment:
|
|
- `post_publish_count` for posts
|
|
- `page_publish_count` for pages
|
|
- `product_publish_count` for products
|
|
- `taxonomy_sync_count` for categories/tags/sectors/clusters
|
|
|
|
**Current State**:
|
|
- WordPress reports back `assigned_post_id` and `post_url`
|
|
- WordPress does NOT report back publish counts or content type statistics
|
|
|
|
**Impact**: IGNY8 dashboard shows incomplete/wrong statistics
|
|
|
|
---
|
|
|
|
### **GAP 3: Taxonomy Sync Doesn't Track Changes**
|
|
**Problem**: You need to track if categories/tags/clusters change in WordPress, but current system doesn't.
|
|
|
|
**Current Flow**:
|
|
1. IGNY8 sends: `categories: ["SEO", "Marketing"]`
|
|
2. WordPress creates/assigns these
|
|
3. **If user later adds "Content Strategy" in WordPress** → IGNY8 never knows
|
|
4. **If user removes "Marketing"** → IGNY8 never knows
|
|
|
|
**What's Missing**:
|
|
- WordPress hook to detect taxonomy changes on IGNY8-managed posts
|
|
- API call to IGNY8 to update taxonomy associations
|
|
- Endpoint in IGNY8 to receive taxonomy change notifications
|
|
|
|
---
|
|
|
|
### **GAP 4: Cluster/Sector/Keyword Changes Not Synced**
|
|
**Problem**: Similar to taxonomy gap but for IGNY8-specific relationships.
|
|
|
|
**Scenario**:
|
|
- Content published with `cluster_id: 12`
|
|
- User changes in WordPress to `cluster_id: 15` via custom field
|
|
- IGNY8 still thinks content belongs to cluster 12
|
|
- Cluster 12 shows wrong content count
|
|
- Cluster 15 missing content in its list
|
|
|
|
**What's Missing**:
|
|
- Detection mechanism for meta field changes on `_igny8_cluster_id`, `_igny8_sector_id`, `_igny8_keyword_ids`
|
|
- Sync back to IGNY8 to update relationships
|
|
- IGNY8 API endpoints to handle relationship updates
|
|
|
|
---
|
|
|
|
### **GAP 5: Manual vs Auto-Publish Flow Not Distinguished**
|
|
**Problem**: Both flows use same code path, but they need different handling.
|
|
|
|
**Manual Publish (Button Click)**:
|
|
- Should publish **immediately**
|
|
- User expects instant feedback
|
|
- Should override any scheduling
|
|
- Should force re-publish if already published
|
|
|
|
**Auto-Publish/Schedule**:
|
|
- Should respect `published_at` timestamp
|
|
- Should not override manual edits in WordPress
|
|
- Should skip if already published (idempotent)
|
|
- Should handle timezone conversions
|
|
|
|
**What's Missing**:
|
|
- `publish_mode` flag in API payload (`manual` vs `scheduled`)
|
|
- Different retry strategies for each mode
|
|
- Different status reporting for each mode
|
|
- Override logic for manual re-publish
|
|
|
|
---
|
|
|
|
### **GAP 6: No Verification After Publish**
|
|
**Problem**: WordPress reports "success" but doesn't verify the content is actually viewable/accessible.
|
|
|
|
**Failure Scenarios Not Caught**:
|
|
- Post published but permalink returns 404 (rewrite rules not flushed)
|
|
- Featured image attached but file doesn't exist (upload failed silently)
|
|
- Categories created but not assigned (database transaction partial commit)
|
|
- SEO meta saved but plugin not active (meta stored but not used)
|
|
|
|
**What's Missing**:
|
|
- Post-publish verification step
|
|
- Check permalink returns 200
|
|
- Verify featured image URL accessible
|
|
- Verify taxonomies actually assigned (count > 0)
|
|
- Report verification results to IGNY8
|
|
|
|
---
|
|
|
|
### **GAP 7: Schedule Publishing Timezone Issues**
|
|
**Problem**: IGNY8 sends UTC timestamp, WordPress stores in site timezone, confusion inevitable.
|
|
|
|
**Scenario**:
|
|
- IGNY8 schedules for "2025-12-01 10:00:00 UTC"
|
|
- WordPress site timezone is "America/New_York" (UTC-5)
|
|
- WordPress interprets as 10:00 AM New York time
|
|
- Content publishes 5 hours later than intended
|
|
|
|
**What's Missing**:
|
|
- Explicit timezone handling in payload
|
|
- Timezone conversion logic in WordPress
|
|
- Verification that scheduled time matches intent
|
|
|
|
---
|
|
|
|
### **GAP 8: All-or-Nothing Guarantees Missing**
|
|
**Problem**: Content can be half-published (post exists but missing images/meta).
|
|
|
|
**Current Flow**:
|
|
```
|
|
1. wp_insert_post() → Success (post ID 1842)
|
|
2. Download featured image → FAILS
|
|
3. Assign categories → Success
|
|
4. Store SEO meta → Success
|
|
5. Report success to IGNY8 ✓
|
|
|
|
Result: Post published without featured image
|
|
IGNY8 thinks everything succeeded
|
|
```
|
|
|
|
**What's Missing**:
|
|
- Transaction wrapper around entire publish operation
|
|
- Failure detection for each sub-operation
|
|
- Rollback mechanism if any step fails
|
|
- Detailed error reporting (which step failed)
|
|
|
|
---
|
|
|
|
### **GAP 9: No Re-Publish Protection**
|
|
**Problem**: If publish button clicked twice or Celery task runs twice, content duplicates.
|
|
|
|
**Scenario**:
|
|
1. User clicks "Publish" in IGNY8
|
|
2. Celery task queued
|
|
3. User clicks "Publish" again (impatient)
|
|
4. Second Celery task queued
|
|
5. Both tasks run → **2 WordPress posts created for same content**
|
|
|
|
**What's Missing**:
|
|
- Task deduplication based on `content_id` + `site_integration_id`
|
|
- Lock mechanism during publish
|
|
- WordPress duplicate detection by `_igny8_content_id` before creating new post
|
|
- Return existing post if already published (idempotent operation)
|
|
|
|
---
|
|
|
|
### **GAP 10: Publish Count Statistics Incomplete**
|
|
**Problem**: You need counts by content type, but current system doesn't track this granularly.
|
|
|
|
**What IGNY8 Needs**:
|
|
```python
|
|
class SiteIntegration(models.Model):
|
|
# Current (missing):
|
|
posts_published_count = models.IntegerField(default=0)
|
|
pages_published_count = models.IntegerField(default=0)
|
|
products_published_count = models.IntegerField(default=0)
|
|
|
|
# Also need:
|
|
categories_synced_count = models.IntegerField(default=0)
|
|
tags_synced_count = models.IntegerField(default=0)
|
|
sectors_synced_count = models.IntegerField(default=0)
|
|
clusters_synced_count = models.IntegerField(default=0)
|
|
|
|
last_publish_at = models.DateTimeField(null=True)
|
|
total_sync_operations = models.IntegerField(default=0)
|
|
```
|
|
|
|
**What's Missing**:
|
|
- WordPress needs to detect content type (post/page/product) and report it
|
|
- WordPress needs to count new vs updated taxonomies and report
|
|
- IGNY8 needs endpoints to receive these counts
|
|
- Dashboard needs to display these statistics
|
|
|
|
---
|
|
|
|
### **GAP 11: Auto-Publish Scheduling Mechanism Unclear**
|
|
**Problem**: Audit shows Celery runs every 5 minutes, but doesn't explain how scheduled publishing works.
|
|
|
|
**Questions Unanswered**:
|
|
- If `published_at` is in future, does Celery skip it?
|
|
- How does Celery know when to publish scheduled content?
|
|
- Is there a separate queue for scheduled vs immediate?
|
|
- What if scheduled time is missed (server down)?
|
|
|
|
**What's Likely Missing**:
|
|
- Scheduled content query filter in Celery task
|
|
- Time-based condition: `published_at <= now()`
|
|
- Missed schedule handler (publish immediately if past due)
|
|
- Different retry logic for scheduled vs immediate
|
|
|
|
---
|
|
|
|
### **GAP 12: Taxonomy Creation vs Assignment Not Clear**
|
|
**Problem**: If category "Digital Marketing" doesn't exist in WordPress, what happens?
|
|
|
|
**Scenario 1: Auto-Create** (probably current):
|
|
- WordPress creates category "Digital Marketing"
|
|
- Assigns to post
|
|
- **Problem**: Might create duplicates if slug differs ("digital-marketing" vs "digitalmarketing")
|
|
|
|
**Scenario 2: Map to Existing**:
|
|
- WordPress looks up by name
|
|
- If not found, uses fallback category
|
|
- **Problem**: User needs to pre-create all categories
|
|
|
|
**What's Missing**:
|
|
- Clear taxonomy reconciliation strategy
|
|
- Slug normalization rules
|
|
- Duplicate prevention logic
|
|
- Fallback category configuration
|
|
|
|
---
|
|
|
|
### **GAP 13: Keywords Not Actually Published**
|
|
**Problem**: Audit shows `focus_keywords` stored in meta, but WordPress doesn't use this field natively.
|
|
|
|
**Current State**:
|
|
- IGNY8 sends: `focus_keywords: ["SEO 2025", "ranking factors"]`
|
|
- WordPress stores: `_igny8_focus_keywords` meta
|
|
- **Nobody reads this field** (unless custom code added)
|
|
|
|
**What's Missing**:
|
|
- Integration with actual keyword tracking plugins (Yoast, RankMath, AIOSEO)
|
|
- Mapping to plugin-specific meta fields
|
|
- Fallback if no SEO plugin installed
|
|
|
|
---
|
|
|
|
### **GAP 14: Gallery Images Limit Arbitrary**
|
|
**Problem**: Audit mentions "5 images max" for gallery but doesn't explain why or what happens to 6th image.
|
|
|
|
**Questions**:
|
|
- Is this IGNY8 limit or WordPress plugin limit?
|
|
- What happens if IGNY8 sends 10 images?
|
|
- Are they silently dropped? Error thrown?
|
|
- How does user know some images were skipped?
|
|
|
|
**What's Missing**:
|
|
- Configurable gallery size limit
|
|
- Clear error message if limit exceeded
|
|
- Option to create separate gallery post/page for overflow
|
|
|
|
---
|
|
|
|
## Implementation Plan (No Code)
|
|
|
|
### **Phase 1: Fix Critical Data Integrity Issues** (Week 1-2)
|
|
|
|
#### 1.1 Implement Atomic Transaction Pattern
|
|
- Wrap entire publish operation in WordPress transaction
|
|
- If ANY step fails → rollback everything
|
|
- Delete post if created but subsequent operations failed
|
|
- Report detailed failure info to IGNY8 (which step failed)
|
|
|
|
#### 1.2 Add Pre-Flight Validation
|
|
Before attempting publish:
|
|
- Verify author exists (by email)
|
|
- Verify all image URLs accessible (HTTP HEAD request)
|
|
- Verify required fields present (title, content)
|
|
- Verify post type enabled in WordPress plugin settings
|
|
- Return validation errors BEFORE creating anything
|
|
|
|
#### 1.3 Implement Duplicate Prevention
|
|
- Check if post with `_igny8_content_id` already exists
|
|
- If exists → update instead of create (unless manual re-publish)
|
|
- Add unique constraint in IGNY8: `(content_id, site_integration_id)` → only one publish task active at a time
|
|
- Celery task deduplication by task signature
|
|
|
|
#### 1.4 Add Post-Publish Verification
|
|
After WordPress reports "success":
|
|
- Wait 5 seconds (let WordPress flush rewrites)
|
|
- HTTP GET the permalink → expect 200
|
|
- HTTP HEAD the featured image URL → expect 200
|
|
- Query taxonomies assigned → expect count > 0
|
|
- If verification fails → mark as "published_with_issues" status
|
|
- Report verification results to IGNY8
|
|
|
|
---
|
|
|
|
### **Phase 2: Implement Publish Count Tracking** (Week 2-3)
|
|
|
|
#### 2.1 Extend IGNY8 Models
|
|
Add to `SiteIntegration`:
|
|
- `posts_published_count`
|
|
- `pages_published_count`
|
|
- `products_published_count`
|
|
- `categories_synced_count`
|
|
- `tags_synced_count`
|
|
- `sectors_synced_count`
|
|
- `clusters_synced_count`
|
|
- `last_publish_at`
|
|
- `total_sync_operations`
|
|
|
|
#### 2.2 Create IGNY8 Stats Endpoint
|
|
```
|
|
PUT /integrations/{site_id}/stats/increment/
|
|
Payload: {
|
|
"content_type": "post", // or "page", "product"
|
|
"taxonomies_created": {
|
|
"categories": 2,
|
|
"tags": 5,
|
|
"sectors": 1,
|
|
"clusters": 1
|
|
},
|
|
"taxonomies_updated": {
|
|
"categories": 0,
|
|
"tags": 1,
|
|
"sectors": 0,
|
|
"clusters": 0
|
|
},
|
|
"published_at": "2025-11-29T10:15:30Z"
|
|
}
|
|
```
|
|
|
|
#### 2.3 Update WordPress Plugin Response
|
|
After successful publish, WordPress must:
|
|
- Detect post type (post/page/product)
|
|
- Count new categories created vs existing assigned
|
|
- Count new tags created vs existing assigned
|
|
- Count new sectors created vs existing assigned
|
|
- Count new clusters created vs existing assigned
|
|
- Call IGNY8 stats endpoint with all counts
|
|
- IGNY8 increments counters atomically
|
|
|
|
---
|
|
|
|
### **Phase 3: Implement Taxonomy Change Tracking** (Week 3-4)
|
|
|
|
#### 3.1 Add WordPress Hooks
|
|
Hook into:
|
|
- `set_object_terms` (when taxonomies assigned/changed)
|
|
- `update_post_meta` (when cluster/sector/keyword meta changed)
|
|
- Filter by: post has `_igny8_task_id` meta (only track IGNY8-managed posts)
|
|
|
|
#### 3.2 Create IGNY8 Taxonomy Update Endpoint
|
|
```
|
|
PUT /writer/tasks/{task_id}/taxonomies/
|
|
Payload: {
|
|
"categories": [1, 2, 3], // WordPress term IDs
|
|
"tags": [5, 8, 12],
|
|
"sectors": [2],
|
|
"clusters": [7, 9],
|
|
"updated_by": "wordpress_user_123",
|
|
"updated_at": "2025-11-29T11:00:00Z"
|
|
}
|
|
```
|
|
|
|
#### 3.3 Create IGNY8 Relationships Update Endpoint
|
|
```
|
|
PUT /writer/tasks/{task_id}/relationships/
|
|
Payload: {
|
|
"cluster_id": 15, // changed from 12
|
|
"sector_id": 5, // unchanged
|
|
"keyword_ids": [1, 2, 3, 8], // added keyword 8
|
|
"updated_by": "wordpress_user_123",
|
|
"updated_at": "2025-11-29T11:00:00Z"
|
|
}
|
|
```
|
|
|
|
#### 3.4 Implement Debouncing
|
|
- Don't sync every single taxonomy change immediately
|
|
- Batch changes over 30-second window
|
|
- Send one API call with all changes
|
|
- Reduce API call volume by 95%
|
|
|
|
---
|
|
|
|
### **Phase 4: Separate Manual vs Auto-Publish Flows** (Week 4-5)
|
|
|
|
#### 4.1 Add `publish_mode` to API Payload
|
|
IGNY8 must send:
|
|
```json
|
|
{
|
|
"content_id": 42,
|
|
"publish_mode": "manual", // or "scheduled"
|
|
"published_at": "2025-12-01T10:00:00Z",
|
|
...
|
|
}
|
|
```
|
|
|
|
#### 4.2 Implement Different Logic
|
|
|
|
**Manual Mode**:
|
|
- Ignore `published_at` timestamp (publish NOW)
|
|
- If post already exists → force update (don't skip)
|
|
- Return immediate feedback (synchronous within 5 seconds)
|
|
- Retry aggressively (3 retries, 10 seconds apart)
|
|
- Show user real-time progress
|
|
|
|
**Scheduled Mode**:
|
|
- Respect `published_at` timestamp
|
|
- If post already exists → skip (idempotent)
|
|
- Queue for future execution
|
|
- Retry conservatively (3 retries, 1 hour apart)
|
|
- Don't notify user of each retry
|
|
|
|
#### 4.3 Update Celery Task Query
|
|
```python
|
|
# Current: publishes everything with status='completed'
|
|
pending_content = ContentPost.objects.filter(
|
|
wordpress_sync_status='pending',
|
|
published_at__isnull=False
|
|
)
|
|
|
|
# New: separate scheduled from immediate
|
|
immediate_content = ContentPost.objects.filter(
|
|
wordpress_sync_status='pending',
|
|
publish_mode='manual',
|
|
published_at__isnull=False
|
|
)
|
|
|
|
scheduled_content = ContentPost.objects.filter(
|
|
wordpress_sync_status='pending',
|
|
publish_mode='scheduled',
|
|
published_at__lte=now(), # only if scheduled time reached
|
|
published_at__isnull=False
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### **Phase 5: Timezone Handling** (Week 5)
|
|
|
|
#### 5.1 Standardize on UTC Everywhere
|
|
- IGNY8 always sends timestamps in UTC with explicit timezone: `"2025-12-01T10:00:00Z"`
|
|
- WordPress plugin converts to site timezone for `post_date`
|
|
- WordPress converts back to UTC when reporting to IGNY8
|
|
- Never rely on implied timezones
|
|
|
|
#### 5.2 Add Timezone to WordPress Response
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"post_id": 1842,
|
|
"post_date_utc": "2025-11-29T10:15:30Z",
|
|
"post_date_site": "2025-11-29T05:15:30-05:00",
|
|
"site_timezone": "America/New_York"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 5.3 Scheduled Publish Verification
|
|
- IGNY8 stores: "Scheduled for 2025-12-01 10:00 UTC"
|
|
- WordPress publishes at: "2025-12-01 05:00 EST" (correct)
|
|
- WordPress reports back: "Published at 2025-12-01T10:00:00Z" (UTC)
|
|
- IGNY8 verifies timestamp matches expected
|
|
|
|
---
|
|
|
|
### **Phase 6: Enhanced Error Reporting** (Week 6)
|
|
|
|
#### 6.1 Add Detailed Error Structure
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": {
|
|
"code": "FEATURED_IMAGE_DOWNLOAD_FAILED",
|
|
"message": "Failed to download featured image",
|
|
"step": "media_processing",
|
|
"step_number": 3,
|
|
"total_steps": 7,
|
|
"details": {
|
|
"image_url": "https://example.com/image.jpg",
|
|
"http_status": 404,
|
|
"error": "Not Found"
|
|
},
|
|
"recoverable": true,
|
|
"retry_recommended": true
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 6.2 Add Progress Reporting for Manual Publish
|
|
For manual publish, send progress updates:
|
|
```
|
|
POST /integrations/{site_id}/publish-progress/
|
|
{
|
|
"task_id": 15,
|
|
"step": "creating_post",
|
|
"progress": 30,
|
|
"message": "Creating WordPress post..."
|
|
}
|
|
```
|
|
|
|
Frontend shows real-time progress bar.
|
|
|
|
---
|
|
|
|
### **Phase 7: Taxonomy Reconciliation Strategy** (Week 6-7)
|
|
|
|
#### 7.1 Add Taxonomy Mapping Configuration
|
|
WordPress plugin settings:
|
|
- **Auto-create missing taxonomies**: ON/OFF
|
|
- **Slug normalization**: lowercase + hyphens
|
|
- **Duplicate detection**: by slug (not name)
|
|
- **Fallback category**: "Uncategorized" (if auto-create OFF and category not found)
|
|
|
|
#### 7.2 Taxonomy Reconciliation Algorithm
|
|
```
|
|
For each category in IGNY8 payload:
|
|
1. Normalize slug: "Digital Marketing" → "digital-marketing"
|
|
2. Query WordPress by slug (not name)
|
|
3. If found → use existing term ID
|
|
4. If not found:
|
|
a. If auto-create ON → create new term
|
|
b. If auto-create OFF → use fallback category
|
|
5. Assign term to post
|
|
```
|
|
|
|
#### 7.3 Report Taxonomy Changes to IGNY8
|
|
```json
|
|
{
|
|
"taxonomies_processed": {
|
|
"categories": {
|
|
"requested": ["Digital Marketing", "SEO"],
|
|
"created": ["SEO"],
|
|
"existing": ["Digital Marketing"],
|
|
"assigned": [1, 5]
|
|
},
|
|
"tags": {
|
|
"requested": ["seo", "ranking"],
|
|
"created": [],
|
|
"existing": ["seo", "ranking"],
|
|
"assigned": [8, 12]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### **Phase 8: SEO Plugin Integration** (Week 7-8)
|
|
|
|
#### 8.1 Detect Active SEO Plugin
|
|
WordPress plugin detects:
|
|
- Yoast SEO
|
|
- Rank Math
|
|
- All in One SEO
|
|
- SEOPress
|
|
- (or none)
|
|
|
|
#### 8.2 Map Focus Keywords to Plugin Fields
|
|
|
|
**Yoast SEO**:
|
|
- `_yoast_wpseo_focuskw` = first keyword
|
|
- `_yoast_wpseo_keywordsynonyms` = remaining keywords (comma-separated)
|
|
|
|
**Rank Math**:
|
|
- `rank_math_focus_keyword` = first keyword
|
|
- Additional keywords stored in JSON meta
|
|
|
|
**All in One SEO**:
|
|
- `_aioseo_keywords` = comma-separated list
|
|
|
|
**No Plugin**:
|
|
- Store in `_igny8_focus_keywords` (current behavior)
|
|
- Optional: Generate simple meta keywords tag
|
|
|
|
#### 8.3 Report SEO Plugin Status to IGNY8
|
|
```json
|
|
{
|
|
"seo_plugin": {
|
|
"active": "yoast",
|
|
"version": "22.0",
|
|
"keywords_supported": true,
|
|
"focus_keyword_set": true
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### **Phase 9: Gallery Image Handling** (Week 8)
|
|
|
|
#### 9.1 Make Gallery Limit Configurable
|
|
WordPress plugin settings:
|
|
- **Max gallery images**: 5 (default)
|
|
- **Overflow behavior**:
|
|
- "Skip extra images" (current)
|
|
- "Create separate gallery post"
|
|
- "Add to post content as image grid"
|
|
|
|
#### 9.2 Handle Overflow Images
|
|
If IGNY8 sends 10 images but limit is 5:
|
|
|
|
**Option A: Skip**:
|
|
- Use first 5
|
|
- Report to IGNY8: `"gallery_images_skipped": 5`
|
|
|
|
**Option B: Create Separate Post**:
|
|
- Create new post: "{Original Title} - Gallery"
|
|
- Attach images 6-10
|
|
- Link from original post
|
|
- Report to IGNY8: `"gallery_overflow_post_id": 1843`
|
|
|
|
**Option C: Inline Grid**:
|
|
- Append HTML grid to post content
|
|
- All 10 images in post body
|
|
- Report to IGNY8: `"gallery_images_inline": 10`
|
|
|
|
---
|
|
|
|
### **Phase 10: Monitoring & Dashboard** (Week 9)
|
|
|
|
#### 10.1 IGNY8 Dashboard Enhancements
|
|
Display per site:
|
|
- **Total Published**: Posts (X) | Pages (Y) | Products (Z)
|
|
- **Taxonomies Synced**: Categories (A) | Tags (B) | Sectors (C) | Clusters (D)
|
|
- **Last Published**: 2 hours ago
|
|
- **Publish Success Rate**: 98.5% (last 30 days)
|
|
- **Average Publish Time**: 3.2 seconds
|
|
- **Pending**: 5 scheduled for today
|
|
|
|
#### 10.2 WordPress Plugin Dashboard
|
|
Display:
|
|
- **IGNY8 Posts**: 142 published | 5 pending
|
|
- **Last Sync**: 10 minutes ago
|
|
- **Connection Status**: Connected ✓
|
|
- **Recent Activity**:
|
|
- 10:15 AM - Published "SEO Guide 2025" (post)
|
|
- 10:05 AM - Published "About Us" (page)
|
|
- 09:50 AM - Synced 3 categories
|
|
|
|
#### 10.3 Add Health Check Endpoint
|
|
```
|
|
GET /wp-json/igny8/v1/health
|
|
Response:
|
|
{
|
|
"status": "healthy",
|
|
"checks": {
|
|
"api_connection": "ok",
|
|
"database": "ok",
|
|
"media_uploads": "ok",
|
|
"taxonomy_creation": "ok"
|
|
},
|
|
"stats": {
|
|
"posts_managed": 142,
|
|
"last_publish": "2025-11-29T10:15:30Z",
|
|
"disk_space": "15GB free"
|
|
}
|
|
}
|
|
```
|
|
|
|
Call from IGNY8 every 5 minutes to detect issues early.
|
|
|
|
---
|
|
|
|
## Summary: What Actually Needs to Change
|
|
|
|
### **Backend (IGNY8 Django)** Changes:
|
|
|
|
1. **Add Models Fields**:
|
|
- `publish_mode` to ContentPost ('manual' or 'scheduled')
|
|
- Publish count fields to SiteIntegration
|
|
- Taxonomy sync count fields
|
|
|
|
2. **Add API Endpoints**:
|
|
- `PUT /integrations/{id}/stats/increment/` (receive counts from WP)
|
|
- `PUT /writer/tasks/{id}/taxonomies/` (receive taxonomy changes from WP)
|
|
- `PUT /writer/tasks/{id}/relationships/` (receive cluster/sector changes from WP)
|
|
|
|
3. **Update Celery Task**:
|
|
- Add pre-flight validation
|
|
- Separate scheduled vs manual queries
|
|
- Add duplicate prevention
|
|
- Add timezone handling
|
|
- Improve error reporting
|
|
|
|
4. **Update API Call to WordPress**:
|
|
- Send `publish_mode` flag
|
|
- Send explicit UTC timezone
|
|
- Handle detailed error responses
|
|
- Process verification results
|
|
|
|
---
|
|
|
|
### **Frontend (IGNY8 Vue/React)** Changes:
|
|
|
|
1. **Manual Publish Button**:
|
|
- Show real-time progress (if WordPress sends updates)
|
|
- Show detailed success message with link to WP post
|
|
- Show detailed error message if fails (which step failed)
|
|
|
|
2. **Dashboard Stats**:
|
|
- Display publish counts by content type
|
|
- Display taxonomy sync counts
|
|
- Display last publish timestamp
|
|
- Display success rate graph
|
|
|
|
3. **Scheduled Publish UI**:
|
|
- Datetime picker with timezone display
|
|
- "Schedule for: Dec 1, 2025 10:00 AM UTC (5:00 AM your time)"
|
|
- List of scheduled publications
|
|
- Ability to cancel scheduled publish
|
|
|
|
---
|
|
|
|
### **WordPress Plugin** Changes:
|
|
|
|
1. **Core Publish Function**:
|
|
- Wrap in transaction (all-or-nothing)
|
|
- Add pre-flight validation
|
|
- Add duplicate detection
|
|
- Add post-publish verification
|
|
- Handle `publish_mode` flag differently
|
|
|
|
2. **Add Taxonomy Hooks**:
|
|
- Detect changes to categories/tags/sectors/clusters
|
|
- Batch changes over 30 seconds
|
|
- Call IGNY8 API to sync changes
|
|
|
|
3. **Add Stats Tracking**:
|
|
- Count content types published
|
|
- Count taxonomies created vs assigned
|
|
- Call IGNY8 stats endpoint after each publish
|
|
|
|
4. **Settings Page**:
|
|
- Taxonomy auto-create ON/OFF
|
|
- Taxonomy fallback category selector
|
|
- Gallery image limit (slider: 1-20)
|
|
- Gallery overflow behavior (dropdown)
|
|
- SEO plugin integration status
|
|
|
|
5. **Response Format**:
|
|
- Add verification results
|
|
- Add taxonomy processing details
|
|
- Add publish counts
|
|
- Add timezone info
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
### 1. **Atomic Transaction Tests**
|
|
- Publish with invalid image URL → entire operation should fail, no post created
|
|
- Publish with invalid author → entire operation should fail
|
|
- Publish with SEO plugin disabled → post created, SEO meta stored anyway
|
|
|
|
### 2. **Duplicate Prevention Tests**
|
|
- Click publish button twice rapidly → only 1 post created
|
|
- Celery task runs while manual publish in progress → only 1 post created
|
|
- Re-publish same content → update existing post, don't create new
|
|
|
|
### 3. **Timezone Tests**
|
|
- Schedule for "Dec 1, 2025 10:00 UTC" from timezone UTC+5 → publishes at correct time
|
|
- WordPress in timezone "America/New_York" → post_date stored correctly in local time
|
|
- IGNY8 receives post_date_utc → matches scheduled time exactly
|
|
|
|
### 4. **Taxonomy Sync Tests**
|
|
- Add category in WordPress → IGNY8 receives update within 30 seconds
|
|
- Remove tag in WordPress → IGNY8 receives update
|
|
- Change cluster via custom field → IGNY8 receives update
|
|
- Change multiple taxonomies at once → IGNY8 receives 1 batched update
|
|
|
|
### 5. **Count Tracking Tests**
|
|
- Publish 1 post → SiteIntegration.posts_published_count increments by 1
|
|
- Publish 1 page → SiteIntegration.pages_published_count increments by 1
|
|
- Create 2 new categories → SiteIntegration.categories_synced_count increments by 2
|
|
- Update post (no new taxonomies) → counts don't change
|
|
|
|
### 6. **Manual vs Scheduled Tests**
|
|
- Manual publish → immediate execution, ignores published_at
|
|
- Scheduled publish → waits until published_at time
|
|
- Manual re-publish of scheduled content → publishes immediately, overrides schedule
|
|
|
|
---
|
|
|
|
## Implementation Priority
|
|
|
|
### **Critical (Do First)**:
|
|
1. Atomic transactions (Phase 1.1)
|
|
2. Duplicate prevention (Phase 1.3)
|
|
3. Publish count tracking (Phase 2)
|
|
4. Manual vs scheduled separation (Phase 4)
|
|
|
|
### **High Priority**:
|
|
5. Timezone handling (Phase 5)
|
|
6. Taxonomy change tracking (Phase 3)
|
|
7. Enhanced error reporting (Phase 6)
|
|
|
|
### **Medium Priority**:
|
|
8. Taxonomy reconciliation (Phase 7)
|
|
9. SEO plugin integration (Phase 8)
|
|
10. Gallery improvements (Phase 9)
|
|
|
|
### **Low Priority**:
|
|
11. Dashboard enhancements (Phase 10)
|
|
|
|
---
|
|
|
|
This plan focuses on **real functional gaps** that affect data integrity, user experience, and system reliability. No cosmetics, just critical infrastructure improvements. |