diff --git a/docs/plans/final-dev-guides-of-futute-implementation/DocA-SAG-Architecture-Dev-Guide.md b/docs/plans/final-dev-guides-of-futute-implementation/DocA-SAG-Architecture-Dev-Guide.md new file mode 100644 index 00000000..46d2f196 --- /dev/null +++ b/docs/plans/final-dev-guides-of-futute-implementation/DocA-SAG-Architecture-Dev-Guide.md @@ -0,0 +1,1789 @@ +# Doc A — SAG Architecture: Development Guide for Claude Code + +**Version:** 1.0 +**Date:** March 2026 +**For:** Claude Code (Opus 4.6) in VSCode on IGNY8 repo +**Purpose:** Step-by-step implementation guide for all SAG architecture features — where every file goes, what models to create or modify, what the frontend shows, how automation works +**Scope:** SAG Core (3-layer architecture, Site Builder, Existing Site Intelligence), Interlinking (Doc 3 / Linker module), External Backlink Campaigns (Doc 4), Industry/Sector Templates +**Rule:** Nothing currently working breaks. All new models use nullable fields on existing tables. All new modules use feature flags. All new frontend pages use the existing sidebar/routing pattern. + +--- + +## Table of Contents + +1. [System Context — What Exists Today](#1-system-context) +2. [Implementation Sequence — The Critical Path](#2-implementation-sequence) +3. [Phase 1: Data Foundation — New Models](#3-phase-1-data-foundation) +4. [Phase 2: Sector Attribute Templates](#4-phase-2-sector-attribute-templates) +5. [Phase 3: Cluster Formation & Keyword Generation Engine](#5-phase-3-cluster-formation--keyword-generation) +6. [Phase 4: Case 2 — SAG Site Builder Wizard](#6-phase-4-sag-site-builder-wizard) +7. [Phase 5: Blueprint-Aware Content Pipeline](#7-phase-5-blueprint-aware-content-pipeline) +8. [Phase 6: Taxonomy Creation Flow](#8-phase-6-taxonomy-creation-flow) +9. [Phase 7: Case 1 — Existing Site Analysis](#9-phase-7-existing-site-analysis) +10. [Phase 8: Blueprint Health Monitoring](#10-phase-8-blueprint-health-monitoring) +11. [Phase 9: SAG Interlinking — Linker Module Evolution](#11-phase-9-sag-interlinking) +12. [Phase 10: External Backlink Campaign Module](#12-phase-10-external-backlink-campaigns) +13. [Frontend Navigation & UI Map](#13-frontend-navigation--ui-map) +14. [API Endpoint Registry](#14-api-endpoint-registry) +15. [AI Function Registry](#15-ai-function-registry) +16. [Celery Task Registry](#16-celery-task-registry) +17. [Feature Flag Registry](#17-feature-flag-registry) +18. [Cross-Reference: What Feeds What](#18-cross-reference) + +--- + +## 1. System Context — What Exists Today {#1-system-context} + +Before building anything, understand the current codebase layout that MUST be preserved. + +### 1.1 Backend File Structure (Django) + +``` +backend/igny8_core/ +├── auth/ # User, Account, Site, Sector, Plan models + auth views +│ ├── models.py # Site model lives here — will get sag_blueprint_id field +│ └── ... +├── api/ # Base ViewSets, authentication, pagination +├── ai/ # AI engine — will get new SAG functions +│ ├── engine.py # AIEngine orchestrator +│ ├── functions/ # AutoCluster, GenerateIdeas, GenerateContent, etc. +│ ├── providers/ # OpenAI, Anthropic, Runware, Bria +│ ├── registry.py # Function registry +│ └── model_registry.py # ModelRegistry service +├── modules/ # API layer — ViewSets, serializers, URLs per module +│ ├── planner/ # Keywords, Clusters, Ideas +│ ├── writer/ # Tasks, Content, Images +│ ├── billing/ # Credits, usage +│ ├── integration/ # WordPress integration +│ ├── system/ # Settings, prompts, AI config +│ ├── linker/ # Internal linking (INACTIVE — behind linker_enabled flag) +│ ├── optimizer/ # Content optimization (INACTIVE) +│ └── publisher/ # Publishing pipeline +├── business/ # Service layer — business logic +│ ├── automation/ # 7-stage automation pipeline +│ ├── content/ # Content generation orchestration +│ ├── integration/ # Sync services +│ ├── linking/ # Link processing (INACTIVE) +│ ├── optimization/ # Content optimization (INACTIVE) +│ ├── planning/ # Clustering, idea generation +│ └── publishing/ # Publishing orchestration +├── plugins/ # Plugin distribution system +└── tasks/ # Celery task definitions +``` + +### 1.2 Frontend File Structure (React/TypeScript) + +``` +frontend/src/ +├── api/ # API clients (linker.api.ts, optimizer.api.ts, etc.) +├── services/ +│ └── api.ts # Main API service (2500+ lines) +├── store/ # Zustand stores (authStore, siteStore, sectorStore, billingStore, moduleStore) +├── pages/ # Route pages +│ ├── Dashboard/ # Main dashboard with widgets +│ ├── Planner/ # Keywords, Clusters, Ideas +│ ├── Writer/ # Tasks, Content, Images, Review, Published +│ ├── Automation/ # Pipeline config and monitoring +│ ├── Linker/ # Internal linking (INACTIVE) +│ ├── Optimizer/ # Content optimization (INACTIVE) +│ ├── Settings/ # Site settings, AI models, prompts +│ ├── Billing/ # Plans, usage, transactions +│ └── Auth/ # Login, register, password reset +├── components/ +│ ├── common/ # Shared components +│ ├── dashboard/ # Dashboard widgets +│ └── header/ # NotificationDropdown +├── layout/ # AppLayout, AppHeader, AppSidebar +└── hooks/ # Custom hooks +``` + +### 1.3 Current Sidebar Navigation + +``` +Dashboard +SETUP + ├── Add Keywords + ├── Content Settings + ├── Sites (if sites_enabled) + └── Thinker (admin only, if thinker_enabled) +WORKFLOW + ├── Planner (Keywords → Clusters → Ideas) + ├── Writer (Queue → Drafts → Images → Review → Published) + ├── Automation + ├── Linker (if linker_enabled — currently hidden) + └── Optimizer (if optimizer_enabled — currently hidden) +ACCOUNT + ├── Account Settings + ├── Plans & Billing + ├── Usage + └── AI Models (admin only) +HELP + └── Help & Docs +``` + +### 1.4 Existing Models That Will Be Modified + +| Model | Location | What Gets Added | Why | +|-------|----------|----------------|-----| +| **Site** | `auth/models.py` | `sag_blueprint_id` (FK, nullable) | Link site to its active blueprint | +| **Cluster** | `modules/planner/models.py` | `sag_cluster_id` (FK, nullable), `cluster_type` (Enum, nullable) | Connect existing clusters to SAG clusters | +| **Tasks** | `modules/writer/models.py` | `sag_cluster_id` (FK, nullable), `blueprint_context` (JSON, nullable) | Writer gets cluster context for type-specific prompts | +| **Content** | `modules/writer/models.py` | `sag_cluster_id` (FK, nullable), `outbound_link_count` (Int, nullable), `inbound_link_count` (Int, nullable), `backlink_count` (Int, nullable) | Map content to clusters, track link metrics | +| **ContentIdea** | `modules/planner/models.py` | `sag_cluster_id` (FK, nullable), `idea_source` (Enum, nullable) | Track whether idea came from keyword clustering or SAG blueprint | + +**Critical rule:** ALL additions to existing models are nullable. No migrations that alter non-null columns. No breaking changes to existing API serializers — new fields are added as optional with `required=False`. + +### 1.5 Existing AI Functions + +``` +ai/functions/ +├── auto_cluster.py # AutoClusterKeywords — Keywords → Clusters +├── generate_ideas.py # GenerateContentIdeas — Cluster → Ideas +├── generate_content.py # GenerateContent — Task → Full article +├── generate_image_prompts.py # GenerateImagePrompts — Content → Image prompts +├── generate_images.py # GenerateImages — Prompts → Images +└── optimize_content.py # OptimizeContent — PENDING, not implemented +``` + +### 1.6 Existing Automation Pipeline (7 stages) + +``` +Stage 1: Process New Keywords +Stage 2: AI Cluster Keywords +Stage 3: Generate Content Ideas +Stage 4: Create Writer Tasks +Stage 5: Generate Article Content +Stage 6: Extract Image Prompts +Stage 7: Generate Images → Review Queue +``` + +### 1.7 Multi-Tenant Data Scoping + +All new models MUST follow the existing pattern: +- Extend `AccountBaseModel` for account-scoped data (SAGBlueprint, SAGCampaign) +- Extend `SiteSectorBaseModel` for site+sector-scoped data where applicable +- ViewSets extend `AccountModelViewSet` or `SiteSectorModelViewSet` for auto-filtering +- `AccountContextMiddleware` resolves tenant from JWT — no manual filtering needed + +--- + +## 2. Implementation Sequence — The Critical Path {#2-implementation-sequence} + +Everything depends on what came before. This sequence cannot be reordered. + +``` +PHASE 1 ─── Data Foundation (NEW models + modified existing models) + │ No UI yet. Backend only. Migrations. + │ +PHASE 2 ─── Sector Attribute Templates (NEW data layer) + │ Admin interface to manage templates. + │ AI-assisted template generation. + │ +PHASE 3 ─── Cluster Formation & Keyword Generation Engine + │ AI functions that turn attributes → clusters → keywords. + │ No user-facing UI yet — these are services called by wizard and pipeline. + │ +PHASE 4 ─── SAG Site Builder Wizard (Case 2) + │ Frontend: Setup wizard gets Step 3 "Site Structure". + │ First user-facing SAG feature. + │ +PHASE 5 ─── Blueprint-Aware Content Pipeline + │ Existing 7-stage pipeline enhanced with blueprint context. + │ Idea generation reads blueprint. Writer uses type-specific prompts. + │ +PHASE 6 ─── Taxonomy Creation Flow + │ IGNY8 → Plugin: push taxonomy creation payload. + │ Plugin creates WP taxonomies from blueprint. + │ +PHASE 7 ─── Existing Site Analysis (Case 1) + │ Plugin sends site data → IGNY8 AI extracts attributes → gap analysis. + │ +PHASE 8 ─── Blueprint Health Monitoring + │ Background Celery tasks. Dashboard widgets. + │ +PHASE 9 ─── SAG Interlinking (Linker Module Evolution) + │ Activate linker_enabled. New SAG-aware linking rules. + │ Depends on: blueprints, clusters, published content. + │ +PHASE 10 ── External Backlink Campaign Module + Depends on: blueprints, clusters, interlinking, GSC data. + New models, new UI, FatGrid/PR integrations. +``` + +**Parallel tracks possible:** +- Phase 2 (templates) and Phase 8 (health monitoring) share no dependencies — template creation can continue while monitoring is built. +- Phase 9 (interlinking) and Phase 10 (backlinks) can overlap: interlinking rules can be finalized while backlink data models are built. + +--- + +## 3. Phase 1: Data Foundation — New Models {#3-phase-1-data-foundation} + +### 3.1 New App: `sag` + +Create a new Django app for all SAG-specific models and business logic. This keeps SAG cleanly separated from existing modules. + +**Create:** +``` +backend/igny8_core/ +├── sag/ # NEW Django app +│ ├── __init__.py +│ ├── apps.py # SagConfig +│ ├── models.py # SAGBlueprint, SAGAttribute, SAGCluster, +│ │ # SectorAttributeTemplate +│ ├── serializers.py # DRF serializers for all SAG models +│ ├── views.py # ViewSets (SAGBlueprintViewSet, etc.) +│ ├── urls.py # /api/v1/sag/* +│ ├── admin.py # Django admin for SAG models +│ ├── services/ # Business logic +│ │ ├── __init__.py +│ │ ├── blueprint_service.py # Blueprint CRUD, versioning, lifecycle +│ │ ├── attribute_service.py # Attribute framework loading, merging, validation +│ │ ├── cluster_service.py # Cluster formation, type classification +│ │ ├── keyword_service.py # Keyword auto-generation from attribute intersections +│ │ ├── template_service.py # Sector template loading, AI generation +│ │ └── health_service.py # Blueprint health score calculation +│ ├── ai_functions/ # SAG-specific AI functions +│ │ ├── __init__.py +│ │ ├── attribute_discovery.py # AI: Industry+Sector → Attribute framework +│ │ ├── attribute_extraction.py # AI: Site data → Attribute values (Case 1) +│ │ ├── attribute_population.py # AI: User inputs → Attribute values (Case 2) +│ │ ├── cluster_formation.py # AI: Populated attributes → Clusters with types +│ │ ├── keyword_generation.py # AI: Clusters + attribute values → Keywords +│ │ └── content_planning.py # AI: Clusters + keywords → Content ideas +│ └── migrations/ +│ └── 0001_initial.py +``` + +**Register in settings.py:** +```python +INSTALLED_APPS = [ + ... + 'igny8_core.sag', +] +``` + +**Register URLs in root urls.py:** +```python +urlpatterns = [ + ... + path('api/v1/sag/', include('igny8_core.sag.urls')), +] +``` + +### 3.2 New Models — Complete Definitions + +**SAGBlueprint** — The master architectural document for a site. + +```python +# sag/models.py + +class SAGBlueprint(AccountBaseModel): + """ + The SAG Blueprint is the complete site architecture generated from + attribute analysis. Both Case 1 (existing site) and Case 2 (new site) + produce this same model. One active blueprint per site at a time. + """ + id = models.UUIDField(primary_key=True, default=uuid4) + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE, related_name='sag_blueprints') + version = models.IntegerField(default=1) + status = models.CharField( + max_length=20, + choices=[ + ('draft', 'Draft'), # Generated, awaiting user confirmation + ('active', 'Active'), # Confirmed, driving all content operations + ('evolving', 'Evolving'), # New clusters being added as site grows + ('archived', 'Archived'), # Replaced by newer version + ], + default='draft' + ) + source = models.CharField( + max_length=20, + choices=[ + ('site_builder', 'Site Builder (Case 2)'), + ('site_analysis', 'Existing Site Analysis (Case 1)'), + ('manual', 'Manual Creation'), + ] + ) + # Denormalized JSON for quick reads — authoritative data is in related models + attributes_json = models.JSONField(default=dict, blank=True) + clusters_json = models.JSONField(default=dict, blank=True) + taxonomy_plan = models.JSONField(default=dict, blank=True) + execution_priority = models.JSONField(default=list, blank=True) + internal_linking_map = models.JSONField( + default=dict, blank=True, + help_text="Placeholder until Doc 3 interlinking spec populates this" + ) + + # Metrics + sag_health_score = models.FloatField(default=0.0, help_text="0-100 score") + total_clusters = models.IntegerField(default=0) + total_keywords = models.IntegerField(default=0) + total_content_planned = models.IntegerField(default=0) + total_content_published = models.IntegerField(default=0) + + # Timestamps + confirmed_at = models.DateTimeField(null=True, blank=True) + last_health_check = models.DateTimeField(null=True, blank=True) + + class Meta: + ordering = ['-created_at'] + unique_together = ['site', 'version'] +``` + +**SAGAttribute** — A classification axis within a blueprint. + +```python +class SAGAttribute(models.Model): + """ + One dimensional axis of the SAG grid. Each attribute becomes a WordPress + custom taxonomy. Values become taxonomy terms. + """ + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE, related_name='attributes') + name = models.CharField(max_length=100) # "Target Area" + slug = models.SlugField(max_length=100) # "target-area" + description = models.TextField(blank=True) # "Primary body area the device targets" + level = models.CharField( + max_length=20, + choices=[ + ('primary', 'Primary'), # Main navigation axes + ('secondary', 'Secondary'), # Cluster depth axes + ('tertiary', 'Tertiary'), # Filtering/tagging + ] + ) + values = models.JSONField( + default=list, + help_text='Array of {name, slug} objects. E.g. [{"name": "Foot", "slug": "foot"}]' + ) + # WordPress sync state + wp_taxonomy_slug = models.CharField(max_length=100, null=True, blank=True) + wp_sync_status = models.CharField( + max_length=20, + choices=[ + ('pending', 'Pending'), + ('synced', 'Synced'), + ('failed', 'Failed'), + ], + default='pending' + ) + sort_order = models.IntegerField(default=0) + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + ordering = ['sort_order', 'level'] +``` + +**SAGCluster** — A meaningful intersection of 2+ attribute values. + +```python +class SAGCluster(AccountBaseModel): + """ + A cluster represents a topical ecosystem formed at the intersection of + 2+ attribute values. Each cluster has a hub page and supporting content. + """ + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE, related_name='clusters') + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE, related_name='sag_clusters') + name = models.CharField(max_length=200) # "Foot Massagers for Neuropathy" + slug = models.SlugField(max_length=200) + cluster_type = models.CharField( + max_length=30, + choices=[ + ('product_category', 'Product/Service Category'), + ('condition_problem', 'Condition/Problem'), + ('feature', 'Feature'), + ('brand', 'Brand'), + ('informational', 'Informational'), + ('comparison', 'Comparison'), + ] + ) + attribute_intersection = models.JSONField( + help_text='Which attribute values form this cluster. E.g. {"target_area": "Foot", "relief_focus": "Neuropathy"}' + ) + + # Hub page info + hub_page_title = models.CharField(max_length=300, blank=True) + hub_page_type = models.CharField(max_length=30, default='cluster_hub') + hub_page_structure = models.CharField(max_length=30, default='guide_tutorial') + hub_page_url_slug = models.CharField(max_length=300, blank=True) + + # Auto-generated keywords + auto_generated_keywords = models.JSONField(default=list) + + # Supporting content plan + supporting_content_plan = models.JSONField( + default=list, + help_text='Array of {title, type, structure, keywords} for planned supporting content' + ) + + # Linking + linked_attribute_terms = models.JSONField( + default=list, + help_text='Which attribute term slugs this cluster connects to' + ) + cross_cluster_links = models.JSONField( + default=list, + help_text='Slugs of other clusters sharing an attribute value' + ) + + # Status and metrics + status = models.CharField( + max_length=20, + choices=[ + ('planned', 'Planned'), + ('partial', 'Partial'), # Some content published + ('complete', 'Complete'), # Hub + all supporting content published + ], + default='planned' + ) + content_count = models.IntegerField(default=0) + link_coverage_score = models.FloatField(default=0.0, help_text="0-100") + + # Backlink campaign fields (Phase 10) + backlink_target_tier = models.CharField( + max_length=5, + choices=[('T1','T1'),('T2','T2'),('T3','T3'),('T4','T4'),('T5','T5')], + null=True, blank=True, + help_text='Backlink campaign tier assignment — set by Doc 4 campaign generator' + ) + + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + ordering = ['name'] +``` + +**SectorAttributeTemplate** — The NEW data layer: sector-level attribute intelligence. + +```python +class SectorAttributeTemplate(models.Model): + """ + This is the foundational data layer that does NOT currently exist. + Each sector gets an attribute framework that defines its dimensional axes + and suggested values. This is the structural DNA of a sector. + """ + id = models.UUIDField(primary_key=True, default=uuid4) + industry = models.CharField(max_length=200) + sector = models.CharField(max_length=200) + site_type = models.CharField( + max_length=30, + choices=[ + ('e_commerce', 'E-Commerce'), + ('services', 'Services'), + ('saas', 'SaaS'), + ('content', 'Content/Blog'), + ('local_business', 'Local Business'), + ('brand', 'Brand'), + ] + ) + attribute_framework = models.JSONField( + help_text='Template attributes with suggested values. Array of {name, description, level, suggested_values[]}' + ) + keyword_templates = models.JSONField( + default=dict, + help_text='Keyword generation templates per cluster type. E.g. {"condition_problem": ["best {target} for {condition}", ...]}' + ) + source = models.CharField( + max_length=30, + choices=[ + ('manual', 'Manual'), + ('ai_generated', 'AI Generated'), + ('user_contributed', 'User Contributed'), + ], + default='manual' + ) + is_active = models.BooleanField(default=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + unique_together = ['industry', 'sector'] + ordering = ['industry', 'sector'] +``` + +### 3.3 Migrations for Existing Models + +**Site model** (`auth/models.py`): +```python +# Add to Site model: +sag_blueprint_id = models.ForeignKey( + 'sag.SAGBlueprint', on_delete=models.SET_NULL, + null=True, blank=True, related_name='active_for_sites', + help_text='Currently active SAG blueprint for this site' +) +``` + +**Cluster model** (`modules/planner/models.py`): +```python +# Add to existing Cluster model: +sag_cluster_id = models.ForeignKey( + 'sag.SAGCluster', on_delete=models.SET_NULL, + null=True, blank=True, related_name='legacy_clusters' +) +cluster_type = models.CharField(max_length=30, null=True, blank=True) +``` + +**Tasks model** (`modules/writer/models.py`): +```python +# Add to existing Tasks model: +sag_cluster_id = models.ForeignKey( + 'sag.SAGCluster', on_delete=models.SET_NULL, + null=True, blank=True +) +blueprint_context = models.JSONField(null=True, blank=True) +``` + +**Content model** (`modules/writer/models.py`): +```python +# Add to existing Content model: +sag_cluster_id = models.ForeignKey( + 'sag.SAGCluster', on_delete=models.SET_NULL, + null=True, blank=True +) +outbound_link_count = models.IntegerField(null=True, blank=True) +inbound_link_count = models.IntegerField(null=True, blank=True) +backlink_count = models.IntegerField(null=True, blank=True) +``` + +**ContentIdea model** (`modules/planner/models.py`): +```python +# Add to existing ContentIdea model: +sag_cluster_id = models.ForeignKey( + 'sag.SAGCluster', on_delete=models.SET_NULL, + null=True, blank=True +) +idea_source = models.CharField( + max_length=30, null=True, blank=True, + choices=[ + ('keyword_clustering', 'Keyword Clustering'), + ('sag_blueprint', 'SAG Blueprint'), + ('gap_analysis', 'Gap Analysis'), + ] +) +``` + +### 3.4 Serializers + +``` +sag/serializers.py +``` + +Create DRF serializers for each model. Key considerations: +- `SAGBlueprintSerializer` — include nested `attributes` and `clusters` on detail view, exclude on list view for performance +- `SAGBlueprintListSerializer` — lightweight: id, site, version, status, health_score, total_clusters, total_keywords, timestamps +- `SAGAttributeSerializer` — full attribute with values array +- `SAGClusterSerializer` — full cluster with keywords, supporting content plan, linking data +- `SectorAttributeTemplateSerializer` — admin-only, includes full attribute_framework JSON + +### 3.5 ViewSets and URLs + +```python +# sag/views.py + +class SAGBlueprintViewSet(AccountModelViewSet): + """ + CRUD for SAG Blueprints. + Additional actions: confirm, archive, regenerate, health_check + """ + queryset = SAGBlueprint.objects.all() + serializer_class = SAGBlueprintSerializer + + @action(detail=True, methods=['post']) + def confirm(self, request, pk=None): + """Move blueprint from draft → active. Sets site.sag_blueprint_id.""" + pass + + @action(detail=True, methods=['post']) + def archive(self, request, pk=None): + """Move blueprint to archived. Removes from site.sag_blueprint_id.""" + pass + + @action(detail=True, methods=['post']) + def regenerate(self, request, pk=None): + """Create new version of blueprint from updated attributes.""" + pass + + @action(detail=True, methods=['get']) + def health_check(self, request, pk=None): + """Run health check and return score + details.""" + pass + +class SAGAttributeViewSet(AccountModelViewSet): + """CRUD for attributes within a blueprint.""" + queryset = SAGAttribute.objects.all() + serializer_class = SAGAttributeSerializer + +class SAGClusterViewSet(AccountModelViewSet): + """CRUD for clusters within a blueprint.""" + queryset = SAGCluster.objects.all() + serializer_class = SAGClusterSerializer + +class SectorAttributeTemplateViewSet(ModelViewSet): + """Admin-only: manage sector attribute templates.""" + queryset = SectorAttributeTemplate.objects.all() + serializer_class = SectorAttributeTemplateSerializer + permission_classes = [IsAdminUser] +``` + +```python +# sag/urls.py + +router = DefaultRouter() +router.register(r'blueprints', SAGBlueprintViewSet) +router.register(r'attributes', SAGAttributeViewSet) +router.register(r'clusters', SAGClusterViewSet) +router.register(r'templates', SectorAttributeTemplateViewSet) + +urlpatterns = [ + path('', include(router.urls)), +] +``` + +### 3.6 Django Admin + +Register all 4 models in Django admin with: +- SAGBlueprint: list display (site, version, status, health_score, created_at), filters (status, source) +- SAGAttribute: inline on Blueprint admin, sortable by sort_order +- SAGCluster: list display (name, cluster_type, status, content_count), filters (cluster_type, status) +- SectorAttributeTemplate: list display (industry, sector, site_type, source, is_active), filters (industry, site_type, source) + +### 3.7 Frontend — Phase 1 Has No User-Facing UI + +Phase 1 is backend-only. The only frontend addition is a read-only blueprint viewer in Site Settings (for development verification): + +``` +frontend/src/pages/Settings/ +├── SiteSettings.tsx # EXISTING — add a "SAG Blueprint" tab +└── components/ + └── BlueprintViewer.tsx # NEW — read-only JSON display of active blueprint +``` + +This is a development aid. The real UI comes in Phase 4 (wizard) and Phase 8 (dashboard). + +--- + +## 4. Phase 2: Sector Attribute Templates {#4-phase-2-sector-attribute-templates} + +### 4.1 What This Phase Delivers + +The SectorAttributeTemplate model from Phase 1 gets populated with actual data. This is the structural DNA that makes everything else work. + +### 4.2 Backend: Template Service + +``` +sag/services/template_service.py +``` + +**Functions:** +- `get_template(industry, sector)` → returns SectorAttributeTemplate or None +- `get_or_generate_template(industry, sector)` → returns existing template OR triggers AI generation +- `merge_templates(sector_list)` → for multi-sector sites: merge attribute frameworks, combine value lists, deduplicate +- `validate_template(template_data)` → ensure all attributes have names, levels, and at least suggested_values structure + +### 4.3 Backend: AI Template Generation + +``` +sag/ai_functions/attribute_discovery.py +``` + +**New AI function: `DiscoverSectorAttributes`** + +Registered in AI engine function registry alongside existing functions. + +```python +# Register in ai/registry.py: +'discover_sector_attributes': 'igny8_core.sag.ai_functions.attribute_discovery.DiscoverSectorAttributes' +``` + +**Input:** industry name, sector name, site_type +**Output:** attribute_framework JSON matching SectorAttributeTemplate schema +**Prompt strategy:** "You are an expert in site architecture for {industry}/{sector}. Define the dimensional axes that organize this sector. For each attribute, specify: name, description, level (primary/secondary/tertiary), and 5-10 suggested values." + +### 4.4 Backend: Manual Template Seeding + +Priority: Seed templates for sectors with highest existing user base in IGNY8. Use the Healthcare/Medical Excel workbook (SAGIndustry01HealthcareMedical.xlsx) as the reference format for how templates should be structured. + +**Admin Interface:** Django admin for SectorAttributeTemplate allows manual creation and editing. The `attribute_framework` JSON field should use a structured widget or at minimum raw JSON with validation. + +### 4.5 Frontend — Admin Template Manager (Admin Only) + +``` +frontend/src/pages/Settings/ +└── components/ + └── SectorTemplateManager.tsx # NEW — admin-only interface +``` + +This is a simple CRUD interface visible only to admin users (similar to existing AI Models admin page). Shows list of all templates, allows editing attribute frameworks, and can trigger AI generation for missing sectors. + +**Not in main sidebar** — accessed via Settings → Admin → Sector Templates (similar to how AI Models is nested under Settings). + +--- + +## 5. Phase 3: Cluster Formation & Keyword Generation Engine {#5-phase-3-cluster-formation--keyword-generation} + +### 5.1 What This Phase Delivers + +The AI intelligence that turns populated attributes into clusters with types, and clusters into 300-500+ keywords. These are backend services — no direct UI yet. They're called by the wizard (Phase 4) and the pipeline (Phase 5). + +### 5.2 Backend: AI Functions + +**`sag/ai_functions/cluster_formation.py` — `FormClusters`** + +Register in AI engine: +```python +'form_clusters': 'igny8_core.sag.ai_functions.cluster_formation.FormClusters' +``` + +**Input:** populated attributes (all values per attribute), sector context, site_type +**Output:** array of cluster objects with: name, cluster_type, attribute_intersection, hub_page_title, hub_page_structure, supporting_content_plan + +**Logic:** +1. Generate all 2-value intersections of primary × primary, primary × secondary +2. AI evaluates each intersection: is this a real topical ecosystem with search demand? +3. Valid intersections become clusters +4. AI classifies each cluster by type (product_category, condition_problem, feature, brand, informational, comparison) +5. AI generates hub page title and supporting content titles per cluster +6. Maximum 50 clusters per sector (hard cap from SAG methodology) + +**`sag/ai_functions/keyword_generation.py` — `GenerateKeywords`** + +Register in AI engine: +```python +'generate_keywords': 'igny8_core.sag.ai_functions.keyword_generation.GenerateKeywords' +``` + +**Input:** clusters with attribute values, keyword_templates from SectorAttributeTemplate +**Output:** per-cluster keyword arrays (15-25 keywords per cluster) + +**Logic:** +1. Load keyword templates for this sector type +2. For each cluster, substitute attribute values into templates +3. Generate long-tail variants with modifiers (best, review, vs, for, how to) +4. Deduplicate across clusters +5. Total should be 300-500+ keywords per site + +### 5.3 Backend: Blueprint Assembly Service + +``` +sag/services/blueprint_service.py — extend with: +``` + +**`assemble_blueprint(site, attributes, clusters, keywords)`** + +Takes all outputs from Phases 2-3 and assembles the complete SAGBlueprint: +1. Create SAGBlueprint record (status=draft) +2. Create SAGAttribute records from attributes +3. Create SAGCluster records from clusters +4. Populate auto_generated_keywords on each cluster +5. Generate taxonomy_plan from attributes +6. Generate execution_priority from cluster types and keyword volumes +7. Populate denormalized JSON fields on blueprint +8. Return blueprint ID + +### 5.4 Backend: Cluster Service + +``` +sag/services/cluster_service.py +``` + +**Functions:** +- `classify_cluster_type(intersection, sector_context)` → Enum +- `generate_hub_page_info(cluster)` → title, type, structure, url_slug +- `plan_supporting_content(cluster)` → array of {title, type, structure, keywords} +- `find_cross_cluster_links(all_clusters)` → for each cluster, find others sharing attribute values +- `find_linked_attribute_terms(cluster)` → which attribute value slugs this cluster connects to + +--- + +## 6. Phase 4: SAG Site Builder Wizard (Case 2) {#6-phase-4-sag-site-builder-wizard} + +### 6.1 What This Phase Delivers + +The first user-facing SAG feature. The setup wizard gets a new Step 3 "Site Structure" that collects business data and generates a complete blueprint. + +### 6.2 Backend: Wizard API Endpoints + +Add to `sag/views.py` or create `sag/wizard_views.py`: + +```python +# POST /api/v1/sag/wizard/generate-attributes/ +# Input: {industry, sectors[], site_type} +# Output: {attributes: [{name, level, suggested_values}]} +# Calls: template_service.get_or_generate_template() + merge if multi-sector + +# POST /api/v1/sag/wizard/populate-attributes/ +# Input: {attributes: [{name, level, values}], business_data: {products, services, brands, locations, conditions}} +# Output: {populated_attributes: [{name, level, values}]} (values now enriched from business data) +# Calls: ai_functions.attribute_population.PopulateAttributes + +# POST /api/v1/sag/wizard/generate-blueprint/ +# Input: {site_id, populated_attributes, mode: 'quick'|'detailed'} +# Output: {blueprint_id, clusters, keywords_count, content_plan_count, taxonomy_count} +# Calls: cluster_formation → keyword_generation → blueprint_service.assemble_blueprint() + +# POST /api/v1/sag/wizard/confirm-blueprint/ +# Input: {blueprint_id} +# Output: {success, blueprint_status: 'active'} +# Calls: blueprint_service.confirm() — sets site.sag_blueprint_id, triggers taxonomy creation +``` + +### 6.3 Backend: AI Function for Business Data Population + +**`sag/ai_functions/attribute_population.py` — `PopulateAttributes`** + +**Input:** attribute framework + user's business data (products list, services list, brands, locations, conditions) +**Output:** populated attributes with site-specific values extracted from business data + +**Logic:** +1. Parse business data inputs (free text, comma-separated lists, structured inputs) +2. Map business items to attribute values (e.g., "foot massagers, neck massagers" → Target Area: [Foot, Neck]) +3. Identify values not in suggested_values → add as new values +4. Apply pruning rules (single-value primary → demote to secondary, etc.) +5. Assess completeness per attribute → flag any that need user attention + +### 6.4 Frontend: Setup Wizard Enhancement + +The existing setup wizard lives at: +``` +frontend/src/pages/Settings/ # or wherever the Add Site wizard is +``` + +**Modify the wizard to insert Step 3 between "Add Site" and "Connect WordPress":** + +``` +frontend/src/pages/Settings/ +├── SetupWizard/ # EXISTING wizard component +│ ├── WizardStep1Welcome.tsx # No changes +│ ├── WizardStep2AddSite.tsx # No changes — already collects Industry, Sectors +│ ├── WizardStep3SiteStructure.tsx # NEW — the Site Builder step +│ │ ├── ModeSelector.tsx # Quick Mode vs Detailed Mode toggle +│ │ ├── AttributeReview.tsx # Shows AI-generated attributes, toggle on/off, edit values +│ │ ├── BusinessDataInput.tsx # Per-site-type input forms (products, services, etc.) +│ │ ├── BlueprintPreview.tsx # Tree view of clusters, keywords count, content plan +│ │ └── BlueprintConfirm.tsx # Approve & Build / Adjust Attributes buttons +│ ├── WizardStep4ConnectWP.tsx # EXISTING — enhanced: auto-creates taxonomies after connect +│ ├── WizardStep5Keywords.tsx # EXISTING — now shows "optional" messaging + gap analysis +│ └── WizardStep6Complete.tsx # EXISTING — enhanced: shows blueprint summary +``` + +### 6.5 Frontend: Step 3 Component Details + +**ModeSelector.tsx** +- Two cards: "Quick Mode" (auto-build, skip review) and "Detailed Mode" (full review + business data) +- Quick mode calls: generate-attributes → generate-blueprint (with defaults) → confirm +- Detailed mode proceeds through all sub-steps + +**AttributeReview.tsx** +- Displays attributes grouped by level (Primary, Secondary, Tertiary) +- Each attribute: name, toggle switch (on/off), expandable values list +- Values: chip/tag UI with [+ Add] button, click to remove +- [+ Add Custom Attribute] button at bottom +- Loading state while AI generates attributes + +**BusinessDataInput.tsx** +- Dynamic form based on site_type from Step 2 +- E-commerce: Products/categories (textarea), Device types (textarea), Problems solved (textarea), Brands (textarea), Features (textarea) +- Services: Services offered (textarea), Locations (textarea), Property types (textarea), Problems solved (textarea) +- SaaS: Features (textarea), Use cases (textarea), Integrations (textarea), Competitors (textarea) +- Content: Topics (textarea), Subtopics (textarea), Audience (textarea) +- Local Business: Services (textarea), Locations (textarea), Conditions (textarea) +- Each textarea has helper text: "Enter one per line, or comma-separated" + +**BlueprintPreview.tsx** +- Tree/accordion view of clusters grouped by primary attribute value +- Each cluster shows: name, type badge, hub page title, supporting content count, keyword count +- Summary bar at top: X clusters, Y keywords, Z content pieces, W taxonomies +- Expandable per cluster: see all keywords, all planned supporting content titles +- This is the "Your Site Architecture" preview from the spec document + +**BlueprintConfirm.tsx** +- Two buttons: [Approve & Build] and [Adjust Attributes] (goes back to AttributeReview) +- Approve triggers: POST /wizard/confirm-blueprint/ +- Shows brief loading animation during confirmation +- On success: proceeds to Step 4 (Connect WordPress) + +### 6.6 Frontend: Zustand Store + +``` +frontend/src/store/ +└── sagStore.ts # NEW +``` + +```typescript +interface SAGState { + blueprint: SAGBlueprint | null; + attributes: SAGAttribute[]; + clusters: SAGCluster[]; + wizardMode: 'quick' | 'detailed'; + wizardStep: number; // Sub-step within Step 3 + isGenerating: boolean; + error: string | null; + + // Actions + setWizardMode: (mode: 'quick' | 'detailed') => void; + generateAttributes: (industry: string, sectors: string[]) => Promise; + populateAttributes: (attributes: any[], businessData: any) => Promise; + generateBlueprint: (siteId: string) => Promise; + confirmBlueprint: (blueprintId: string) => Promise; + loadBlueprint: (siteId: string) => Promise; +} +``` + +### 6.7 Frontend: API Client + +``` +frontend/src/api/ +└── sag.api.ts # NEW +``` + +API client for all `/api/v1/sag/*` endpoints. Follows existing pattern from other API clients (linker.api.ts, optimizer.api.ts). + +--- + +## 7. Phase 5: Blueprint-Aware Content Pipeline {#7-phase-5-blueprint-aware-content-pipeline} + +### 7.1 What This Phase Delivers + +The existing 7-stage automation pipeline becomes SAG-aware. Ideas generate from the blueprint, tasks carry cluster context, writer uses type-specific prompts, and content gets auto-assigned to correct taxonomies. + +### 7.2 Backend: Modified Automation Stages + +**Location:** `business/automation/` — modify existing stage handlers + +**Stage 0 (NEW): Blueprint Check** +```python +# business/automation/stages/stage_0_blueprint_check.py (NEW) +# Before any pipeline run: +# 1. Check if site has active SAG blueprint (site.sag_blueprint_id is not None) +# 2. If yes: load blueprint, identify unfulfilled content needs +# 3. If no: pipeline runs in legacy mode (no changes to current behavior) +``` + +**Stage 2: AI Cluster Keywords — ENHANCED** +```python +# business/automation/stages/ — modify existing Stage 2 +# If blueprint exists: +# - Skip AI clustering (clusters already defined by blueprint) +# - Instead: map any new user-added keywords to existing SAG clusters +# - Flag keywords that don't match any cluster +# If no blueprint: +# - Run existing AutoClusterKeywords (unchanged) +``` + +**Stage 3: Generate Content Ideas — ENHANCED** +```python +# business/automation/stages/ — modify existing Stage 3 +# If blueprint exists: +# - Call sag/ai_functions/content_planning.py instead of generic idea generation +# - Each idea gets: correct Sector, Structure, Type, Cluster from blueprint +# - idea_source = 'sag_blueprint' +# If no blueprint: +# - Run existing GenerateContentIdeas (unchanged) +``` + +**Stage 4: Create Writer Tasks — ENHANCED** +```python +# business/automation/stages/ — modify existing Stage 4 +# If blueprint exists: +# - Tasks carry sag_cluster_id and blueprint_context +# - blueprint_context includes: cluster_type, hub_title, attribute_terms, related_content +# If no blueprint: +# - Run existing task creation (unchanged) +``` + +**Stage 5: Generate Article Content — ENHANCED** +```python +# business/automation/stages/ — modify existing Stage 5 +# If task has blueprint_context: +# - Select prompt template by Structure + Type (instead of generic) +# - Include SAG context variables: {cluster_name}, {cluster_type}, {hub_title}, {attribute_terms} +# - Content generation includes type-specific sections +# If no blueprint_context: +# - Run existing GenerateContent (unchanged) +``` + +**Stage 6 (NEW enhancement): Taxonomy Assignment** +```python +# After content generation, before image prompts: +# If blueprint exists: +# - Auto-assign content to correct custom taxonomies from blueprint +# - Set sag_cluster_id on Content record +# - Mark cluster status as 'partial' if first content piece +``` + +### 7.3 Backend: Enhanced Prompt Templates + +**Location:** Existing `PromptTemplate` model or defaults in code + +Add SAG-context prompt variants. These are stored in the same PromptTemplate system but selected based on content type: + +| Content Type | Structure | Prompt Template Key | +|-------------|-----------|-------------------| +| Cluster Hub Page | Guide Tutorial | `sag_hub_guide` | +| Cluster Hub Page | Top Listicle | `sag_hub_listicle` | +| Blog Post | Comparison | `sag_blog_comparison` | +| Blog Post | Review | `sag_blog_review` | +| Blog Post | How To | `sag_blog_howto` | +| Blog Post | Question | `sag_blog_question` | +| Attribute Term Page | Guide Tutorial | `sag_term_page` | +| Product Page | Review | `sag_product_page` | +| Service Page | Guide Tutorial | `sag_service_page` | + +Each prompt includes SAG context variables: +``` +You are writing a {content_type} for the cluster "{cluster_name}". +This cluster covers the intersection of {attribute_intersection}. +The hub page for this cluster is: "{hub_page_title}" at {hub_page_url}. +Related content in this cluster includes: {related_blogs}. +This content should naturally reference these taxonomy terms: {attribute_terms}. +``` + +### 7.4 Frontend: Pipeline UI Shows Blueprint Context + +**Location:** `pages/Automation/` — existing pipeline monitoring view + +When a site has an active blueprint, the automation page shows: +- Blueprint status badge: "SAG Blueprint Active (v1)" +- Pipeline mode indicator: "Running in SAG Mode" vs "Running in Legacy Mode" +- Stage 0 (Blueprint Check) appears as the first stage in the progress display + +**Location:** `pages/Writer/` — existing task and content views + +When viewing a task or content item that has `sag_cluster_id`: +- Show cluster badge: "Cluster: Foot Massagers for Neuropathy" +- Show type badge: "Type: Hub Page" or "Type: Supporting Blog" +- Show blueprint context panel (collapsible): cluster type, attribute terms, related content links + +These are display-only enhancements to existing views — no new pages needed. + +--- + +## 8. Phase 6: Taxonomy Creation Flow {#8-phase-6-taxonomy-creation-flow} + +### 8.1 What This Phase Delivers + +When a blueprint is confirmed, IGNY8 pushes taxonomy creation instructions to the WordPress plugin, which creates the actual WordPress custom taxonomies and terms. + +### 8.2 Backend: Taxonomy Payload Generator + +``` +sag/services/taxonomy_service.py # NEW +``` + +**Functions:** +- `generate_taxonomy_payload(blueprint)` → JSON payload matching plugin's expected format +- `send_taxonomy_payload(site, payload)` → POST to WordPress plugin endpoint +- `handle_taxonomy_response(site, response)` → update SAGAttribute wp_sync_status +- `check_taxonomy_status(site)` → GET current taxonomy state from plugin + +**Payload format:** +```json +{ + "taxonomies": [ + { + "slug": "target-area", + "label": "Target Area", + "description": "Primary body area the device targets", + "hierarchical": true, + "post_types": ["product", "post", "page"], + "terms": [ + {"name": "Foot", "slug": "foot", "description": "Foot massagers and foot therapy devices"}, + {"name": "Neck", "slug": "neck", "description": "Neck massagers and cervical therapy"} + ] + } + ] +} +``` + +### 8.3 Plugin Side: Taxonomy Builder + +The WordPress plugin already has planned files for this: +``` +igny8-plugin/includes/modules/sag/ +├── class-taxonomy-builder.php # Create WP taxonomies from payload +├── class-term-builder.php # Create terms within taxonomies +``` + +Plugin endpoint: `POST /wp-json/igny8/v1/sag/create-taxonomies` +- Receives payload from IGNY8 app +- Registers taxonomies via `register_taxonomy()` +- Creates terms via `wp_insert_term()` +- Returns success with term IDs mapped to slugs +- Stores taxonomy registrations in option for persistence across requests + +### 8.4 Backend: Integration with Existing Sync Architecture + +**Location:** `business/integration/` — extend existing sync services + +The taxonomy creation uses the same `Site.wp_api_key` authentication and webhook architecture that content publishing already uses. No new auth mechanism needed. + +**Flow:** +``` +Blueprint confirmed + → sag/services/taxonomy_service.generate_taxonomy_payload() + → business/integration/sync_service.push_to_wordpress(site, '/sag/create-taxonomies', payload) + → Plugin creates taxonomies + terms + → Plugin POSTs response back to IGNY8 webhook + → sag/services/taxonomy_service.handle_taxonomy_response() + → SAGAttribute.wp_sync_status updated to 'synced' +``` + +### 8.5 Frontend: Taxonomy Sync Status + +**Location:** `pages/Settings/SiteSettings.tsx` — add SAG tab or extend existing integration tab + +Show: +- List of attributes from blueprint +- Each attribute: name, WP taxonomy slug, sync status (pending/synced/failed) +- "Sync Taxonomies" button to retry failed syncs +- This is visible after blueprint is confirmed (Phase 4) and site is connected to WordPress + +--- + +## 9. Phase 7: Existing Site Analysis (Case 1) {#9-phase-7-existing-site-analysis} + +### 9.1 What This Phase Delivers + +For existing WordPress/WooCommerce sites, IGNY8 collects site data, AI extracts attributes from it, generates a gap analysis, and produces a blueprint. + +### 9.2 Backend: Extended Site Data Collection + +**Location:** Plugin already has site data collection: +``` +igny8-plugin/data/site-collection.php # Collects post data, taxonomy data, product data +igny8-plugin/data/semantic-mapping.php # Maps site content to semantic strategy +``` + +**Enhance plugin to collect additional data for SAG:** +- All WooCommerce product attributes + values (pa_color, pa_size, custom attributes) +- Product titles and descriptions (for AI attribute extraction) +- Existing custom taxonomies with all terms +- Navigation menu structure with hierarchy +- Page templates in use + +**New plugin endpoint:** `GET /wp-json/igny8/v1/sag/site-analysis` +Returns comprehensive site data package for AI analysis. + +### 9.3 Backend: AI Attribute Extraction (Case 1) + +**`sag/ai_functions/attribute_extraction.py` — `ExtractAttributes`** + +**Input:** raw site data (product titles, descriptions, categories, existing taxonomies, menu structure) +**Output:** discovered attributes with values and confidence scores + +**Logic:** +1. AI analyzes product/content titles for recurring patterns +2. Cross-references against sector template (if exists) for validation +3. Returns discovered attributes with frequency counts per value +4. Flags low-confidence discoveries for user review + +### 9.4 Backend: Gap Analysis Service + +``` +sag/services/gap_analysis_service.py # NEW +``` + +**Functions:** +- `analyze_gap(site_data, blueprint)` → comprehensive gap report +- Gap report includes: missing cluster hubs, missing supporting content, products needing attribute enrichment, taxonomy terms without content, internal links missing + +### 9.5 Frontend: Case 1 Analysis UI + +**Location:** Accessed from Site Settings when a site is connected but has no blueprint + +``` +frontend/src/pages/Settings/ +└── components/ + ├── SiteAnalysis.tsx # NEW — trigger and display site analysis + ├── DiscoveredAttributes.tsx # NEW — show AI-discovered attributes, user confirms/edits + ├── GapAnalysisReport.tsx # NEW — show gap analysis results + └── ProductAutoTagger.tsx # NEW — review and approve AI-generated product tags +``` + +**Flow:** +1. User clicks "Analyze Site Structure" in Site Settings +2. Loading state while plugin collects data and AI processes it +3. DiscoveredAttributes screen: shows AI findings, user toggles/edits/confirms +4. After confirmation → blueprint generates (same as Case 2 but with extracted data) +5. GapAnalysisReport: shows what's missing vs what the blueprint recommends +6. ProductAutoTagger: for e-commerce sites, review AI-suggested attribute assignments per product + +--- + +## 10. Phase 8: Blueprint Health Monitoring {#10-phase-8-blueprint-health-monitoring} + +### 10.1 What This Phase Delivers + +Background monitoring that tracks blueprint completion, content coverage per cluster, link health, and overall SAG health score. Dashboard widgets surface this data. + +### 10.2 Backend: Health Service + +``` +sag/services/health_service.py # Already created in Phase 1, now implement +``` + +**`calculate_health_score(blueprint)`** returns 0-100 score based on: +- Content completeness per cluster (hub exists? blogs published?) — 30 points +- Taxonomy sync status (all taxonomies created?) — 15 points +- Internal link coverage (from Linker module when active) — 20 points +- Keyword coverage (keywords have matching content?) — 15 points +- Unassigned content (pages/products not mapped to clusters) — 10 points +- Overall structure balance (no cluster with 0 content while others have 5+) — 10 points + +### 10.3 Backend: Celery Tasks + +``` +sag/tasks.py # NEW +``` + +```python +@shared_task +def run_blueprint_health_check(site_id): + """Weekly health check for a site's active blueprint.""" + site = Site.objects.get(id=site_id) + if not site.sag_blueprint_id: + return + blueprint = site.sag_blueprint + score = health_service.calculate_health_score(blueprint) + blueprint.sag_health_score = score + blueprint.last_health_check = now() + blueprint.save() + +@shared_task +def check_blueprint_evolution_triggers(site_id): + """Check if blueprint needs evolution (new products, new keywords, etc.).""" + pass +``` + +**Register in Celery Beat schedule** (existing `celery.py` configuration): +- `run_blueprint_health_check`: weekly for all sites with active blueprints +- `check_blueprint_evolution_triggers`: weekly, same schedule + +### 10.4 Frontend: Dashboard Widgets + +**Location:** `components/dashboard/` — add new widgets alongside existing ones + +``` +frontend/src/components/dashboard/ +├── SAGHealthWidget.tsx # NEW — health score gauge, cluster completion bars +├── BlueprintProgressWidget.tsx # NEW — content published vs planned per cluster +``` + +**SAGHealthWidget:** +- Circular gauge showing overall health score (0-100) +- Color: green (80+), yellow (50-79), red (<50) +- Below gauge: quick stats (clusters complete, content published/planned, taxonomies synced) +- Click → goes to blueprint detail page + +**BlueprintProgressWidget:** +- Horizontal bar chart: each cluster as a row +- Bar shows: published content / planned content +- Color coding by cluster status: complete (green), partial (yellow), planned (gray) +- Sorted by execution priority + +**Dashboard integration:** +- Widgets only appear when site has an active blueprint +- Add to existing dashboard grid alongside WorkflowPipelineWidget, AIOperationsWidget, etc. + +### 10.5 Frontend: Blueprint Management Page + +``` +frontend/src/pages/ +└── Blueprint/ # NEW page + ├── BlueprintOverview.tsx # Health score, cluster grid, quick actions + ├── ClusterDetail.tsx # Single cluster view: hub, supporting content, keywords, links + ├── AttributeManager.tsx # View/edit attributes, see taxonomy sync status + └── ExecutionPlan.tsx # Phase 1-4 execution plan, what to build next +``` + +**Sidebar addition:** +``` +WORKFLOW + ├── Planner + ├── Writer + ├── Automation + ├── Blueprint (NEW — if site has active blueprint, always visible) + ├── Linker (if linker_enabled) + └── Optimizer (if optimizer_enabled) +``` + +--- + +## 11. Phase 9: SAG Interlinking — Linker Module Evolution {#11-phase-9-sag-interlinking} + +### 11.1 What This Phase Delivers + +The existing Linker module (currently INACTIVE behind `linker_enabled` flag) evolves from generic content-similarity linking to SAG-aware deterministic linking. This implements Doc 3 — Interlinking Specification. + +### 11.2 Backend: New Models for Interlinking + +Add to `sag/models.py`: + +```python +class SAGLink(AccountBaseModel): + """Individual internal link tracked by the SAG interlinking system.""" + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE, related_name='links') + source_content = models.ForeignKey('writer.Content', on_delete=models.CASCADE, related_name='outbound_sag_links') + target_content = models.ForeignKey('writer.Content', on_delete=models.CASCADE, null=True, blank=True, related_name='inbound_sag_links') + target_url = models.URLField(blank=True, help_text='For term pages or external targets') + link_type = models.CharField(max_length=30, choices=[ + ('hub_upward', 'Supporting → Hub'), + ('hub_downward', 'Hub → Supporting'), + ('sibling', 'Sibling within cluster'), + ('cross_cluster', 'Cross-cluster hub ↔ hub'), + ('taxonomy_contextual', 'Term page → cluster hubs'), + ('breadcrumb', 'Breadcrumb structural'), + ('related_content', 'Related reading cross-cluster'), + ]) + anchor_text = models.CharField(max_length=300) + placement_zone = models.CharField(max_length=30, choices=[ + ('in_body', 'In Body'), + ('related_section', 'Related Section'), + ('breadcrumb', 'Breadcrumb'), + ('guide_contents', 'Guide Contents'), + ]) + status = models.CharField(max_length=20, choices=[ + ('planned', 'Planned'), + ('injected', 'Injected into content'), + ('published', 'Published on WordPress'), + ('broken', 'Broken'), + ('removed', 'Removed'), + ], default='planned') + score = models.FloatField(default=0.0) + injected_at = models.DateTimeField(null=True, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + +class SAGLinkAudit(AccountBaseModel): + """Periodic link audit snapshot.""" + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE) + audit_date = models.DateTimeField(auto_now_add=True) + total_links = models.IntegerField(default=0) + missing_mandatory = models.IntegerField(default=0) + orphan_pages = models.IntegerField(default=0) + broken_links = models.IntegerField(default=0) + over_linked_pages = models.IntegerField(default=0) + cluster_scores = models.JSONField(default=dict) + recommendations = models.JSONField(default=list) +``` + +### 11.3 Backend: Linking Services + +``` +sag/services/linking_service.py # NEW +``` + +**Functions:** +- `generate_links_for_content(content)` → creates SAGLink records for a newly generated content piece +- `audit_cluster_links(cluster)` → score the cluster's link completeness (0-100) +- `audit_site_links(blueprint)` → full site link audit +- `find_missing_mandatory_links(blueprint)` → list of mandatory links that don't exist +- `suggest_anchor_text(source_content, target_content, link_type)` → AI-generated anchor text variants + +**Link generation rules (from Doc 3):** + +| Link Type | Rule | Mandatory? | Max Count | +|-----------|------|-----------|-----------| +| hub_upward | Every supporting blog → its cluster hub | YES | 1 per blog | +| hub_downward | Every hub → all its published supporting content | YES | All | +| sibling | Supporting ↔ supporting within same cluster | No | 2 per article | +| cross_cluster | Hub ↔ hub sharing attribute value | No | 2 per hub | +| taxonomy_contextual | Term page → all hubs using that value | YES | All | +| breadcrumb | Every page has breadcrumb path | YES | 1 chain | +| related_content | Supporting → content in other clusters | No | 2-3 | + +### 11.4 Backend: Pipeline Integration (Stage 8) + +**Add Stage 8 to automation pipeline:** + +```python +# business/automation/stages/stage_8_link_generation.py # NEW + +# After Stage 7 (images generated): +# 1. Load blueprint context for this content +# 2. Generate required SAGLink records per rules +# 3. Inject link HTML into content body +# 4. Content enters review queue with links already present +``` + +Modify `business/automation/pipeline.py` to include Stage 8 when `linker_enabled` AND blueprint exists. + +### 11.5 Frontend: Linker Page Evolution + +**Location:** `pages/Linker/` — existing but INACTIVE + +When `linker_enabled` is activated and blueprint exists, the Linker page shows: + +``` +frontend/src/pages/Linker/ +├── LinkerOverview.tsx # REPLACE existing — SAG link dashboard +│ ├── ClusterLinkCoverage.tsx # Table: clusters × link scores +│ ├── SiteLinkMap.tsx # Visual: clusters as nodes, links as edges +│ ├── LinkAuditDashboard.tsx # Stats: total links, missing, broken, orphans +│ └── GapAnalysisExport.tsx # Download link gap report +├── LinkDetail.tsx # Single link view: source, target, anchor, status +└── LinkAudit.tsx # Audit history with snapshots +``` + +### 11.6 Backend: Celery Tasks for Linking + +```python +# sag/tasks.py — add: + +@shared_task +def generate_links_for_published_content(content_id): + """After content publishes, generate/update SAG links.""" + pass + +@shared_task +def run_link_audit(blueprint_id): + """Weekly link audit for a blueprint.""" + pass + +@shared_task +def check_broken_links(blueprint_id): + """Check all published SAGLinks for broken targets.""" + pass +``` + +--- + +## 12. Phase 10: External Backlink Campaign Module {#12-phase-10-external-backlink-campaigns} + +### 12.1 What This Phase Delivers + +Automated backlink campaign generation from SAG blueprints. Implements Doc 4 — External Backlink Campaign Specification. New models, new UI, external API integrations (FatGrid, PR distribution). + +### 12.2 Backend: New Models + +Add to `sag/models.py`: + +```python +class CountryMarketProfile(models.Model): + """Country-specific campaign parameters. Admin-editable.""" + country_code = models.CharField(max_length=5, primary_key=True) + country_name = models.CharField(max_length=100) + competition_floor = models.CharField(max_length=20) + profile_data = models.JSONField(help_text='Full country profile: DR targets, budgets, link mix, anchor mix, velocity, quality thresholds, KPI milestones') + is_active = models.BooleanField(default=True) + updated_at = models.DateTimeField(auto_now=True) + +class SAGCampaign(AccountBaseModel): + """A backlink campaign generated from a SAG blueprint for a specific market.""" + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE, related_name='campaigns') + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE) + country_code = models.CharField(max_length=5) + status = models.CharField(max_length=20, choices=[ + ('draft', 'Draft'), ('active', 'Active'), + ('paused', 'Paused'), ('completed', 'Completed'), + ], default='draft') + tier_assignments = models.JSONField(default=dict, help_text='{content_id: tier}') + total_links_target = models.IntegerField(default=0) + total_budget_estimate = models.JSONField(default=dict, help_text='{min: X, max: Y}') + timeline_months = models.IntegerField(default=0) + monthly_plan = models.JSONField(default=list) + anchor_text_plan = models.JSONField(default=dict) + current_month = models.IntegerField(default=0) + kpi_data = models.JSONField(default=dict) + started_at = models.DateTimeField(null=True, blank=True) + completed_at = models.DateTimeField(null=True, blank=True) + +class SAGBacklink(AccountBaseModel): + """Individual backlink tracked within a campaign.""" + id = models.UUIDField(primary_key=True, default=uuid4) + blueprint = models.ForeignKey(SAGBlueprint, on_delete=models.CASCADE) + campaign = models.ForeignKey(SAGCampaign, on_delete=models.CASCADE, related_name='backlinks') + target_content = models.ForeignKey('writer.Content', on_delete=models.CASCADE, null=True, blank=True) + target_url = models.URLField() + target_tier = models.CharField(max_length=5) + source_url = models.URLField(blank=True) + source_domain = models.CharField(max_length=200, blank=True) + source_dr = models.IntegerField(null=True, blank=True) + source_traffic = models.IntegerField(null=True, blank=True) + anchor_text = models.CharField(max_length=300, blank=True) + anchor_type = models.CharField(max_length=30, blank=True) + link_type = models.CharField(max_length=30, blank=True) + marketplace = models.CharField(max_length=100, blank=True) + cost = models.DecimalField(max_digits=10, decimal_places=2, default=0) + quality_score = models.FloatField(default=0.0) + country_relevant = models.BooleanField(default=False) + date_built = models.DateField(null=True, blank=True) + date_live = models.DateField(null=True, blank=True) + date_last_checked = models.DateField(null=True, blank=True) + status = models.CharField(max_length=20, choices=[ + ('ordered', 'Ordered'), ('pending', 'Pending'), ('live', 'Live'), + ('dead', 'Dead'), ('removed', 'Removed'), ('replaced', 'Replaced'), + ], default='ordered') + notes = models.TextField(blank=True) + +class SAGCampaignSnapshot(models.Model): + """Monthly KPI snapshot for a campaign.""" + id = models.UUIDField(primary_key=True, default=uuid4) + campaign = models.ForeignKey(SAGCampaign, on_delete=models.CASCADE, related_name='snapshots') + snapshot_date = models.DateField() + kpi_values = models.JSONField(help_text='All 18+ KPI metrics for this month') + comparison_to_previous = models.JSONField(default=dict) +``` + +### 12.3 Backend: Campaign Services + +``` +sag/services/campaign_service.py # NEW +``` + +**Functions:** +- `generate_campaign(blueprint, country_code, budget_override=None)` → creates SAGCampaign with full plan +- `assign_tiers(blueprint, clusters)` → auto-classify pages into T1-T5 +- `generate_monthly_plan(campaign)` → month-by-month execution plan +- `generate_anchor_text_plan(campaign)` → pre-generated anchors per target page +- `calculate_budget(campaign)` → budget estimate from link counts × cost ranges +- `detect_tipping_point(campaign)` → check if authority tipping point indicators are met + +### 12.4 Backend: External API Integrations + +``` +sag/integrations/ # NEW +├── __init__.py +├── fatgrid.py # FatGrid API client (publisher discovery, pricing) +├── pr_distribution.py # PRNews.io / EIN Presswire / Linking News +└── ahrefs.py # Ahrefs API (DR/DA tracking, lost links) +``` + +These integrations are optional — campaigns can be generated and tracked without them. The APIs enrich the campaign with real marketplace data and automated monitoring. + +### 12.5 Frontend: Campaign UI + +``` +frontend/src/pages/ +└── Campaigns/ # NEW page (or sub-page of Linker) + ├── CampaignOverview.tsx # Campaign dashboard: progress, budget, current month + ├── CampaignGenerator.tsx # Generate new campaign wizard + ├── MonthlyPlan.tsx # This month's targets vs actual + ├── LinkTracker.tsx # Filterable table of all backlinks + ├── TierBreakdown.tsx # T1-T5 progress visualization + ├── KPIDashboard.tsx # Monthly trend charts (DR, traffic, keywords) + ├── TippingPointDetector.tsx # Authority tipping point indicators + └── LinkOpportunities.tsx # FatGrid publisher search (if integrated) +``` + +**Sidebar addition:** +``` +WORKFLOW + ├── Planner + ├── Writer + ├── Automation + ├── Blueprint + ├── Linker (internal links) + ├── Campaigns (NEW — external backlink campaigns, if campaign_enabled) + └── Optimizer +``` + +**Feature flag:** `campaign_enabled` — follows same pattern as `linker_enabled` via GlobalModuleSettings. + +--- + +## 13. Frontend Navigation — Updated Sidebar {#13-frontend-navigation--ui-map} + +After all SAG phases are complete, the sidebar becomes: + +``` +Dashboard (with SAG health + blueprint progress widgets) +SETUP + ├── Add Keywords (now shows "optional" when blueprint active) + ├── Content Settings + ├── Sites (setup wizard now includes Step 3 Site Builder) + └── Thinker (admin only) +WORKFLOW + ├── Planner (Keywords → Clusters → Ideas — enhanced with blueprint source) + ├── Writer (Queue → Drafts → Images → Review → Published — shows cluster context) + ├── Automation (7→8 stages when linker active, SAG mode indicator) + ├── Blueprint (NEW — health, clusters, attributes, execution plan) + ├── Linker (SAG-aware internal linking — when linker_enabled) + ├── Campaigns (External backlink campaigns — when campaign_enabled) + └── Optimizer (when optimizer_enabled) +ACCOUNT + ├── Account Settings + ├── Plans & Billing + ├── Usage + └── AI Models (admin only) +ADMIN (admin only) + └── Sector Templates (manage attribute templates) +HELP + └── Help & Docs +``` + +--- + +## 14. API Endpoint Registry {#14-api-endpoint-registry} + +Complete list of new API endpoints introduced across all phases: + +### SAG Core (Phase 1-3) +``` +GET /api/v1/sag/blueprints/ # List blueprints for current site +POST /api/v1/sag/blueprints/ # Create blueprint (admin/internal) +GET /api/v1/sag/blueprints/{id}/ # Blueprint detail with attributes + clusters +POST /api/v1/sag/blueprints/{id}/confirm/ # Draft → Active +POST /api/v1/sag/blueprints/{id}/archive/ # Active → Archived +POST /api/v1/sag/blueprints/{id}/regenerate/ # Create new version +GET /api/v1/sag/blueprints/{id}/health_check/ # Run health check +GET /api/v1/sag/attributes/ # List attributes for current blueprint +GET /api/v1/sag/clusters/ # List clusters for current blueprint +GET /api/v1/sag/clusters/{id}/ # Cluster detail with keywords, content, links +GET /api/v1/sag/templates/ # Admin: list sector templates +POST /api/v1/sag/templates/ # Admin: create template +PUT /api/v1/sag/templates/{id}/ # Admin: update template +``` + +### Site Builder Wizard (Phase 4) +``` +POST /api/v1/sag/wizard/generate-attributes/ # Industry+Sectors → attribute framework +POST /api/v1/sag/wizard/populate-attributes/ # Attributes+BusinessData → populated attributes +POST /api/v1/sag/wizard/generate-blueprint/ # Populated attributes → full blueprint +POST /api/v1/sag/wizard/confirm-blueprint/ # Blueprint → active, trigger taxonomy creation +``` + +### Existing Site Analysis (Phase 7) +``` +POST /api/v1/sag/analysis/extract-attributes/ # Site data → discovered attributes +POST /api/v1/sag/analysis/generate-gap-report/ # Blueprint + site data → gap report +POST /api/v1/sag/analysis/auto-tag-products/ # AI product attribute assignment +``` + +### Interlinking (Phase 9) +``` +GET /api/v1/sag/links/ # List all SAG links for blueprint +POST /api/v1/sag/links/generate/ # Generate links for content +GET /api/v1/sag/links/audit/ # Run link audit +GET /api/v1/sag/links/audit/history/ # Audit snapshots +GET /api/v1/sag/links/missing/ # Missing mandatory links +``` + +### Backlink Campaigns (Phase 10) +``` +GET /api/v1/sag/campaigns/ # List campaigns +POST /api/v1/sag/campaigns/generate/ # Generate campaign from blueprint + country +GET /api/v1/sag/campaigns/{id}/ # Campaign detail +PATCH /api/v1/sag/campaigns/{id}/ # Update status, adjust plan +GET /api/v1/sag/campaigns/{id}/monthly/ # Current month plan +GET /api/v1/sag/campaigns/{id}/kpi/ # KPI dashboard data +GET /api/v1/sag/campaigns/{id}/tipping-point/ # Tipping point indicators +GET /api/v1/sag/backlinks/ # List all backlinks for campaign +POST /api/v1/sag/backlinks/ # Log new backlink +PATCH /api/v1/sag/backlinks/{id}/ # Update backlink status +GET /api/v1/sag/countries/ # List country market profiles +GET /api/v1/sag/fatgrid/search/ # FatGrid publisher search (proxy) +``` + +--- + +## 15. AI Function Registry {#15-ai-function-registry} + +New AI functions to register in `ai/registry.py`: + +| Function Key | Location | Input | Output | +|-------------|----------|-------|--------| +| `discover_sector_attributes` | `sag/ai_functions/attribute_discovery.py` | Industry, sector, site_type | Attribute framework JSON | +| `extract_site_attributes` | `sag/ai_functions/attribute_extraction.py` | Raw site data | Discovered attributes with confidence | +| `populate_attributes` | `sag/ai_functions/attribute_population.py` | Attributes + business data | Populated attribute values | +| `form_clusters` | `sag/ai_functions/cluster_formation.py` | Populated attributes, sector | Clusters with types | +| `generate_keywords` | `sag/ai_functions/keyword_generation.py` | Clusters + templates | Per-cluster keyword arrays | +| `plan_content` | `sag/ai_functions/content_planning.py` | Clusters + keywords + existing content | Content ideas with Structure + Type | +| `generate_anchor_text` | `sag/ai_functions/anchor_text.py` | Source, target, link_type, cluster | Anchor text variants | + +All functions use the existing `AIEngine → Function → Provider` pattern. They're registered the same way as `AutoClusterKeywords` and `GenerateContentIdeas`. + +--- + +## 16. Celery Task Registry {#16-celery-task-registry} + +New periodic and on-demand tasks: + +| Task | Schedule | Trigger | Location | +|------|----------|---------|----------| +| `run_blueprint_health_check` | Weekly (Celery Beat) | Also manual from dashboard | `sag/tasks.py` | +| `check_blueprint_evolution_triggers` | Weekly (Celery Beat) | — | `sag/tasks.py` | +| `generate_links_for_published_content` | On demand | After content publishes | `sag/tasks.py` | +| `run_link_audit` | Weekly (Celery Beat) | Also manual from Linker | `sag/tasks.py` | +| `check_broken_links` | Weekly (Celery Beat) | — | `sag/tasks.py` | +| `check_backlink_status` | Weekly (Celery Beat) | — | `sag/tasks.py` | +| `generate_campaign_snapshot` | Monthly (Celery Beat) | — | `sag/tasks.py` | +| `detect_tipping_point` | Monthly (Celery Beat) | After snapshot | `sag/tasks.py` | + +--- + +## 17. Feature Flag Registry {#17-feature-flag-registry} + +| Flag | Controls | Default | Phase | +|------|---------|---------|-------| +| `sag_enabled` | Blueprint generation, wizard Step 3, blueprint-aware pipeline | `False` | Phase 1 | +| `linker_enabled` | Linker module, SAG link generation, link audit | `False` (exists) | Phase 9 | +| `campaign_enabled` | External backlink campaigns, FatGrid integration | `False` | Phase 10 | + +All flags follow existing pattern: `GlobalModuleSettings` (platform-wide) + `ModuleEnableSettings` (per-account). Checked in sidebar rendering and API permission classes. + +When `sag_enabled` is `False`: +- Setup wizard skips Step 3 (current behavior preserved) +- Pipeline runs in legacy mode (current behavior preserved) +- Blueprint page hidden from sidebar +- All SAG API endpoints return 403 + +--- + +## 18. Cross-Reference: What Feeds What {#18-cross-reference} + +``` +SectorAttributeTemplate + └── feeds → Blueprint generation (Layer 1 attributes) + +SAGBlueprint + ├── feeds → Content pipeline (idea generation, task context, type-specific prompts) + ├── feeds → Taxonomy creation (plugin creates WP taxonomies) + ├── feeds → Linker module (link rules derived from cluster structure) + ├── feeds → Campaign module (tier assignments from cluster types + keyword volumes) + └── feeds → Health monitoring (completeness tracking) + +SAGCluster + ├── feeds → Content Ideas (hub + supporting content per cluster) + ├── feeds → Keywords (auto-generated from attribute intersections) + ├── feeds → Internal links (hub↔supporting, cross-cluster, taxonomy contextual) + └── feeds → Backlink tiers (T1-T5 assignment based on cluster type + volume) + +SAGLink + ├── feeds → Content HTML (links injected before publish) + ├── feeds → Link audit (health scores, gap analysis) + └── feeds → Blueprint health score (link coverage component) + +SAGCampaign + ├── feeds → KPI dashboard (monthly snapshots, trend charts) + ├── feeds → Tipping point detection (compares metrics vs country thresholds) + └── feeds → Blueprint health score (backlink coverage component) + +GSC Data (from Consolidated Module Plans — separate implementation) + ├── feeds → Campaign KPI dashboard (organic traffic, keywords, impressions) + ├── feeds → Tipping point detection (pages ranking without backlinks) + └── feeds → Blueprint health (indexed pages, crawl status) +``` + +--- + +## Reference Documents + +This guide draws from and should be used alongside: + +| Document | Purpose | Location | +|----------|---------|----------| +| **SAG-Master-Document.md** | Pure SAG methodology — clustering rules, dimensional philosophy | Project knowledge | +| **SAG-IGNY8-Implementation.md** | Three-layer architecture, two entry scenarios, data models, pipeline integration | Project knowledge | +| **SAG-Doc3-Interlinking-Specification-PLAN.md** | Internal linking rules, 7 link types, authority flow, scoring | Project knowledge | +| **SAG-Doc4-External-Backlink-Campaign-PLAN.md** | Campaign generation, country profiles, FatGrid/PR integration, KPI tracking | Project knowledge | +| **IGNY8-Current-State.md** | Complete current platform state — all file paths, models, modules, navigation | Project knowledge | +| **SAG-Niche-Definition-Process.docx** | Cluster formation rules, max 50 clusters, hub + supporting structure | Project knowledge | +| **IGNY8-Industry-Sector-Master-List.md** | All industries and sectors in IGNY8 | Project knowledge | +| **SAGIndustry01HealthcareMedical.xlsx** | Reference template format for sector attribute frameworks | Project knowledge | + +--- + +*End of Doc A — SAG Architecture Development Guide* diff --git a/docs/plans/final-dev-guides-of-futute-implementation/DocB-Platform-Modules-Dev-Guide.md b/docs/plans/final-dev-guides-of-futute-implementation/DocB-Platform-Modules-Dev-Guide.md new file mode 100644 index 00000000..04385add --- /dev/null +++ b/docs/plans/final-dev-guides-of-futute-implementation/DocB-Platform-Modules-Dev-Guide.md @@ -0,0 +1,1700 @@ +# Doc B — IGNY8 Platform Modules: Development Guide for Claude Code + +**Version:** 1.0 +**Date:** March 2026 +**For:** Claude Code (Opus 4.6) in VSCode on IGNY8 repo +**Purpose:** Step-by-step implementation guide for all IGNY8 platform module enhancements — Content Types Writing, Taxonomy & Term Content, Optimizer, GSC Integration, Rich Schema & SERP Enhancement, Socializer, and Video Creator +**Rule:** Nothing currently working breaks. All new functionality uses the existing pipeline pattern. All new modules use feature flags. Existing Writer/Planner/Automation pages are enhanced, not replaced. +**Dependency:** Doc A (SAG Architecture) provides the blueprint, cluster, and attribute data that several modules here consume. Content Types Writing and Taxonomy & Term Content should ideally complete before Optimizer, but GSC and Rich Schema can run in parallel. + +--- + +## Table of Contents + +1. [System Context — Current Pipeline & Module Structure](#1-system-context) +2. [Implementation Sequence](#2-implementation-sequence) +3. [Module 1: Content Types Writing](#3-content-types-writing) +4. [Module 2: Taxonomy & Term Content](#4-taxonomy--term-content) +5. [Module 3: Optimizer Module](#5-optimizer-module) +6. [Module 4: GSC Integration](#6-gsc-integration) +7. [Module 5: Rich Schema & SERP Enhancement](#7-rich-schema) +8. [Module 6: Socializer](#8-socializer) +9. [Module 7: Video Creator](#9-video-creator) +10. [Updated Automation Pipeline — All Stages](#10-updated-automation-pipeline) +11. [Updated Navigation & Sidebar](#11-updated-navigation) +12. [Complete API Endpoint Registry](#12-api-endpoints) +13. [Complete AI Function Registry](#13-ai-functions) +14. [Complete Celery Task Registry](#14-celery-tasks) +15. [Feature Flag Registry](#15-feature-flags) +16. [Credit Cost Summary](#16-credit-costs) +17. [Cross-Module Dependencies](#17-cross-dependencies) + +--- + +## 1. System Context — Current Pipeline & Module Structure {#1-system-context} + +### 1.1 Current Content Pipeline (What Exists) + +``` +Stage 1: Process New Keywords → modules/planner/ + business/planning/ +Stage 2: AI Cluster Keywords → ai/functions/auto_cluster.py +Stage 3: Generate Content Ideas → ai/functions/generate_ideas.py + modules/planner/ +Stage 4: Create Writer Tasks → modules/writer/ +Stage 5: Generate Article Content → ai/functions/generate_content.py + business/content/ +Stage 6: Extract Image Prompts → ai/functions/generate_image_prompts.py +Stage 7: Generate Images → ai/functions/generate_images.py → Review Queue +``` + +All stages execute via Celery tasks defined in `tasks/`. Automation orchestration lives in `business/automation/`. Configuration per site is in `AutomationConfig`. + +### 1.2 Current Content Model Fields (Relevant) + +```python +# modules/writer/models.py — Content model (simplified) +class Content(SiteSectorBaseModel): + task = ForeignKey(Tasks) + title = CharField() + slug = SlugField() + content = TextField() # Full HTML + meta_title = CharField() + meta_description = TextField() + status = CharField() # queue, draft, review, published + content_type = CharField() # Currently: 'post', 'page' + word_count = IntegerField() + # ... images, keywords, publishing fields +``` + +### 1.3 Current Inactive Modules + +| Module | Backend | API | Frontend | Flag | +|--------|---------|-----|----------|------| +| Linker | `business/linking/` | `modules/linker/` | `pages/Linker/`, `api/linker.api.ts` | `linker_enabled` | +| Optimizer | `business/optimization/` | `modules/optimizer/` | `pages/Optimizer/`, `api/optimizer.api.ts` | `optimizer_enabled` | + +### 1.4 Existing Prompt System + +Prompts are stored in `PromptTemplate` model or defaults in code. Templates exist for: `auto_cluster`, `generate_ideas`, `generate_content`, `generate_image_prompts`, `optimize_content` (pending). Users customize via Settings → Prompts (Thinker module). + +### 1.5 Existing Integration Architecture + +WordPress communication uses: +- `Site.wp_api_key` for authentication +- Webhook endpoints for sync (plugin → IGNY8 and IGNY8 → plugin) +- `business/integration/` for sync services +- `modules/integration/` for API endpoints +- Plugin file: `data/site-collection.php` for data gathering + +### 1.6 Existing Credit System + +All AI operations deduct credits via `CreditService.check_credits()` → execute → `CreditService.deduct_credits_for_operation()`. Costs configured per model in `AIModelConfig`. + +--- + +## 2. Implementation Sequence {#2-implementation-sequence} + +``` +MODULE 1 ─── Content Types Writing (FIRST — foundation for all others) + │ Extends Writer pipeline with new content types and structures. + │ No new module — enhances existing Planner + Writer + Publisher. + │ +MODULE 2 ─── Taxonomy & Term Content + │ Depends on Module 1 for content structures. + │ Requires taxonomy sync restoration. + │ Enhances Planner + Writer + Publisher + Integration. + │ +MODULE 3 ─── Optimizer (activate existing module) + │ Depends on Module 1+2 for content type support. + │ Benefits from SAG cluster mapping (Doc A Phase 5). + │ Activates optimizer_enabled flag. + │ +MODULE 4 ─── GSC Integration (CAN PARALLEL with 1-3) + │ Independent of content pipeline changes. + │ New module entirely: OAuth, URL Inspection, metrics. + │ +MODULE 5 ─── Rich Schema & SERP Enhancement (CAN PARALLEL with 4) + │ Enhances content pipeline Stage 5 + adds retroactive engine. + │ Benefits from Module 1 (content type classification). + │ +MODULE 6 ─── Socializer + │ Depends on published content (any type from Module 1+2). + │ New module: OAuth, platform connections, scheduling. + │ New automation Stage 8. + │ +MODULE 7 ─── Video Creator + Depends on Module 6 infrastructure (OAuth, scheduling, media storage). + New module: script generation, TTS, video assembly. + New automation Stage 9. +``` + +**Parallel tracks:** +- GSC (Module 4) is fully independent — start anytime +- Rich Schema (Module 5) can start alongside GSC +- Socializer OAuth/platform connections can start while earlier modules finish + +--- + +## 3. Module 1: Content Types Writing {#3-content-types-writing} + +### 3.1 What This Module Delivers + +IGNY8 currently writes blog posts (`content_type='post'`). This module extends the Writer to produce pages, products (WooCommerce), services, company pages, taxonomy landing pages, and cluster hub pages — all through the same pipeline. + +### 3.2 Backend: Content Type Expansion + +**Modify:** `modules/writer/models.py` — extend `content_type` choices on Content model + +```python +# Add new choices to Content.content_type: +CONTENT_TYPE_CHOICES = [ + ('post', 'Blog Post'), # Existing + ('page', 'Page'), # Existing (limited use) + ('product', 'Product Page'), # NEW + ('service', 'Service Page'), # NEW + ('company_page', 'Company Page'), # NEW + ('taxonomy_landing', 'Taxonomy Landing'), # NEW + ('cluster_hub', 'Cluster Hub Page'), # NEW + ('comparison', 'Comparison Page'), # NEW + ('brand_page', 'Brand Page'), # NEW +] +``` + +**Add new field:** `content_structure` on Content model (or extend existing structure field) + +```python +# Add to Content model: +content_structure = models.CharField( + max_length=30, null=True, blank=True, + choices=[ + # Blog structures (existing, now explicit) + ('guide_tutorial', 'Guide/Tutorial'), + ('comparison', 'Comparison'), + ('review', 'Review'), + ('how_to', 'How To'), + ('question', 'Question/Answer'), + ('top_listicle', 'Top Listicle'), + # Page structures (NEW) + ('landing_page', 'Landing Page'), + ('about_page', 'About Page'), + ('contact_page', 'Contact Page'), + # Product structures (NEW) + ('product_single', 'Single Product'), + ('product_collection', 'Product Collection'), + # Service structures (NEW) + ('service_single', 'Single Service'), + ('service_area', 'Service Area Page'), + # Company structures (NEW) + ('company_about', 'Company About'), + ('company_team', 'Company Team'), + ('company_careers', 'Company Careers'), + # Taxonomy structures (NEW) + ('category_archive', 'Category Archive'), + ('tag_archive', 'Tag Archive'), + ('attribute_archive', 'Attribute Archive'), + ('cluster_hub', 'Cluster Hub'), + ] +) +``` + +**Modify:** `modules/planner/models.py` — extend ContentIdea model with same fields + +```python +# Add to ContentIdea model: +content_type = models.CharField(max_length=30, null=True, blank=True) # Same choices as Content +content_structure = models.CharField(max_length=30, null=True, blank=True) +``` + +**Modify:** `modules/writer/models.py` — extend Tasks model + +```python +# Add to Tasks model: +content_type = models.CharField(max_length=30, default='post') +content_structure = models.CharField(max_length=30, null=True, blank=True) +``` + +### 3.3 Backend: Type-Specific Prompt Templates + +**Location:** Add to existing PromptTemplate system or as defaults in `ai/functions/generate_content.py` + +Each content_type × content_structure combination gets a distinct prompt. The prompt includes type-specific section requirements: + +| Content Type | Required Sections in Prompt | +|-------------|---------------------------| +| **product** | Features/benefits, specs table, comparison to alternatives, FAQs, CTA, product schema placeholders | +| **service** | Service overview, process steps, outcomes/results, FAQs, local SEO sections (if location-based), CTA | +| **company_page** | Brand mission/values, history, team bios (if team page), FAQ, media/press block | +| **taxonomy_landing** | Intro + topical definition, key subtopics with internal link placeholders, related items, FAQ section | +| **cluster_hub** | Comprehensive guide introduction, section per supporting topic, product/service roundup, FAQ, internal linking sections | +| **comparison** | Head-to-head comparison table, pros/cons per item, winner recommendation, FAQ | + +**Register new prompt templates:** +```python +# In PromptTemplate seeding or defaults: +'generate_content_product' # Product page prompt +'generate_content_service' # Service page prompt +'generate_content_company' # Company page prompt +'generate_content_taxonomy_landing' # Taxonomy landing prompt +'generate_content_cluster_hub' # Cluster hub prompt +'generate_content_comparison' # Comparison page prompt +``` + +### 3.4 Backend: Type-Specific Idea Generation + +**Modify:** `ai/functions/generate_ideas.py` — enhance `GenerateContentIdeas` + +When generating ideas, the system now considers content_type: +- Product ideas: features/specs/benefits angle, "Best X for Y" format +- Service ideas: process/outcomes angle, "How [Service] Works" format +- Company page ideas: mission/team/careers angle +- Taxonomy landing ideas: topical overview, "Complete Guide to [Term]" format + +The existing function stays but gets an additional parameter: `target_content_type`. If provided, idea generation is type-aware. If not provided (legacy), defaults to blog post ideas. + +### 3.5 Backend: Publishing Enhancement + +**Modify:** `business/publishing/` — extend publishing to handle content types + +```python +# business/publishing/wordpress_publisher.py — extend publish logic: + +def publish_content(content): + if content.content_type == 'post': + # Existing: publish as WordPress post + pass + elif content.content_type == 'page': + # Publish as WordPress page + pass + elif content.content_type == 'product': + # Publish as WooCommerce product (requires WooCommerce API) + pass + elif content.content_type == 'service': + # Publish as custom post type 'service' (requires theme/plugin CPT) + pass + elif content.content_type == 'taxonomy_landing': + # Publish as term description content (Module 2 handles this) + pass + elif content.content_type == 'cluster_hub': + # Publish as WordPress page with hub template + pass +``` + +**Plugin side:** The IGNY8 Bridge plugin needs enhanced content receiving: +``` +igny8-plugin/includes/modules/content-sync/ +├── class-content-mapper.php # MODIFY: map IGNY8 content_type to WP post type +``` + +Mapping: +| IGNY8 content_type | WordPress post_type | Template | +|-------------------|--------------------|---------| +| post | post | Standard | +| page | page | Default page | +| product | product (WooCommerce) | Product template | +| service | service (CPT from theme) | Service template | +| company_page | page | Company page template | +| taxonomy_landing | term description | Term archive template | +| cluster_hub | page | Hub page template | +| comparison | post | Standard (with comparison CSS) | + +### 3.6 Frontend: Writer UI Enhancement + +**Location:** `pages/Writer/` — enhance existing views + +**Task Creation — Add content type selector:** +``` +pages/Writer/ +├── components/ +│ ├── TaskCreationForm.tsx # MODIFY: add content_type dropdown + content_structure dropdown +│ └── ContentTypeSelector.tsx # NEW: visual card selector for content type +``` + +When creating a new task (manual mode), user sees: +- Content Type dropdown: Blog Post, Page, Product, Service, Company Page, Taxonomy Landing, Cluster Hub, Comparison +- Content Structure dropdown: dynamically filtered based on content_type selection +- Existing fields (title, keywords, cluster, sector) remain unchanged + +**Content List — Show type badge:** +``` +pages/Writer/ +├── components/ +│ └── ContentListItem.tsx # MODIFY: add content_type badge next to title +``` + +Each content item in Queue/Drafts/Review/Published shows a small badge: "Post", "Product", "Hub", "Service", etc. + +**Ideas List — Show type:** +``` +pages/Planner/ +├── components/ +│ └── IdeaListItem.tsx # MODIFY: show content_type and content_structure +``` + +### 3.7 Frontend: No New Pages + +Module 1 adds NO new pages to the sidebar. Everything happens within existing Planner and Writer pages. The changes are: +- Dropdowns added to task creation +- Badges added to list items +- Type-specific preview in content review + +--- + +## 4. Module 2: Taxonomy & Term Content {#4-taxonomy--term-content} + +### 4.1 What This Module Delivers + +Every taxonomy term (WordPress categories, tags, WooCommerce product categories/attributes, custom taxonomies from SAG) becomes a rich SEO landing page generated through the same pipeline as posts. + +### 4.2 Backend: Restore Taxonomy Sync + +**Current state:** Taxonomy sync was partially implemented then removed ("legacy removed"). `ContentTaxonomy` model exists. WordPress client knows how to fetch categories/tags/WooCommerce attributes. + +**Restore and enhance in:** `business/integration/` + +```python +# business/integration/taxonomy_sync_service.py # RESTORE/REWRITE + +class TaxonomySyncService: + def sync_taxonomies(self, site): + """Fetch all taxonomies + terms from WordPress and sync to ContentTaxonomy.""" + # 1. Fetch via plugin API: categories, tags, WooCommerce product_cat, + # product_tag, all pa_* attributes, custom taxonomies (from SAG) + # 2. Create/update ContentTaxonomy records + # 3. Map terms to clusters where possible (using SAG blueprint if active) + pass + + def publish_term_content(self, content_taxonomy, content): + """Push generated content back to WordPress term description.""" + # 1. Content → term description HTML + # 2. POST to plugin endpoint: /wp-json/igny8/v1/terms/{term_id}/content + # 3. Update ContentTaxonomy sync status + pass +``` + +**Plugin endpoint needed:** +``` +POST /wp-json/igny8/v1/terms/{term_id}/content +Body: {description: "HTML content", meta: {igny8_term_content, igny8_term_faq, ...}} +``` + +### 4.3 Backend: Term-to-Cluster Mapping Service + +```python +# business/planning/cluster_mapping_service.py # NEW + +class ClusterMappingService: + def map_term_to_cluster(self, term_name, term_description, site): + """Match a taxonomy term to the best SAG cluster.""" + # If SAG blueprint active: match term to cluster by attribute value overlap + # If no blueprint: use AI semantic similarity to existing clusters + # Return: cluster_id, confidence_score + pass + + def bulk_map_terms(self, terms, site): + """Map all terms for a site to clusters.""" + pass +``` + +### 4.4 Backend: Term Content Generation + +The key insight: term content generation follows the SAME pipeline as post content. The difference is in content_type and publishing destination. + +**Idea generation for terms:** +```python +# business/planning/ — extend idea generation + +def generate_term_ideas(site, terms): + """For each taxonomy term without content, create a ContentIdea.""" + for term in terms: + idea = ContentIdea( + title=f"Complete Guide to {term.name}", + content_type='taxonomy_landing', + content_structure='category_archive', # or tag_archive, attribute_archive + cluster=term.mapped_cluster, + idea_source='sag_blueprint' if site.sag_blueprint_id else 'keyword_clustering', + # ... sector, keywords + ) +``` + +**Task creation and content generation** use the same pipeline as Module 1 — the content_type='taxonomy_landing' selects the appropriate prompt template. + +**Publishing** goes to term description instead of post content (handled by `TaxonomySyncService.publish_term_content()`). + +### 4.5 Backend: ContentTaxonomy Model Enhancement + +**Modify:** existing `ContentTaxonomy` model (if it exists) or create: + +```python +# modules/planner/models.py or modules/integration/models.py + +class ContentTaxonomy(SiteSectorBaseModel): + # Existing fields... + external_taxonomy = models.CharField(max_length=100) # 'category', 'post_tag', 'pa_color', etc. + external_term_id = models.IntegerField() + name = models.CharField(max_length=200) + slug = models.SlugField(max_length=200) + description = models.TextField(blank=True) + parent_term_id = models.IntegerField(null=True, blank=True) + post_count = models.IntegerField(default=0) + + # NEW fields: + mapped_cluster_id = models.ForeignKey('sag.SAGCluster', null=True, blank=True, on_delete=models.SET_NULL) + has_generated_content = models.BooleanField(default=False) + generated_content_id = models.ForeignKey('writer.Content', null=True, blank=True, on_delete=models.SET_NULL) + content_sync_status = models.CharField(max_length=20, default='pending', + choices=[('pending','Pending'),('synced','Synced'),('failed','Failed')]) + last_synced_at = models.DateTimeField(null=True, blank=True) +``` + +### 4.6 Frontend: Taxonomy Management UI + +**Location:** Add to Planner section + +``` +frontend/src/pages/Planner/ +├── Taxonomies.tsx # NEW — list all synced taxonomies + terms +├── components/ +│ ├── TaxonomyList.tsx # Taxonomy groups with term counts +│ ├── TermList.tsx # Terms within a taxonomy with content status +│ ├── TermClusterMapper.tsx # Assign/reassign cluster per term +│ └── TermContentStatus.tsx # Content generated? Published? Sync status? +``` + +**Sidebar integration:** Add "Taxonomies" as a sub-item under Planner: +``` +WORKFLOW + ├── Planner + │ ├── Keywords + │ ├── Clusters + │ ├── Ideas + │ └── Taxonomies (NEW) + ├── Writer + ... +``` + +**Taxonomy List view:** +- Shows all synced taxonomies grouped: WordPress Default (categories, tags), WooCommerce (product_cat, product_tag, pa_*), Custom/SAG (from blueprint) +- Per taxonomy: term count, terms with content, terms without content +- "Sync Taxonomies" button to trigger fresh sync from WordPress +- "Generate All Term Content" button to batch-create ideas for all unmapped terms + +**Term Detail view:** +- Term name, slug, description, post count +- Cluster mapping: current cluster (or "Unmapped"), dropdown to change +- Content status: Not generated / Draft / Review / Published +- "Generate Content" button for individual term +- Preview of generated content + +### 4.7 Frontend: Automation Integration + +When automation runs with taxonomy content enabled: +- Stage 3 (Idea Generation) includes term ideas alongside post ideas +- Ideas list in Planner shows term ideas with "Taxonomy Landing" badge +- Writer Queue/Drafts show term content alongside post content +- Publishing routes term content to term description instead of creating a new post + +--- + +## 5. Module 3: Optimizer Module {#5-optimizer-module} + +### 5.1 What This Module Delivers + +Activates the existing `optimizer_enabled` module. Analyzes and optimizes existing published content: maps to clusters, rewrites structure for intent alignment, refreshes SEO metadata, generates schema markup. + +### 5.2 Backend: Implement OptimizeContent AI Function + +**Location:** `ai/functions/optimize_content.py` — currently PENDING, implement it + +```python +class OptimizeContent: + """ + Takes existing content and produces an optimized version: + - Maps to best-matching cluster + - Rewrites structure for intent alignment + - Refreshes meta title/description + - Adds missing sections (FAQs, comparisons, etc.) + - Generates schema JSON-LD + """ + + def execute(self, content, cluster=None, optimization_config=None): + # 1. If no cluster provided, call ClusterMappingService to find best match + # 2. Analyze current content: heading structure, keyword density, missing sections + # 3. Generate optimized version with SAG context + # 4. Generate before/after scores + # 5. Return: optimized_content, meta, schema, scores, diff_summary + pass +``` + +### 5.3 Backend: Optimizer Service + +```python +# business/optimization/optimizer_service.py # IMPLEMENT (file exists, logic pending) + +class OptimizerService: + def analyze_content(self, content): + """Score content against its cluster targets. Return analysis report.""" + # Keyword coverage score + # Heading structure score + # Content length assessment + # Missing sections detection + # Internal link opportunities + # Schema coverage + pass + + def optimize_content(self, content, apply_mode='manual'): + """Generate optimized version. apply_mode: 'manual' (review first) or 'auto'.""" + pass + + def batch_optimize(self, site, content_ids): + """Queue batch optimization as Celery tasks.""" + pass + + def generate_schema(self, content): + """Generate appropriate JSON-LD schema based on content_type.""" + pass +``` + +### 5.4 Backend: Optimizer Models + +**Modify/create in:** `modules/optimizer/models.py` + +```python +class OptimizationJob(SiteSectorBaseModel): + """Tracks a single optimization operation.""" + content = models.ForeignKey('writer.Content', on_delete=models.CASCADE) + status = models.CharField(max_length=20, choices=[ + ('pending', 'Pending'), + ('analyzing', 'Analyzing'), + ('optimized', 'Optimized'), + ('applied', 'Applied'), + ('rejected', 'Rejected'), + ], default='pending') + original_score = models.FloatField(null=True, blank=True) + optimized_score = models.FloatField(null=True, blank=True) + cluster_match = models.ForeignKey('sag.SAGCluster', null=True, blank=True, on_delete=models.SET_NULL) + cluster_confidence = models.FloatField(null=True, blank=True) + optimized_content = models.TextField(blank=True) + optimized_meta_title = models.CharField(max_length=300, blank=True) + optimized_meta_description = models.TextField(blank=True) + generated_schema = models.JSONField(default=dict, blank=True) + diff_summary = models.JSONField(default=dict, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + applied_at = models.DateTimeField(null=True, blank=True) +``` + +### 5.5 Backend: Optimizer API + +**Enhance:** `modules/optimizer/views.py` + +```python +# POST /api/v1/optimizer/analyze/ +# Input: {content_id} +# Output: {score, cluster_match, recommendations} + +# POST /api/v1/optimizer/optimize/ +# Input: {content_id, cluster_id (optional override)} +# Output: {job_id, optimized_preview} + +# POST /api/v1/optimizer/apply/{job_id}/ +# Input: {job_id} +# Output: {success, updated_content} + +# POST /api/v1/optimizer/batch/ +# Input: {content_ids: [...]} +# Output: {jobs: [{content_id, job_id}]} + +# GET /api/v1/optimizer/jobs/ +# List all optimization jobs with status +``` + +### 5.6 Frontend: Optimizer Page + +**Location:** `pages/Optimizer/` — existing but INACTIVE, implement UI + +``` +frontend/src/pages/Optimizer/ +├── OptimizerDashboard.tsx # IMPLEMENT — overview of optimization opportunities +│ ├── ContentScoreList.tsx # All content sorted by optimization score (lowest first) +│ ├── ClusterCoverage.tsx # Which clusters have optimized vs unoptimized content +│ └── OptimizationQueue.tsx # Active/pending optimization jobs +├── OptimizeContent.tsx # IMPLEMENT — single content optimization view +│ ├── BeforeAfterView.tsx # Side-by-side original vs optimized +│ ├── ScoreComparison.tsx # Score breakdown: before vs after +│ ├── ClusterMatcher.tsx # Show matched cluster, allow override +│ ├── SchemaPreview.tsx # Preview generated JSON-LD +│ └── ApplyRejectButtons.tsx # Apply optimization or reject +└── BatchOptimize.tsx # IMPLEMENT — select multiple, batch optimize +``` + +**Sidebar:** Optimizer appears under WORKFLOW when `optimizer_enabled = True` (existing behavior, now with actual UI). + +### 5.7 Settings Integration + +**Location:** `pages/Settings/` — add Optimizer settings tab + +Settings for Optimizer module: +- Enable/disable Optimizer +- Default schema type per content type (Article, Product, FAQ, etc.) +- Keyword density targets (percentage range) +- Content length guidelines (min/max per content type) +- Auto-apply vs manual review toggle +- Exclude content from optimization (by ID or date range) + +--- + +## 6. Module 4: GSC Integration {#6-gsc-integration} + +### 6.1 What This Module Delivers + +Google Search Console integration: OAuth connection, URL Inspection API, auto-indexing pipeline, search metrics dashboard, plugin status sync. + +### 6.2 Backend: New Django App + +``` +backend/igny8_core/ +├── gsc/ # NEW Django app +│ ├── __init__.py +│ ├── apps.py +│ ├── models.py # GSCConnection, URLTrackingRecord, SearchMetric +│ ├── serializers.py +│ ├── views.py # OAuth flow, inspection, metrics endpoints +│ ├── urls.py # /api/v1/gsc/* +│ ├── admin.py +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── oauth_service.py # Google OAuth token management +│ │ ├── site_mapping_service.py # Map IGNY8 sites to GSC properties +│ │ ├── inspection_service.py # URL Inspection API calls +│ │ ├── indexing_service.py # Auto-indexing queue + pipeline +│ │ ├── metrics_service.py # Search Analytics API data fetch +│ │ └── quota_service.py # Daily quota tracking (2,000/day) +│ ├── tasks.py # Celery tasks for queue processing +│ └── migrations/ +``` + +### 6.3 Backend: Models + +```python +# gsc/models.py + +class GSCConnection(AccountBaseModel): + """One Google OAuth connection per account. Manages all sites.""" + google_email = models.EmailField() + access_token = models.TextField() + refresh_token = models.TextField() + token_expiry = models.DateTimeField() + scopes = models.JSONField(default=list) + is_active = models.BooleanField(default=True) + connected_at = models.DateTimeField(auto_now_add=True) + last_refreshed = models.DateTimeField(null=True, blank=True) + +class GSCSiteMapping(models.Model): + """Maps an IGNY8 site to a GSC property.""" + site = models.OneToOneField('auth.Site', on_delete=models.CASCADE, related_name='gsc_mapping') + gsc_property = models.CharField(max_length=300, help_text='e.g., sc-domain:example.com') + property_type = models.CharField(max_length=20, choices=[ + ('domain', 'Domain Property'), + ('url_prefix', 'URL Prefix'), + ]) + status = models.CharField(max_length=20, choices=[ + ('matched', 'Auto-Matched'), + ('manual', 'Manually Mapped'), + ('not_found', 'Not Found in GSC'), + ]) + verified = models.BooleanField(default=False) + mapped_at = models.DateTimeField(auto_now_add=True) + +class URLTrackingRecord(SiteSectorBaseModel): + """Tracks indexing status for each URL.""" + url = models.URLField() + content = models.ForeignKey('writer.Content', null=True, blank=True, on_delete=models.SET_NULL) + is_igny8_content = models.BooleanField(default=True) + + # Inspection results + index_status = models.CharField(max_length=30, choices=[ + ('unknown', 'Unknown'), + ('indexed', 'Indexed'), + ('not_indexed', 'Not Indexed'), + ('indexing_requested', 'Indexing Requested'), + ('error', 'Error'), + ('noindex', 'Noindex Detected'), + ], default='unknown') + coverage_state = models.CharField(max_length=100, blank=True) + last_crawl_time = models.DateTimeField(null=True, blank=True) + crawl_status = models.CharField(max_length=50, blank=True) + + # Queue management + queue_priority = models.IntegerField(default=50) + next_check_at = models.DateTimeField(null=True, blank=True) + check_count = models.IntegerField(default=0) + max_checks = models.IntegerField(default=4) + + last_inspected_at = models.DateTimeField(null=True, blank=True) + indexing_requested_at = models.DateTimeField(null=True, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + +class SearchMetricSnapshot(SiteSectorBaseModel): + """Daily/weekly search metrics from GSC Search Analytics API.""" + date = models.DateField() + dimension = models.CharField(max_length=20, choices=[ + ('page', 'Page'), ('query', 'Query'), + ('country', 'Country'), ('device', 'Device'), + ]) + dimension_value = models.CharField(max_length=500) + clicks = models.IntegerField(default=0) + impressions = models.IntegerField(default=0) + ctr = models.FloatField(default=0.0) + position = models.FloatField(default=0.0) + is_igny8_content = models.BooleanField(default=False) +``` + +### 6.4 Backend: Queue Processing + +```python +# gsc/tasks.py + +@shared_task +def process_indexing_queue(): + """Process URL inspection/indexing queue. Runs every 5 minutes.""" + # 1. Check daily quota (2,000 inspections, resets midnight PT) + # 2. Pick next item from queue by priority + # 3. Call URL Inspection API + # 4. Parse response: indexed? → done. Not indexed? → request indexing + # 5. Schedule re-inspection (24h, 3d, 6d, 13d) + # 6. Wait 3 seconds between calls + # 7. Sync status to WordPress plugin + pass + +@shared_task +def fetch_search_metrics(site_id): + """Fetch search analytics data from GSC. Runs daily.""" + pass + +@shared_task +def auto_index_published_content(content_id): + """Triggered when content is published to WordPress. Adds to indexing queue.""" + pass + +@shared_task +def sync_index_status_to_plugin(site_id): + """Batch sync index statuses to WordPress plugin. Runs every 5 min.""" + pass +``` + +### 6.5 Backend: API Endpoints + +```python +# gsc/urls.py + +# OAuth +POST /api/v1/gsc/connect/ # Initiate OAuth flow +GET /api/v1/gsc/callback/ # OAuth callback +DELETE /api/v1/gsc/disconnect/ # Revoke connection +GET /api/v1/gsc/status/ # Connection status + +# Site mapping +GET /api/v1/gsc/sites/ # List GSC properties + mapping status +POST /api/v1/gsc/sites/map/ # Manually map IGNY8 site to GSC property +POST /api/v1/gsc/sites/auto-map/ # Auto-detect and map + +# URL Inspection +GET /api/v1/gsc/urls/ # List tracked URLs with index status +POST /api/v1/gsc/urls/inspect/ # Manual inspect a URL +POST /api/v1/gsc/urls/request-index/ # Manual request indexing +GET /api/v1/gsc/urls/queue/ # Queue status (pending, quota remaining) + +# Search Metrics +GET /api/v1/gsc/metrics/ # Search metrics with date range + dimensions +GET /api/v1/gsc/metrics/top-pages/ # Top pages by clicks +GET /api/v1/gsc/metrics/top-queries/ # Top queries +GET /api/v1/gsc/metrics/igny8-only/ # IGNY8-published content metrics only +``` + +### 6.6 Frontend: GSC Pages + +``` +frontend/src/pages/ +└── SearchConsole/ # NEW page + ├── GSCConnect.tsx # OAuth connection flow + welcome screen + ├── SiteMapping.tsx # Map IGNY8 sites to GSC properties + ├── IndexingDashboard.tsx # URL list, index status, queue status + │ ├── IndexStatusTable.tsx # Filterable URL table + │ ├── QueueStatus.tsx # Quota remaining, items in queue + │ └── ManualInspect.tsx # Inspect any URL manually + ├── PerformanceMetrics.tsx # Search analytics dashboard + │ ├── MetricsSummary.tsx # Clicks, impressions, CTR, position cards + │ ├── TopPages.tsx # Top pages table with IGNY8 star markers + │ ├── TopQueries.tsx # Top queries table + │ └── DateRangePicker.tsx # Date range selector + └── components/ + └── IndexStatusBadge.tsx # Reusable status badge component +``` + +**Sidebar addition:** +``` +WORKFLOW + ├── Planner + ├── Writer + ├── Automation + ├── Blueprint (if SAG active) + ├── Linker (if linker_enabled) + ├── Campaigns (if campaign_enabled) + ├── Search Console (NEW — if gsc_enabled) + └── Optimizer (if optimizer_enabled) +``` + +**Feature flag:** `gsc_enabled` + +### 6.7 Plugin Side Enhancement + +``` +igny8-plugin/includes/modules/gsc/ +├── class-gsc-module.php # Module entry +├── class-gsc-status-display.php # Index status column in WP admin content list +├── class-gsc-metabox.php # Edit screen metabox showing index status +└── views/ + └── gsc-metabox.php # Metabox template +``` + +Plugin receives index status updates from IGNY8 app via: +``` +POST /wp-json/igny8/v1/gsc/status-sync +Body: {urls: [{url, index_status, last_inspected, coverage_state}]} +``` + +--- + +## 7. Module 5: Rich Schema & SERP Enhancement {#7-rich-schema} + +### 7.1 What This Module Delivers + +Automated JSON-LD schema injection and on-page SERP elements (TL;DR boxes, TOC, definition blocks, comparison tables, PAA subheadings) into content — both during generation and retroactively for existing pages. + +### 7.2 Backend: Schema Service + +``` +backend/igny8_core/ +├── schema/ # NEW (or extend within modules/writer/) +│ ├── __init__.py +│ ├── services/ +│ │ ├── schema_generator.py # Core: content → schema JSON-LD +│ │ ├── content_classifier.py # Classify content type for schema mapping +│ │ ├── faq_generator.py # AI: extract/generate FAQ pairs +│ │ ├── howto_extractor.py # AI: detect procedural content → HowTo +│ │ ├── review_analyzer.py # AI: sentiment analysis → Review schema +│ │ ├── proscons_generator.py # AI: generate pros/cons from content +│ │ ├── toc_generator.py # Parse H2/H3 → TOC with jump links +│ │ ├── tldr_generator.py # AI: generate TL;DR summary +│ │ ├── definition_extractor.py # AI: extract key terms → definition blocks +│ │ ├── paa_integrator.py # AI: generate PAA-style subheadings +│ │ └── validator.py # JSON-LD structural validation +│ └── ai_functions/ +│ ├── generate_schema_elements.py # Combined AI function for all schema/SERP elements +│ └── retroactive_analyzer.py # AI: analyze existing page → what's missing +``` + +### 7.3 Backend: Content Type → Schema Mapping + +This is the core decision engine. For each content classification, determine which schemas and elements apply: + +```python +# schema/services/schema_generator.py + +SCHEMA_MAP = { + 'blog_article': { + 'schemas': ['faq', 'article', 'author_person', 'breadcrumb'], + 'elements': ['tldr', 'toc', 'definition_blocks', 'paa_subheadings'], + }, + 'tutorial_guide': { + 'schemas': ['faq', 'howto', 'article', 'author_person', 'breadcrumb'], + 'elements': ['tldr', 'toc', 'definition_blocks', 'paa_subheadings'], + }, + 'product_review': { + 'schemas': ['faq', 'review_rating', 'pros_cons', 'article', 'author_person', 'breadcrumb'], + 'elements': ['tldr', 'toc', 'paa_subheadings'], + }, + 'service_page': { + 'schemas': ['faq', 'breadcrumb', 'service'], + 'elements': ['definition_blocks'], + }, + 'comparison_post': { + 'schemas': ['faq', 'review_rating', 'pros_cons', 'article', 'author_person', 'breadcrumb'], + 'elements': ['tldr', 'toc', 'comparison_table', 'paa_subheadings'], + }, + 'product_page': { + 'schemas': ['faq', 'product', 'review_rating', 'breadcrumb'], + 'elements': [], + }, +} +``` + +### 7.4 Backend: Pipeline Integration + +**Enhance Stage 5 (Content Generation):** + +After AI generates content body, a post-processing step generates schema and on-page elements: + +```python +# business/content/ — extend content generation flow + +def post_process_content(content): + """After content body is generated, add schema and SERP elements.""" + # 1. Classify content type + content_class = content_classifier.classify(content) + + # 2. Get applicable schemas and elements from SCHEMA_MAP + applicable = SCHEMA_MAP.get(content_class, {}) + + # 3. Generate each applicable schema + schemas = {} + if 'faq' in applicable['schemas']: + schemas['faq'] = faq_generator.generate(content) + if 'howto' in applicable['schemas']: + schemas['howto'] = howto_extractor.extract(content) + # ... etc + + # 4. Generate on-page elements + elements = {} + if 'tldr' in applicable['elements']: + elements['tldr'] = tldr_generator.generate(content) + if 'toc' in applicable['elements']: + elements['toc'] = toc_generator.generate(content) + # ... etc + + # 5. Store on Content model + content.schema_data = schemas # NEW JSON field + content.serp_elements = elements # NEW JSON field + content.save() +``` + +**New fields on Content model:** +```python +# Add to modules/writer/models.py — Content model: +schema_data = models.JSONField(null=True, blank=True, help_text='Generated JSON-LD schemas') +serp_elements = models.JSONField(null=True, blank=True, help_text='Generated SERP elements (TL;DR, TOC, etc.)') +``` + +### 7.5 Backend: Retroactive Enhancement Engine + +```python +# schema/services/retroactive_engine.py + +class RetroactiveEngine: + def scan_site(self, site): + """Fetch all published pages via plugin, classify, identify missing schemas.""" + # 1. GET site inventory from plugin + # 2. For each page: classify content type, check existing schema + # 3. Return: [{url, content_type, missing_schemas, missing_elements}] + pass + + def generate_enhancements(self, site, pages): + """For each page with missing schemas, generate them.""" + # AI analyzes page content → generates applicable schemas + elements + # Returns review-ready enhancement set + pass + + def push_enhancements(self, site, approved_enhancements): + """Push approved schemas to WordPress via plugin bulk endpoint.""" + # POST /wp-json/igny8/v1/schema/bulk-update + pass +``` + +### 7.6 Backend: Validation Pipeline + +```python +# schema/services/validator.py + +class SchemaValidator: + def validate_structural(self, schema_json): + """Check JSON-LD syntax and schema.org conformance.""" + pass + + def validate_rich_results(self, url, schema_json): + """Check against Google Rich Results Test API.""" + pass +``` + +### 7.7 Frontend: Schema Module UI + +``` +frontend/src/pages/ +└── Schema/ # NEW page (or sub-section of Optimizer) + ├── SchemaOverview.tsx # Site-wide schema coverage dashboard + │ ├── SchemaCoverage.tsx # % of pages with each schema type + │ ├── MissingSchemaList.tsx # Pages missing applicable schemas + │ └── ValidationStatus.tsx # Schema validation results + ├── RetroactiveEnhancer.tsx # Scan existing site, review/approve enhancements + │ ├── SiteScanResults.tsx # Classified pages with enhancement recommendations + │ ├── EnhancementPreview.tsx # Preview schema + elements per page + │ └── BulkApprove.tsx # Approve all / select and approve + └── SchemaSettings.tsx # Per-content-type schema defaults +``` + +**Sidebar:** Can be a sub-page under Optimizer or a standalone item if `schema_enabled` flag is set. + +### 7.8 Plugin Side Enhancement + +``` +igny8-plugin/includes/modules/schema/ # Already planned in Plugin Build Plan +├── class-schema-module.php +├── class-schema-generator.php # JSON-LD output in +├── class-schema-renderer.php # On-page element renderer (shortcodes/blocks) +``` + +Plugin stores schemas in post meta (`igny8_schema_faq`, `igny8_schema_howto`, etc.) and renders them in `wp_head` hook. + +On-page elements (FAQ section, TOC, TL;DR box) rendered via shortcodes or automatic injection based on content type. + +**Bulk update endpoint:** +``` +POST /wp-json/igny8/v1/schema/bulk-update +Body: {pages: [{post_id, schemas: {faq: {...}, article: {...}}, elements: {tldr: "...", toc: [...]}}]} +``` + +--- + +## 8. Module 6: Socializer {#8-socializer} + +### 8.1 What This Module Delivers + +Adapts published content into social posts and schedules across 5 platforms: LinkedIn, Twitter/X, Facebook, Instagram, TikTok. + +### 8.2 Backend: New Django App + +``` +backend/igny8_core/ +├── socializer/ # NEW Django app +│ ├── __init__.py +│ ├── apps.py +│ ├── models.py # SocialAccount, SocialPost, SocialSchedule +│ ├── serializers.py +│ ├── views.py +│ ├── urls.py # /api/v1/socializer/* +│ ├── admin.py +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── oauth_service.py # OAuth2 flows per platform +│ │ ├── content_adapter.py # AI: adapt content for each platform +│ │ ├── image_resizer.py # Resize/crop per platform specs +│ │ ├── publisher.py # Publish to platform APIs +│ │ ├── scheduler.py # Schedule management, best-time slots +│ │ └── metrics_service.py # Fetch engagement metrics +│ ├── platforms/ # Platform-specific API clients +│ │ ├── __init__.py +│ │ ├── linkedin.py +│ │ ├── twitter.py +│ │ ├── facebook.py +│ │ ├── instagram.py +│ │ └── tiktok.py +│ ├── ai_functions/ +│ │ ├── adapt_for_social.py # AI: content → platform-specific post +│ │ └── generate_hashtags.py # AI: generate relevant hashtags +│ ├── tasks.py # Celery tasks for scheduled posting + metrics +│ └── migrations/ +``` + +### 8.3 Backend: Models + +```python +# socializer/models.py + +class SocialAccount(AccountBaseModel): + """Connected social media account/page.""" + platform = models.CharField(max_length=20, choices=[ + ('linkedin', 'LinkedIn'), ('twitter', 'Twitter/X'), + ('facebook', 'Facebook'), ('instagram', 'Instagram'), + ('tiktok', 'TikTok'), + ]) + account_name = models.CharField(max_length=200) + account_id = models.CharField(max_length=200) + access_token = models.TextField() + refresh_token = models.TextField(blank=True) + token_expiry = models.DateTimeField(null=True, blank=True) + page_id = models.CharField(max_length=200, blank=True, help_text='For Facebook Pages, LinkedIn Company Pages') + is_active = models.BooleanField(default=True) + connected_at = models.DateTimeField(auto_now_add=True) + +class SocialPost(SiteSectorBaseModel): + """A social post generated from IGNY8 content.""" + source_content = models.ForeignKey('writer.Content', on_delete=models.CASCADE, related_name='social_posts') + platform = models.CharField(max_length=20) + social_account = models.ForeignKey(SocialAccount, on_delete=models.CASCADE) + post_type = models.CharField(max_length=30, choices=[ + ('announcement', 'Announcement'), + ('highlight', 'Key Highlights'), + ('quote_card', 'Quote Card'), + ('faq_snippet', 'FAQ Snippet'), + ('thread', 'Thread (Twitter)'), + ]) + text_content = models.TextField() + hashtags = models.JSONField(default=list) + image_url = models.URLField(blank=True) + link_url = models.URLField(blank=True) + + # Scheduling + status = models.CharField(max_length=20, choices=[ + ('draft', 'Draft'), ('scheduled', 'Scheduled'), + ('published', 'Published'), ('failed', 'Failed'), + ], default='draft') + scheduled_at = models.DateTimeField(null=True, blank=True) + published_at = models.DateTimeField(null=True, blank=True) + platform_post_id = models.CharField(max_length=200, blank=True) + + # Metrics + clicks = models.IntegerField(default=0) + likes = models.IntegerField(default=0) + shares = models.IntegerField(default=0) + comments = models.IntegerField(default=0) + impressions = models.IntegerField(default=0) + metrics_updated_at = models.DateTimeField(null=True, blank=True) + + created_at = models.DateTimeField(auto_now_add=True) +``` + +### 8.4 Backend: Automation Pipeline Stage 8 + +```python +# business/automation/stages/stage_8_socializer.py # NEW + +# After content is published to WordPress (Stage 7 + publish): +# 1. Check if socializer_enabled for this site +# 2. Load connected social accounts +# 3. For each active platform: +# a. AI adapts content for platform (tone, length, format) +# b. Resize image for platform specs +# c. Generate hashtags +# d. Create SocialPost (status=scheduled) +# e. Queue for scheduled publishing +``` + +Add to `AutomationConfig` choices: +```python +# Stage 8: Socializer (if socializer_enabled) +``` + +### 8.5 Backend: Celery Tasks + +```python +# socializer/tasks.py + +@shared_task +def publish_scheduled_posts(): + """Every 5 min: check for posts due for publishing, publish them.""" + pass + +@shared_task +def fetch_engagement_metrics(): + """Every 6 hours: fetch metrics for recently published posts.""" + pass + +@shared_task +def refresh_social_tokens(): + """Daily: refresh OAuth tokens approaching expiry.""" + pass +``` + +### 8.6 Frontend: Socializer Pages + +``` +frontend/src/pages/ +└── Socializer/ # NEW page + ├── SocialAccounts.tsx # Connected accounts management + │ ├── ConnectAccount.tsx # OAuth connect flow per platform + │ └── AccountList.tsx # List connected accounts with status + ├── SocialPosts.tsx # All social posts with status + │ ├── PostList.tsx # Filterable by platform, status, date + │ ├── PostPreview.tsx # Platform-specific preview card + │ └── PostEditor.tsx # Edit text/image before scheduling + ├── SocialCalendar.tsx # Calendar view of scheduled posts + └── SocialAnalytics.tsx # Engagement metrics per platform/post +``` + +**Sidebar addition:** +``` +WORKFLOW + ├── ... + ├── Socializer (NEW — if socializer_enabled) + └── ... +``` + +**Feature flag:** `socializer_enabled` + +--- + +## 9. Module 7: Video Creator {#9-video-creator} + +### 9.1 What This Module Delivers + +Converts published articles into video content and publishes to YouTube, Instagram Reels, TikTok, YouTube Shorts. + +### 9.2 Backend: New Django App + +``` +backend/igny8_core/ +├── video/ # NEW Django app +│ ├── __init__.py +│ ├── apps.py +│ ├── models.py # VideoProject, VideoScript, VideoAsset, VideoRender +│ ├── serializers.py +│ ├── views.py +│ ├── urls.py # /api/v1/video/* +│ ├── admin.py +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── script_service.py # AI script generation from content +│ │ ├── tts_service.py # Text-to-speech (OpenAI, ElevenLabs, self-hosted) +│ │ ├── asset_service.py # Stock footage/image fetching (Pexels, Pixabay) +│ │ ├── composer_service.py # FFmpeg + MoviePy video assembly +│ │ ├── subtitle_service.py # SRT caption generation +│ │ ├── thumbnail_service.py # AI thumbnail generation +│ │ ├── seo_service.py # Video titles, descriptions, tags per platform +│ │ └── publisher_service.py # Publish to YouTube, Instagram, TikTok +│ ├── platforms/ +│ │ ├── youtube.py # YouTube Data API v3 +│ │ ├── instagram.py # Instagram Graph API (Reels) +│ │ └── tiktok.py # TikTok Content Posting API +│ ├── ai_functions/ +│ │ ├── generate_script.py # AI: content → VideoScript +│ │ ├── generate_video_seo.py # AI: script → platform-specific SEO +│ │ └── generate_thumbnail.py # AI: content → thumbnail image +│ ├── tasks.py # Celery tasks (separate queue for rendering) +│ └── migrations/ +``` + +### 9.3 Backend: Models + +```python +# video/models.py + +class VideoProject(SiteSectorBaseModel): + """A video project generated from IGNY8 content.""" + source_content = models.ForeignKey('writer.Content', on_delete=models.CASCADE, related_name='video_projects') + video_type = models.CharField(max_length=20, choices=[ + ('short', 'Short Form (30-90s)'), + ('medium', 'Medium (60-180s)'), + ('long', 'Long Form (5-15 min)'), + ]) + status = models.CharField(max_length=20, choices=[ + ('script_draft', 'Script Draft'), + ('script_approved', 'Script Approved'), + ('rendering', 'Rendering'), + ('rendered', 'Rendered'), + ('published', 'Published'), + ('failed', 'Failed'), + ], default='script_draft') + target_platforms = models.JSONField(default=list, help_text='["youtube", "instagram", "tiktok"]') + render_preset = models.CharField(max_length=30, choices=[ + ('youtube_long', '1920×1080 3-15min'), + ('youtube_short', '1080×1920 30-60s'), + ('instagram_reel', '1080×1920 30-90s'), + ('tiktok', '1080×1920 30-180s'), + ]) + created_at = models.DateTimeField(auto_now_add=True) + +class VideoScript(models.Model): + """AI-generated narration script for a video project.""" + project = models.OneToOneField(VideoProject, on_delete=models.CASCADE, related_name='script') + sections = models.JSONField(help_text='[{type: "hook"|"intro"|"point"|"cta", text, visual_cue, duration_seconds}]') + total_duration_seconds = models.IntegerField(default=0) + voice_id = models.CharField(max_length=100, blank=True) + voice_provider = models.CharField(max_length=30, blank=True) + seo_title = models.JSONField(default=dict, help_text='{youtube: "...", instagram: "...", tiktok: "..."}') + seo_description = models.JSONField(default=dict) + seo_tags = models.JSONField(default=list) + chapter_markers = models.JSONField(default=list, help_text='For YouTube chapters') + created_at = models.DateTimeField(auto_now_add=True) + +class VideoRender(models.Model): + """A rendered video file for a specific platform.""" + project = models.ForeignKey(VideoProject, on_delete=models.CASCADE, related_name='renders') + platform = models.CharField(max_length=20) + file_url = models.URLField(blank=True, help_text='S3/storage URL') + file_size_bytes = models.BigIntegerField(default=0) + duration_seconds = models.IntegerField(default=0) + resolution = models.CharField(max_length=20) + thumbnail_url = models.URLField(blank=True) + subtitle_url = models.URLField(blank=True, help_text='SRT file URL') + status = models.CharField(max_length=20, choices=[ + ('queued', 'Queued'), ('rendering', 'Rendering'), + ('complete', 'Complete'), ('failed', 'Failed'), + ], default='queued') + platform_video_id = models.CharField(max_length=200, blank=True) + published_at = models.DateTimeField(null=True, blank=True) + render_started_at = models.DateTimeField(null=True, blank=True) + render_completed_at = models.DateTimeField(null=True, blank=True) +``` + +### 9.4 Backend: Celery Tasks (Separate Queue) + +Video rendering is CPU/memory intensive — use a separate Celery queue. + +```python +# video/tasks.py + +@shared_task(queue='video_render') +def render_video(project_id, platform): + """Heavy task: assemble and render video. Runs on dedicated worker.""" + # 1. Load script + assets + # 2. TTS: generate voiceover audio + # 3. Fetch stock footage/images for visual cues + # 4. Compose video with FFmpeg/MoviePy + # 5. Add subtitles + # 6. Upload to S3/storage + # 7. Update VideoRender record + pass + +@shared_task +def publish_video(render_id): + """Publish rendered video to platform.""" + pass + +@shared_task +def generate_video_thumbnail(project_id): + """AI-generate thumbnail from content.""" + pass +``` + +**Celery config addition:** +```python +# celery.py — add video_render queue +CELERY_TASK_ROUTES = { + 'igny8_core.video.tasks.render_video': {'queue': 'video_render'}, +} +``` + +### 9.5 Backend: Automation Pipeline Stage 9 + +```python +# business/automation/stages/stage_9_video.py # NEW + +# After socializer (Stage 8) or after publish: +# 1. Check if video_enabled for this site +# 2. If auto-video enabled: generate script → queue for rendering +# 3. If manual: create project in script_draft status for user review +``` + +### 9.6 Frontend: Video Creator Pages + +``` +frontend/src/pages/ +└── VideoCreator/ # NEW page + ├── VideoProjects.tsx # List all video projects with status + ├── ScriptEditor.tsx # View/edit AI-generated script + │ ├── ScriptSections.tsx # Section-by-section editor + │ ├── VoiceSelector.tsx # Choose TTS voice + preview + │ └── VisualCueEditor.tsx # Edit visual cues per section + ├── VideoPreview.tsx # Preview rendered video + ├── VideoPublisher.tsx # Select platforms + publish + └── VideoAnalytics.tsx # View/engagement metrics per video +``` + +**Sidebar addition:** +``` +WORKFLOW + ├── ... + ├── Socializer (if socializer_enabled) + ├── Video Creator (NEW — if video_enabled) + └── ... +``` + +**Feature flag:** `video_enabled` + +--- + +## 10. Updated Automation Pipeline — All Stages {#10-updated-automation-pipeline} + +After all modules are implemented, the full pipeline becomes: + +``` +Stage 0: Blueprint Check (if SAG active — from Doc A) +Stage 1: Process New Keywords +Stage 2: AI Cluster Keywords (or SAG cluster mapping) +Stage 3: Generate Content Ideas (type-aware, blueprint-guided) +Stage 4: Create Writer Tasks (with content_type + content_structure) +Stage 5: Generate Article Content (type-specific prompts + schema/SERP post-processing) +Stage 6: Extract Image Prompts +Stage 7: Generate Images → Review Queue +--- After publish to WordPress --- +Stage 7.5: Auto-Index via GSC (if gsc_enabled) +Stage 8: Linker — Generate SAG links (if linker_enabled — from Doc A) +Stage 9: Socializer — Generate social posts (if socializer_enabled) +Stage 10: Video Creator — Generate video project (if video_enabled) +``` + +Each stage beyond 7 is independently enabled/disabled. The pipeline gracefully skips disabled stages. + +**AutomationConfig** model extends to include stage enable/disable per site: +```python +# Add to AutomationConfig or AutomationSettings: +gsc_auto_index = models.BooleanField(default=True) +auto_generate_links = models.BooleanField(default=True) +auto_generate_social = models.BooleanField(default=False) +auto_generate_video = models.BooleanField(default=False) +``` + +--- + +## 11. Updated Navigation & Sidebar {#11-updated-navigation} + +After all modules implemented: + +``` +Dashboard (with GSC indexing widget, social metrics widget, video status widget) +SETUP + ├── Add Keywords (optional when SAG active) + ├── Content Settings + ├── Sites + └── Thinker (admin only) +WORKFLOW + ├── Planner + │ ├── Keywords + │ ├── Clusters + │ ├── Ideas + │ └── Taxonomies (if taxonomy sync active — Module 2) + ├── Writer (Queue → Drafts → Images → Review → Published, all content types) + ├── Automation (Stages 1-10 visualization, per-stage toggle) + ├── Blueprint (if SAG active — from Doc A) + ├── Linker (if linker_enabled — from Doc A) + ├── Campaigns (if campaign_enabled — from Doc A) + ├── Search Console (if gsc_enabled — Module 4) + ├── Optimizer (if optimizer_enabled — Module 3) + ├── Schema (if schema_enabled — Module 5, or nested under Optimizer) + ├── Socializer (if socializer_enabled — Module 6) + └── Video Creator (if video_enabled — Module 7) +ACCOUNT + ├── Account Settings + ├── Plans & Billing + ├── Usage + └── AI Models (admin only) +ADMIN (admin only) + └── Sector Templates +HELP + └── Help & Docs +``` + +--- + +## 12. Complete API Endpoint Registry {#12-api-endpoints} + +### Content Types Writing (Module 1 — no new endpoints, enhances existing) +``` +Existing writer/tasks/ and writer/content/ endpoints — now accept content_type and content_structure fields +``` + +### Taxonomy & Term Content (Module 2) +``` +GET /api/v1/planner/taxonomies/ # List synced taxonomies +POST /api/v1/planner/taxonomies/sync/ # Trigger taxonomy sync from WordPress +GET /api/v1/planner/taxonomies/{id}/terms/ # List terms within taxonomy +POST /api/v1/planner/taxonomies/terms/{id}/map/ # Map term to cluster +POST /api/v1/planner/taxonomies/terms/{id}/generate/ # Generate content for term +POST /api/v1/planner/taxonomies/bulk-generate/ # Batch generate term content +``` + +### Optimizer (Module 3) +``` +POST /api/v1/optimizer/analyze/ # Analyze content +POST /api/v1/optimizer/optimize/ # Generate optimized version +POST /api/v1/optimizer/apply/{job_id}/ # Apply optimization +POST /api/v1/optimizer/reject/{job_id}/ # Reject optimization +POST /api/v1/optimizer/batch/ # Batch optimize +GET /api/v1/optimizer/jobs/ # List optimization jobs +GET /api/v1/optimizer/settings/ # Module settings +PUT /api/v1/optimizer/settings/ # Update settings +``` + +### GSC Integration (Module 4) +``` +POST /api/v1/gsc/connect/ # OAuth initiate +GET /api/v1/gsc/callback/ # OAuth callback +DELETE /api/v1/gsc/disconnect/ # Revoke +GET /api/v1/gsc/status/ # Connection status +GET /api/v1/gsc/sites/ # GSC properties +POST /api/v1/gsc/sites/map/ # Manual mapping +POST /api/v1/gsc/sites/auto-map/ # Auto-detect +GET /api/v1/gsc/urls/ # Tracked URLs +POST /api/v1/gsc/urls/inspect/ # Manual inspect +POST /api/v1/gsc/urls/request-index/ # Manual index request +GET /api/v1/gsc/urls/queue/ # Queue status +GET /api/v1/gsc/metrics/ # Search metrics +GET /api/v1/gsc/metrics/top-pages/ # Top pages +GET /api/v1/gsc/metrics/top-queries/ # Top queries +GET /api/v1/gsc/metrics/igny8-only/ # IGNY8 content only +``` + +### Rich Schema (Module 5) +``` +GET /api/v1/schema/coverage/ # Site-wide schema coverage stats +POST /api/v1/schema/generate/{content_id}/ # Generate schema for content +POST /api/v1/schema/scan-site/ # Retroactive: scan site +POST /api/v1/schema/generate-bulk/ # Retroactive: generate for multiple pages +POST /api/v1/schema/push-bulk/ # Push approved schemas to WordPress +POST /api/v1/schema/validate/{content_id}/ # Validate schema +GET /api/v1/schema/settings/ # Schema settings +PUT /api/v1/schema/settings/ # Update settings +``` + +### Socializer (Module 6) +``` +GET /api/v1/socializer/accounts/ # List connected accounts +POST /api/v1/socializer/accounts/connect/{platform}/ # OAuth initiate +DELETE /api/v1/socializer/accounts/{id}/ # Disconnect +GET /api/v1/socializer/posts/ # List social posts +POST /api/v1/socializer/posts/generate/ # Generate posts from content +PATCH /api/v1/socializer/posts/{id}/ # Edit post text/schedule +POST /api/v1/socializer/posts/{id}/publish/ # Publish now +DELETE /api/v1/socializer/posts/{id}/ # Delete draft +GET /api/v1/socializer/calendar/ # Calendar view data +GET /api/v1/socializer/analytics/ # Engagement metrics +GET /api/v1/socializer/settings/ # Scheduling rules, defaults +PUT /api/v1/socializer/settings/ # Update settings +``` + +### Video Creator (Module 7) +``` +GET /api/v1/video/projects/ # List video projects +POST /api/v1/video/projects/create/ # Create project from content +GET /api/v1/video/projects/{id}/ # Project detail +PATCH /api/v1/video/projects/{id}/script/ # Edit script +POST /api/v1/video/projects/{id}/approve-script/ # Approve script, start render +POST /api/v1/video/projects/{id}/render/ # Queue rendering +GET /api/v1/video/projects/{id}/renders/ # List renders per platform +POST /api/v1/video/projects/{id}/publish/ # Publish to platforms +GET /api/v1/video/analytics/ # Video metrics +GET /api/v1/video/voices/ # Available TTS voices +``` + +--- + +## 13. Complete AI Function Registry {#13-ai-functions} + +| Function Key | Module | Location | Input | Output | +|-------------|--------|----------|-------|--------| +| `generate_content_product` | 1 | `ai/functions/generate_content.py` (extend) | Task + product context | Product page HTML | +| `generate_content_service` | 1 | same | Task + service context | Service page HTML | +| `generate_content_taxonomy` | 1 | same | Task + term context | Term landing HTML | +| `generate_content_hub` | 1 | same | Task + cluster context | Hub page HTML | +| `optimize_content` | 3 | `ai/functions/optimize_content.py` (implement) | Content + cluster | Optimized content + schema | +| `generate_faq_pairs` | 5 | `schema/ai_functions/` | Content body | FAQ Q&A pairs | +| `extract_howto_steps` | 5 | `schema/ai_functions/` | Content body | HowTo steps | +| `generate_pros_cons` | 5 | `schema/ai_functions/` | Content body | Pros and cons lists | +| `generate_tldr` | 5 | `schema/ai_functions/` | Content body | TL;DR summary | +| `adapt_for_social` | 6 | `socializer/ai_functions/adapt_for_social.py` | Content + platform | Platform-adapted text | +| `generate_hashtags` | 6 | `socializer/ai_functions/generate_hashtags.py` | Content + platform | Hashtag list | +| `generate_video_script` | 7 | `video/ai_functions/generate_script.py` | Content + video_type | VideoScript sections | +| `generate_video_seo` | 7 | `video/ai_functions/generate_video_seo.py` | Script + platform | SEO title/desc/tags | +| `generate_thumbnail` | 7 | `video/ai_functions/generate_thumbnail.py` | Content | Thumbnail image prompt | + +--- + +## 14. Complete Celery Task Registry {#14-celery-tasks} + +| Task | Module | Schedule | Queue | +|------|--------|----------|-------| +| `process_indexing_queue` | GSC | Every 5 min | default | +| `fetch_search_metrics` | GSC | Daily | default | +| `auto_index_published_content` | GSC | On demand (after publish) | default | +| `sync_index_status_to_plugin` | GSC | Every 5 min | default | +| `refresh_gsc_token` | GSC | Daily | default | +| `publish_scheduled_posts` | Socializer | Every 5 min | default | +| `fetch_engagement_metrics` | Socializer | Every 6 hours | default | +| `refresh_social_tokens` | Socializer | Daily | default | +| `render_video` | Video | On demand | video_render (separate) | +| `publish_video` | Video | On demand | default | +| `generate_video_thumbnail` | Video | On demand | default | + +--- + +## 15. Feature Flag Registry {#15-feature-flags} + +| Flag | Module | Controls | Default | +|------|--------|---------|---------| +| `optimizer_enabled` | Optimizer | Optimizer page, optimization API, automation integration | `False` (exists) | +| `gsc_enabled` | GSC | Search Console page, OAuth, auto-indexing | `False` | +| `schema_enabled` | Rich Schema | Schema generation in pipeline, retroactive engine | `False` | +| `socializer_enabled` | Socializer | Socializer page, OAuth, social posting, Stage 9 | `False` | +| `video_enabled` | Video Creator | Video Creator page, rendering, Stage 10 | `False` | + +Content Types Writing and Taxonomy & Term Content have **no feature flags** — they extend existing pipeline capabilities and are always available once deployed. + +--- + +## 16. Credit Cost Summary {#16-credit-costs} + +| Operation | Module | Credits | +|-----------|--------|---------| +| Generate product/service/hub content | Content Types | Same as articles (5 per 100 words) | +| Generate taxonomy landing content | Taxonomy | Same as articles | +| Analyze content for optimization | Optimizer | 2 | +| Optimize content (rewrite) | Optimizer | 5 per 100 words | +| Generate schema elements | Rich Schema | 2 per page | +| Retroactive scan + generate | Rich Schema | 1 per page scanned + 2 per page enhanced | +| Adapt content for 1 platform | Socializer | 1 | +| Generate hashtags | Socializer | 0.5 | +| Generate Twitter thread | Socializer | 2 | +| Generate social image | Socializer | 3-10 | +| Full social suite (5 platforms) | Socializer | 15-25 per content item | +| Generate video script | Video | 5 | +| TTS voiceover | Video | 10/min (standard), 20/min (HD), 2/min (self-hosted) | +| Visual assets per video | Video | 15-50 | +| Thumbnail generation | Video | 3-10 | +| Video composition (render) | Video | 5 per render | +| Video SEO metadata | Video | 1 per platform | +| Full short-form video | Video | ~40-80 total | +| Full long-form video | Video | ~100-250 total | + +--- + +## 17. Cross-Module Dependencies {#17-cross-dependencies} + +``` +Content Types Writing (Module 1) + └── feeds → Taxonomy & Term Content (content structures for term pages) + └── feeds → Optimizer (supports all content types) + └── feeds → Rich Schema (content type classification drives schema mapping) + └── feeds → Socializer (any content type can be socialized) + └── feeds → Video Creator (any content type can become a video) + +Taxonomy & Term Content (Module 2) + └── feeds → Optimizer (term pages can be optimized) + └── feeds → Rich Schema (term pages get schema) + └── depends on → Content Types Writing (Module 1) + └── depends on → SAG Blueprint (Doc A) for cluster mapping + +Optimizer (Module 3) + └── feeds → Rich Schema (schema generation is part of optimization) + └── depends on → Content Types Writing (Module 1) + └── depends on → SAG clusters (Doc A) for cluster matching + +GSC Integration (Module 4) + └── feeds → SAG Backlink Campaigns (Doc A Phase 10) for KPI data + └── feeds → Blueprint Health (Doc A Phase 8) for indexed page tracking + └── INDEPENDENT — no dependencies on other modules + +Rich Schema (Module 5) + └── feeds → WordPress plugin (schema storage + rendering) + └── depends on → Content Types Writing (Module 1) for type classification + └── benefits from → GSC (Module 4) for schema error monitoring + +Socializer (Module 6) + └── depends on → Published content (any module) + └── shares OAuth patterns with → Video Creator (Module 7) + +Video Creator (Module 7) + └── depends on → Published content (any module) + └── depends on → Socializer (Module 6) for shared infrastructure + └── requires → S3/media storage, FFmpeg, separate Celery queue +``` + +--- + +## Reference Documents + +| Document | Purpose | +|----------|---------| +| **IGNY8-Consolidated-Module-Plans.md** | Strategic plans for all modules — source for this guide | +| **IGNY8-Rich-Schema-SERP-Enhancement-Module.docx** | Detailed schema types, mapping matrix, rollout plan | +| **IGNY8-Current-State.md** | Current platform state — all file paths, models, modules | +| **Doc A — SAG Architecture Dev Guide** | SAG models, blueprint, clusters — consumed by Modules 2, 3, 5 | + +--- + +*End of Doc B — IGNY8 Platform Modules Development Guide* diff --git a/docs/plans/final-dev-guides-of-futute-implementation/DocC-WordPress-Ecosystem-Dev-Guide.md b/docs/plans/final-dev-guides-of-futute-implementation/DocC-WordPress-Ecosystem-Dev-Guide.md new file mode 100644 index 00000000..0175c6d6 --- /dev/null +++ b/docs/plans/final-dev-guides-of-futute-implementation/DocC-WordPress-Ecosystem-Dev-Guide.md @@ -0,0 +1,820 @@ +# Doc C — WordPress Ecosystem: Development Guide for Claude Code + +**Version:** 1.0 +**Date:** March 2026 +**For:** Claude Code (Opus 4.6) in VSCode +**Purpose:** Step-by-step implementation guide for the IGNY8 WordPress Plugin (free + connected), Companion Theme, and Toolkit Plugin — where every file goes, what it does, build sequence, and how it connects to the IGNY8 SaaS platform +**Scope:** Plugin (14 modules, 10 build phases), Theme (7 CPTs, 9 taxonomies, 15 landing sections, 50+ block patterns, 5 starters, WooCommerce), Toolkit Plugin (5 modules) +**Rule:** Plugin works with ANY theme. Theme works WITHOUT the plugin. Both work WITHOUT the IGNY8 SaaS platform. Connected mode enhances both but is never required. +**Dependency:** Doc A (SAG Architecture) defines the blueprint/cluster data the plugin receives in connected mode. Doc B (Platform Modules) defines the IGNY8 SaaS features that push content/schemas/links to the plugin. + +--- + +## Table of Contents + +1. [Architecture Overview — Three Deliverables](#1-architecture-overview) +2. [Build Sequence — What Comes First](#2-build-sequence) +3. [IGNY8 Plugin — Foundation & Infrastructure](#3-plugin-foundation) +4. [IGNY8 Plugin — Module 1: SEO Core](#4-seo-core) +5. [IGNY8 Plugin — Module 2: Schema](#5-schema) +6. [IGNY8 Plugin — Module 3: Sitemap](#6-sitemap) +7. [IGNY8 Plugin — Module 4: Redirects](#7-redirects) +8. [IGNY8 Plugin — Module 5: Site Intelligence](#8-site-intelligence) +9. [IGNY8 Plugin — Module 6: Internal Linking](#9-internal-linking) +10. [IGNY8 Plugin — Module 7: GSC](#10-gsc) +11. [IGNY8 Plugin — Module 8: Socializer](#11-socializer) +12. [IGNY8 Plugin — Module 9: Analytics + SMTP](#12-analytics-smtp) +13. [IGNY8 Plugin — Module 10: Content Sync (Connected)](#13-content-sync) +14. [IGNY8 Plugin — Module 11: SAG Structure (Connected)](#14-sag-structure) +15. [IGNY8 Plugin — Setup Wizard & Import](#15-setup-wizard) +16. [IGNY8 Plugin — Data Architecture](#16-data-architecture) +17. [IGNY8 Plugin — REST API Endpoints](#17-rest-api) +18. [IGNY8 Plugin — Performance Rules](#18-performance) +19. [Theme — CPTs, Taxonomies, Meta Fields](#19-theme-structure) +20. [Theme — Term Landing Pages & SAG Templates](#20-term-templates) +21. [Theme — Landing Page Builder](#21-landing-pages) +22. [Theme — Block Patterns & Starter Templates](#22-patterns-starters) +23. [Theme — Interlinking Display Components](#23-interlinking-display) +24. [Theme — WooCommerce Integration](#24-woocommerce) +25. [Theme — Design System & Build Plan](#25-design-build) +26. [Toolkit Plugin — All 5 Modules](#26-toolkit) +27. [Free vs Premium Split](#27-free-premium) +28. [Theme ↔ Plugin Contract](#28-theme-plugin-contract) +29. [Plugin ↔ IGNY8 SaaS Communication](#29-saas-communication) + +--- + +## 1. Architecture Overview — Three Deliverables {#1-architecture-overview} + +``` +┌────────────────────────────────────────────────────────────┐ +│ IGNY8 PLUGIN │ +│ SEO Core, Schema, Sitemap, Redirects, Analytics, GSC, │ +│ Site Intelligence, Internal Linking, Socializer, SMTP │ +│ + Connected: Content Sync, SAG Structure │ +│ │ +│ Distribution: Free on WordPress.org │ +│ Connected premium features via IGNY8 SaaS subscription │ +│ Works with ANY theme │ +└──────────────────────┬─────────────────────────────────────┘ + │ reads plugin data via igny8() API +┌──────────────────────┴─────────────────────────────────────┐ +│ COMPANION THEME │ +│ 7 CPTs, 9 custom taxonomies, meta fields, SAG templates, │ +│ term landing pages, landing page builder, 50+ patterns, │ +│ 5 site-type starters, WooCommerce templates, design system │ +│ │ +│ Distribution: Free on WordPress.org (limited), Premium │ +│ Works WITHOUT the plugin (graceful degradation) │ +└──────────────────────┬─────────────────────────────────────┘ + │ extends theme with infrastructure +┌──────────────────────┴─────────────────────────────────────┐ +│ TOOLKIT PLUGIN │ +│ Performance/Caching, Forms, Security, SMTP, WooCommerce │ +│ │ +│ Distribution: Free on WordPress.org (limited), Premium │ +│ Works with ANY theme │ +└────────────────────────────────────────────────────────────┘ +``` + +**Key principle:** Each piece works independently. Together they create the full SAG-optimized WordPress experience. + +--- + +## 2. Build Sequence — What Comes First {#2-build-sequence} + +``` +PHASE 1 (Days 1-3) ─── Plugin Foundation + │ Skeleton, module manager, admin menu, REST API base, + │ setup wizard, database installer, compatibility layer + +PHASE 2 (Days 4-7) ─── SEO Core Module + │ Meta box, title tags, meta description, content analysis, + │ OG tags, breadcrumbs, robots.txt, verification codes + +PHASE 3 (Days 8-10) ─── Schema + Sitemap + Redirects + │ JSON-LD schemas, XML sitemap, redirect manager, 404 monitor + +PHASE 4 (Days 11-13) ── Site Intelligence + │ Site audit, orphan detection, thin content, cannibalization, + │ cluster detection, intelligence dashboard + +PHASE 5 (Days 14-15) ── Internal Linking + │ Link crawl, link audit, suggestions, link graph + +PHASE 6 (Days 16-18) ── Socializer + Analytics + SMTP + │ Share buttons, social profiles, GA/GTM connector, + │ pixel manager, SMTP override, GSC OAuth + dashboard + +PHASE 7 (Days 19-20) ── SEO Import + │ Yoast, RankMath, AIOSEO importers + +PHASE 8 (Days 21-23) ── Connected Mode — Content Sync + │ API client, content puller, mapper, sync queue, scheduler + +PHASE 9 (Days 24-27) ── Connected Mode — SAG Structure + │ Blueprint sync, taxonomy builder, term builder, + │ cluster manager, structure visualizer + +PHASE 10 (Days 28-30) ─ Polish + Package + Cross-module testing, performance audit, WP.org compliance + +--- THEME BUILD (30 days, can overlap with plugin Phases 6+) --- + +THEME PHASE 1 (Days 1-3) Foundation (templates, design system, CSS) +THEME PHASE 2 (Days 4-6) CPTs + Taxonomies + Meta Boxes +THEME PHASE 3 (Days 7-9) Term Landing Page Templates +THEME PHASE 4 (Days 10-11) Interlinking Display Components +THEME PHASE 5 (Days 12-14) Landing Page Builder +THEME PHASE 6 (Days 15-16) Single Templates (service, portfolio, docs) +THEME PHASE 7 (Days 17-19) Custom Blocks + 50+ Patterns +THEME PHASE 8 (Days 20-22) Site-Type Starters + WooCommerce +THEME PHASE 9 (Days 23-27) Toolkit Plugin (all 5 modules) +THEME PHASE 10 (Days 28-30) Setup Wizard + Polish + +--- THEME CAN START after Plugin Phase 5 (interlinking data contract defined) --- +``` + +--- + +## 3. IGNY8 Plugin — Foundation & Infrastructure {#3-plugin-foundation} + +### 3.1 Complete File Structure + +``` +igny8/ +├── igny8.php # Plugin header, bootstrap, constants +├── readme.txt # WordPress.org readme +├── uninstall.php # Full cleanup on uninstall +│ +├── includes/ +│ ├── class-igny8.php # Main singleton class +│ ├── class-module-manager.php # Register, activate, deactivate modules +│ ├── class-api-client.php # IGNY8 SaaS API client (connected mode) +│ ├── class-connection.php # API key validation, connection status +│ ├── class-utils.php # Shared utilities +│ ├── class-ajax.php # Shared AJAX handler +│ ├── class-rest-api.php # Plugin REST endpoints (for theme + external) +│ ├── class-compatibility.php # Detect conflicting plugins, show notices +│ │ +│ ├── modules/ # 14 modules (see sections 4-14) +│ │ ├── seo/ # SEO Core (Phase 2) +│ │ ├── schema/ # Schema (Phase 3) +│ │ ├── sitemap/ # Sitemap (Phase 3) +│ │ ├── redirects/ # Redirects (Phase 3) +│ │ ├── analytics/ # Analytics (Phase 6) +│ │ ├── site-intelligence/ # Site Intelligence (Phase 4) +│ │ ├── linking/ # Internal Linking (Phase 5) +│ │ ├── gsc/ # Google Search Console (Phase 6) +│ │ ├── socializer/ # Social sharing + posting (Phase 6) +│ │ ├── smtp/ # Email delivery (Phase 6) +│ │ ├── content-sync/ # [Connected] Content from IGNY8 (Phase 8) +│ │ └── sag/ # [Connected] SAG structure (Phase 9) +│ │ +│ ├── admin/ # Admin UI infrastructure +│ │ ├── class-admin-menu.php # Menu registration (top-level "IGNY8" menu) +│ │ ├── class-dashboard.php # Main plugin dashboard page +│ │ ├── class-setup-wizard.php # First-run wizard (6 steps) +│ │ ├── class-compatibility-notice.php # Admin notices for conflicts +│ │ ├── views/ # PHP templates for admin pages +│ │ │ ├── dashboard.php +│ │ │ ├── wizard/step-1 through step-6.php +│ │ │ └── connect-prompt.php +│ │ └── assets/ +│ │ ├── admin.css, admin.js +│ │ └── meta-box.css, meta-box.js +│ │ +│ ├── frontend/ +│ │ ├── class-head-output.php # ALL output (meta, schema, OG) in single hook +│ │ ├── class-share-output.php # Share button HTML/CSS/JS (conditional) +│ │ └── assets/ +│ │ ├── share-buttons.css # <3KB, loaded only if share enabled +│ │ └── share-buttons.js # <2KB, loaded only if share enabled +│ │ +│ ├── data/ +│ │ ├── class-installer.php # Create all custom DB tables on activation +│ │ ├── class-migrator.php # Version-based migration handler +│ │ └── class-importer.php # Import from Yoast/RankMath/AIOSEO +│ │ +│ └── integrations/ +│ ├── class-woocommerce.php # WooCommerce-specific SEO/schema +│ └── class-theme-bridge.php # Data passing to companion theme +│ +└── languages/ + └── igny8.pot # Translation template +``` + +### 3.2 Module Manager Pattern + +Every module follows the same lifecycle: + +```php +// class-module-manager.php pattern + +class ModuleManager { + private $modules = []; + + public function register($slug, $class, $options = []) { + // Register module with slug, class path, free/connected flag + } + + public function activate($slug) { + // Enable module, call module's activate() method + } + + public function deactivate($slug) { + // Disable module, call module's deactivate() method + } + + public function is_active($slug) { + // Check igny8_active_modules option + } + + public function boot_active_modules() { + // Called on plugins_loaded — instantiate all active modules + } +} + +// Each module extends: +abstract class IGNY8_Module { + abstract public function get_slug(); + abstract public function get_name(); + abstract public function init(); // Hook registration + public function activate() {} // On module enable + public function deactivate() {} // On module disable + public function is_connected_only() { return false; } +} +``` + +### 3.3 Admin Menu Structure + +``` +IGNY8 (top-level menu, dashicons-chart-area) +├── Dashboard # Plugin overview + connect prompt +├── SEO # SEO settings page +├── Schema # Schema settings +├── Sitemaps # Sitemap configuration +├── Redirects # Redirect manager + 404 log +├── Site Intelligence # Audit dashboard +├── Internal Links # Link audit + suggestions +├── Search Console # GSC connection + metrics +├── Socializer # Share buttons + accounts +├── Analytics # GA/GTM/pixel settings +├── SMTP # Mail settings +├── Settings # Global plugin settings +│ +└── (Connected only, appear after connection): + ├── Content Sync # Sync dashboard + └── SAG Structure # Blueprint + structure visualizer +``` + +### 3.4 Public API Class + +The plugin exposes a global function for themes and other plugins: + +```php +function igny8() { + return IGNY8::instance(); +} + +// Usage by theme: +if (function_exists('igny8')) { + $title = igny8()->seo->get_title($post_id); + $schema = igny8()->schema->get_json_ld($post_id); + $breadcrumbs = igny8()->seo->get_breadcrumbs(); + $related = igny8()->linking->get_related_links($post_id); + $cluster_nav = igny8()->linking->get_cluster_navigation($post_id); + $term_content = igny8()->seo->get_term_content($term_id); + $share = igny8()->socializer->render_share_buttons($post_id); +} +``` + +--- + +## 4-12. Plugin Modules — Build Reference {#4-seo-core} + +Each module section below specifies: files to create, what each file does, which hooks it uses, what data it reads/writes, and how it connects to the IGNY8 SaaS platform in connected mode. + +### Module 1: SEO Core (Phase 2, Days 4-7) + +**Files:** `modules/seo/` — 9 PHP files + 2 view templates (see file structure above) + +**What it does:** +- `class-meta-box.php` — Adds SEO meta box below editor on all post types. Fields: focus keyword, SEO title (with SERP preview), meta description (with character counter), canonical URL, robots index/follow toggles. Saves to `_igny8_*` post meta keys. Connected enhancement: multi-keyword fields, cluster-aware scoring. +- `class-title-tag.php` — Manages `` tag output. Template system: `{site_title} {separator} {page_title}`. Customizable per post type. Filters: `igny8_title_parts`, `igny8_title_separator`. +- `class-meta-tags.php` — Outputs `<meta name="description">`, `<meta name="robots">`, `<link rel="canonical">` in `<head>`. Single `wp_head` hook at priority 1. +- `class-content-analysis.php` — Real-time JavaScript analysis in editor: keyword density, heading check (H1 count, H2 usage), readability score (Flesch), internal link count, image alt text check, meta length check. Outputs score 0-100 stored in `_igny8_seo_score`. +- `class-breadcrumbs.php` — Generates breadcrumb HTML. Shortcode `[igny8_breadcrumbs]`. Also outputs BreadcrumbList schema. SAG-aware: when connected, breadcrumbs follow dimensional path (Home → Attribute → Term → Post). +- `class-opengraph.php` — OG title, description, image, type, URL. Twitter Card meta. Per-post overrides via meta box. +- `class-robots-txt.php` — Virtual robots.txt manager. Adds sitemap URL, custom rules. +- `class-verification.php` — Google, Bing, Pinterest, Yandex verification meta tags. + +**WP Hooks used:** `wp_head` (priority 1), `add_meta_boxes`, `save_post`, `wp_title`, `document_title_parts`, `the_content` (for breadcrumb auto-insertion option). + +### Module 2: Schema (Phase 3, Days 8-9) + +**Files:** `modules/schema/` — 12 PHP files + +**What it does:** Generates JSON-LD for all schema types and outputs as a single `<script type="application/ld+json">` block in `wp_head`. Schema types: Article/BlogPosting, Organization/Person, WebPage/CollectionPage, BreadcrumbList, FAQPage, HowTo, LocalBusiness, Service, Product (WooCommerce), WebSite+SearchAction, custom field for advanced users. + +**Schema selection logic:** Content type → schema type mapping. Blog posts get Article. Service CPT gets Service. Products get Product. FAQ CPT gets FAQPage. Hub pages get WebPage. Users can override via `_igny8_schema_type` meta. + +**Connected enhancement:** IGNY8 SaaS pushes pre-generated schemas (FAQ pairs, HowTo steps, Pros/Cons) via bulk endpoint. Plugin stores in post meta and renders alongside auto-generated schemas. + +### Module 3: Sitemap (Phase 3, Day 9) + +**Files:** `modules/sitemap/` — 5 PHP files + +**What it does:** XML sitemap index at `/sitemap_index.xml`. Sub-sitemaps per post type, per taxonomy, image sitemap. XSL stylesheet for browser viewing. Respects noindex settings. Includes `<lastmod>`, `<image:image>`. WooCommerce: includes price, availability in product sitemap entries. + +### Module 4: Redirects (Phase 3, Day 10) + +**Files:** `modules/redirects/` — 4 PHP files + 1 view + +**What it does:** CRUD for 301/302/307 redirects in custom DB table. 404 monitoring with hit count. Auto-redirect when post slug changes. CSV import/export. Admin page with sortable/filterable table. + +### Module 5: Site Intelligence (Phase 4, Days 11-13) + +**Files:** `modules/site-intelligence/` — 10 PHP files + 2 views + +**What it does (Free):** Site audit runner (WP Cron scheduled, weekly). Orphan page detection (pages with 0 internal links pointing to them). Thin content scanner (below word count threshold, configurable). Empty taxonomy terms. Duplicate title/meta detection. Keyword cannibalization (multiple pages targeting same keyword). Basic cluster detection (auto-group content by topic similarity). + +**What it does (Connected):** Full SAG gap analysis: missing clusters, missing term pages, missing attribute values. Cluster health scores: content coverage, link density per cluster. Architecture blueprint showing recommended new pages. Priority queue: which gaps to fill first. Topical authority scoring per cluster. + +**Dashboard:** Admin page showing audit results. Severity color coding (critical/warning/info). Per-issue action buttons. Re-run audit button. Connected: SAG gap analysis section with "Connect to IGNY8 to fix these gaps" CTA. + +### Module 6: Internal Linking (Phase 5, Days 14-15) + +**Files:** `modules/linking/` — 7 PHP files + 2 views + +**What it does (Free):** Link crawl: scans all content, builds `{prefix}igny8_link_map` table. Link audit page: per-post inbound/outbound link counts, broken links, orphan pages. Link suggestions: "This post could link to these 5 related posts" based on shared categories/tags/keywords. Link equity distribution overview. + +**What it does (Connected):** SAG-aware automatic link suggestions based on cluster relationships (data from Doc A Linker module). Bulk link insertion tool. Link template rules (keyword → URL mapping). Contextual link placement (AI-determined anchor text and position). Link priority scoring based on cluster importance. + +### Module 7: GSC (Phase 6, Day 18) + +**Files:** `modules/gsc/` — 6 PHP files + 2 views + +**What it does (Free):** Google OAuth connection. Search performance dashboard: clicks, impressions, CTR, position. Keyword position tracking. Date range filtering. + +**What it does (Connected):** URL Inspection API: inspect any URL's index status. Auto-indexing: content published via IGNY8 gets auto-inspected and index-requested (driven by IGNY8 SaaS, plugin receives status updates). Status display: index status column in content list, metabox on edit screen. + +### Module 8: Socializer (Phase 6, Days 16-17) + +**Files:** `modules/socializer/` — 8 PHP files + 2 views + +**What it does (Free):** Pure CSS/JS share buttons (zero external dependencies, <5KB total). Position options: floating, above/below content, inline. Networks: Facebook, X, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy Link. Social profile links management (site-wide, used in schema). + +**What it does (Connected):** Auto-post to social platforms on WordPress publish (content adapted by IGNY8 SaaS Socializer module). Per-platform message templates. Scheduling. Platform API connections: X, Facebook Pages, LinkedIn, Instagram. Dynamic OG image generation. Social post performance tracking. + +### Module 9: Analytics + SMTP (Phase 6, Days 17-18) + +**Analytics files:** `modules/analytics/` — 4 PHP files +**SMTP files:** `modules/smtp/` — 3 PHP files + +**Analytics:** GA4 connector (tracking code injection), GTM connector, Facebook/TikTok/Pinterest pixel manager, custom header/footer scripts manager. + +**SMTP:** Override `wp_mail()` with SMTP credentials. Email delivery log in custom DB table. Test email utility. + +--- + +## 13. IGNY8 Plugin — Content Sync (Connected Mode) {#13-content-sync} + +### Files + +``` +modules/content-sync/ +├── class-sync-module.php # Module entry, WP Cron scheduling +├── class-content-puller.php # Fetch content from IGNY8 SaaS API +├── class-content-mapper.php # Map IGNY8 content_type → WP post type +├── class-image-downloader.php # Download AI images → attach to posts +├── class-sync-queue.php # {prefix}igny8_sync_queue table management +├── class-publish-scheduler.php # Review queue, scheduled publishing +└── views/ + ├── sync-dashboard.php # Status, controls, history + └── content-review.php # Review queue before publish +``` + +### Content Type Mapping + +| IGNY8 content_type | WP post_type | WP template | Notes | +|-------------------|-------------|-------------|-------| +| post | post | Standard | Default | +| page | page | Default page | — | +| product | product | WooCommerce product | Requires WooCommerce | +| service | service | single-service template | Requires theme CPT | +| company_page | page | page-company template | — | +| taxonomy_landing | — | — | Written to term description, not a post | +| cluster_hub | page | page-hub template | Landing page preset applied | +| comparison | post | Standard | — | +| brand_page | post or page | Standard | — | + +### Sync Flow + +``` +IGNY8 SaaS publishes content + → Webhook to plugin: POST /wp-json/igny8/v1/sync/push + → Plugin creates sync queue entry (status: pending) + → WP Cron processes queue: + 1. Download images → attach to media library + 2. Map content_type → WP post_type + 3. Create/update WP post with content, meta, featured image + 4. Assign taxonomies from IGNY8 cluster/attribute data + 5. If taxonomy_landing: write to term description instead + 6. Status: 'review' (manual review required) or 'synced' (auto-publish) + → Plugin POSTs confirmation back to IGNY8 SaaS +``` + +--- + +## 14. IGNY8 Plugin — SAG Structure (Connected Mode) {#14-sag-structure} + +### Files + +``` +modules/sag/ +├── class-sag-module.php # Module entry +├── class-blueprint-sync.php # Receive SAG blueprint JSON from IGNY8 +├── class-taxonomy-builder.php # register_taxonomy() from SAG attributes +├── class-term-builder.php # wp_insert_term() from attribute values +├── class-cluster-manager.php # Map clusters → hub pages/terms +├── class-structure-visualizer.php # Visual map of site structure +└── views/ + ├── sag-dashboard.php # SAG structure overview + ├── blueprint-review.php # Review proposed taxonomies before applying + └── structure-map.php # Visual cluster/taxonomy/content map +``` + +### Blueprint Sync Flow + +``` +IGNY8 SaaS confirms blueprint + → POST to plugin: /wp-json/igny8/v1/sag/sync-blueprint + → Plugin stores blueprint in igny8_sag_blueprint option + → Blueprint review UI shows proposed changes: + - New taxonomies to create + - New terms to create + - Existing taxonomies to map + → User approves → Taxonomy Builder executes: + 1. register_taxonomy() for each SAG attribute + (stored in option for persistence across requests) + 2. wp_insert_term() for each attribute value + 3. Set term meta: _igny8_term_sag_attribute, _igny8_term_sag_level + 4. Map clusters to existing hub pages or create placeholders + → Plugin POSTs success + term IDs back to IGNY8 SaaS + → IGNY8 SaaS updates SAGAttribute.wp_taxonomy_slug and wp_sync_status +``` + +### Structure Visualizer + +Admin page showing: +- Tree view: Taxonomies → Terms → assigned posts/products +- Cluster map: clusters as cards with hub page status, supporting content count +- Gap indicators: terms without content, clusters without hubs +- Connected to IGNY8: "Generate content for this term" links to IGNY8 app + +--- + +## 15. Setup Wizard & SEO Import {#15-setup-wizard} + +### Wizard Steps + +| Step | Title | What It Does | +|------|-------|-------------| +| 1 | Site Type | Blog, Business, eCommerce, Local Business, SaaS, Portfolio — sets schema defaults | +| 2 | SEO Import | Detects Yoast/RankMath/AIOSEO → one-click import via WP Cron | +| 3 | Site Basics | Site name, Organization/Person, logo, title separator | +| 4 | Social Profiles | All social URLs + default sharing image | +| 5 | Connect to IGNY8 | API key input, connection test, site pairing. Clear skip option. | +| 6 | Done | Summary, "Run first site audit" CTA, key settings links | + +### SEO Import Data Mapping + +| Source | Source Meta Key | IGNY8 Meta Key | +|--------|----------------|---------------| +| Yoast | `_yoast_wpseo_focuskw` | `_igny8_focus_keyword` | +| Yoast | `_yoast_wpseo_title` | `_igny8_seo_title` | +| Yoast | `_yoast_wpseo_metadesc` | `_igny8_meta_description` | +| Yoast | `_yoast_wpseo_canonical` | `_igny8_canonical_url` | +| Yoast | `_yoast_wpseo_meta-robots-noindex` | `_igny8_robots_index` | +| RankMath | `rank_math_focus_keyword` | `_igny8_focus_keyword` | +| RankMath | `rank_math_title` | `_igny8_seo_title` | +| RankMath | `rank_math_description` | `_igny8_meta_description` | +| RankMath | `rank_math_canonical_url` | `_igny8_canonical_url` | +| RankMath | `rank_math_robots` | `_igny8_robots_index` + `_igny8_robots_follow` | +| AIOSEO | `_aioseo_title` | `_igny8_seo_title` | +| AIOSEO | `_aioseo_description` | `_igny8_meta_description` | + +Import runs as background WP Cron task with progress tracking. Completion report shows counts per data type. + +--- + +## 16. Data Architecture {#16-data-architecture} + +### Custom Database Tables + +| Table | Purpose | Created In | +|-------|---------|-----------| +| `{prefix}igny8_redirects` | Redirect rules (source, target, type, hits) | Phase 3 | +| `{prefix}igny8_404_log` | 404 hit log (URL, referrer, hits, resolved) | Phase 3 | +| `{prefix}igny8_link_map` | Internal link graph (source→target, anchor, position) | Phase 5 | +| `{prefix}igny8_audit_results` | Site audit findings (type, severity, message, data) | Phase 4 | +| `{prefix}igny8_email_log` | SMTP delivery log (to, subject, status, error) | Phase 6 | +| `{prefix}igny8_sync_queue` | Content sync queue (IGNY8 ID, status, WP post/term ID) | Phase 8 | + +### Post Meta Keys (all prefixed `_igny8_`) + +SEO: `focus_keyword`, `secondary_keywords`, `seo_title`, `meta_description`, `canonical_url`, `robots_index`, `robots_follow`, `og_title`, `og_description`, `og_image`, `twitter_title`, `twitter_description`, `schema_type`, `schema_custom`, `seo_score`, `content_score`, `readability_score` + +Connected: `cluster_id`, `related_links`, `link_suggestions`, `last_analysis`, `igny8_content_id`, `sync_status`, `schema_faq`, `schema_howto`, `schema_article`, `schema_review` + +### Term Meta Keys (all prefixed `_igny8_term_`) + +`seo_title`, `meta_description`, `robots_index`, `og_image`, `content`, `cluster_id`, `sag_attribute`, `sag_level`, `faq`, `related_terms`, `igny8_id` + +### Options Keys (all prefixed `igny8_`) + +Global: `version`, `active_modules`, `seo_settings`, `schema_settings`, `sitemap_settings`, `social_profiles`, `analytics_settings`, `redirect_settings`, `smtp_settings`, `share_settings`, `linking_settings`, `intelligence_settings` + +Connected: `api_key`, `api_connected`, `site_id`, `last_sync`, `sag_blueprint`, `gsc_token`, `gsc_property` + +--- + +## 17. REST API Endpoints {#17-rest-api} + +### Plugin-Provided Endpoints (for theme + external consumers) + +``` +GET /wp-json/igny8/v1/related/{post_id} # Related content links +GET /wp-json/igny8/v1/cluster/{cluster_id} # All content in cluster +GET /wp-json/igny8/v1/term/{term_id}/content # Term landing page data +GET /wp-json/igny8/v1/structure/overview # Site structure summary +GET /wp-json/igny8/v1/audit/summary # Site audit summary +``` + +### Plugin-Received Endpoints (from IGNY8 SaaS platform) + +``` +POST /wp-json/igny8/v1/sync/push # Push content from IGNY8 +POST /wp-json/igny8/v1/sag/sync-blueprint # Push SAG blueprint +POST /wp-json/igny8/v1/sag/create-taxonomies # Create taxonomies from blueprint +POST /wp-json/igny8/v1/terms/{term_id}/content # Push term content +POST /wp-json/igny8/v1/schema/bulk-update # Push schemas for multiple posts +POST /wp-json/igny8/v1/gsc/status-sync # Push GSC index statuses +POST /wp-json/igny8/v1/event # Webhooks (task ready, etc.) +``` + +All endpoints validate `X-IGNY8-API-KEY` header against `Site.wp_api_key`. + +--- + +## 18. Performance Rules {#18-performance} + +| Rule | How | +|------|-----| +| Zero frontend CSS unless share buttons enabled | `wp_enqueue_scripts` with conditional check | +| Zero frontend JS unless share buttons or dynamic features active | Same conditional | +| ALL `<head>` output in single `wp_head` hook at priority 1 | `class-head-output.php` consolidates everything | +| Schema as single JSON-LD block, not multiple `<script>` tags | `class-schema-generator.php` merges all schemas | +| Admin assets only on IGNY8 admin pages | `admin_enqueue_scripts` with screen check | +| Meta box assets only on editor screens | Screen check before enqueue | +| Site audit runs via WP Cron, never on page load | `wp_schedule_event` weekly | +| Link crawl is background process | WP Cron, batch processing | +| Connected mode API calls are async | WP Cron queue, never blocks | +| Option reads use object cache | `wp_cache_get/set` wrapping | + +--- + +## 19-25. Theme Build Reference {#19-theme-structure} + +### 19. CPTs, Taxonomies, Meta Fields + +**7 CPTs:** service, landing_page, portfolio, team_member, testimonial, faq, documentation + +**9 Custom Taxonomies:** service_category, service_area, service_attribute, cluster, portfolio_category, portfolio_tag, faq_category, doc_category, topic_tag + +**WooCommerce:** Theme does NOT register Woo taxonomies. Provides rich templates for product_cat, product_tag, pa_* archives. Registers `cluster` taxonomy for `product` post type. + +**Meta fields per CPT:** Service (10 fields: price, duration, process steps, outcomes, FAQs, CTA, areas, gallery, related). Portfolio (8 fields: client, date, URL, results, tech, testimonial, gallery, before/after). Team (6 fields: position, email, phone, social, order, department). Testimonial (8 fields: author name/title, company, rating, image, featured, linked service/product). FAQ (2 fields: order, schema enabled). Documentation (4 fields: sidebar, TOC, last reviewed, related docs). + +All theme meta keys use `_theme_` prefix. Theme reads `_igny8_` prefix for plugin data. + +### 20. Term Landing Pages & SAG Templates + +Every taxonomy term archive renders as a rich landing page with 7 sections: + +1. **Term Hero** — H1 from term name, description, breadcrumbs, post count +2. **Rich Content** — From IGNY8 `_igny8_term_content` or WP term description +3. **Child Terms** — Grid of child term cards (if hierarchical) +4. **Posts Grid** — All posts in this term, paginated +5. **Related Clusters** — Other clusters sharing attribute values +6. **FAQ** — From `_igny8_term_faq` or `_theme_*` meta +7. **CTA** — Configurable call to action + +Template files: `taxonomy-service_category.html`, `taxonomy-service_area.html`, `taxonomy-service_attribute.html`, `taxonomy-cluster.html`, `taxonomy-faq_category.html`, `taxonomy-product_cat.html`, `taxonomy-product_tag.html` + +### 21. Landing Page Builder + +**CPT:** `landing_page` with section repeater meta box (`_theme_landing_sections`) + +**15 section types:** hero, features-grid, how-it-works, social-proof, pricing, faq, cta-band, content-block, stats-counter, team, portfolio-grid, contact-form, video-embed, logo-bar, comparison-table + +**8 presets:** SaaS Product, Service Business, Product Launch, Lead Generation, Portfolio/Agency, Event/Webinar, Cluster Hub, Term Landing + +Admin JS: drag-to-reorder sections, add/remove/duplicate, per-section field configuration. Frontend renderer: loops through sections, renders each with its template. + +### 22. Block Patterns & Starter Templates + +**50+ block patterns** organized by category: Heroes (4), Content (4), Social Proof (4), Conversion (4), Services (3), Portfolio (3), Footers (3), plus additional patterns. + +**5 site-type starters** (importable demo content): Blog, SaaS, Corporate, eCommerce, Portfolio. Each includes: front-page, core pages, sample CPT entries, sample taxonomy terms. + +### 23. Interlinking Display Components + +6 template parts that read IGNY8 plugin data with graceful fallbacks: + +| Component | Template Part | Data Source | Fallback | +|-----------|-------------|-------------|----------| +| Related Content | `parts/related-content.html` | `_igny8_related_links` post meta | WordPress related by category | +| Cluster Navigation | `parts/cluster-navigation.html` | `igny8()->linking->get_cluster_navigation()` | Posts in same cluster term | +| Attribute Browse | `parts/attribute-browse.html` | Custom taxonomy terms for context | — | +| Breadcrumb Trail | `parts/breadcrumbs.html` | `igny8()->seo->get_breadcrumbs()` | Theme simple breadcrumbs | +| Term Quick Links | `parts/term-quick-links.html` | All terms assigned to current post | — | +| Child Term Grid | `parts/child-term-grid.html` | `get_term_children()` + term meta | — | + +### 24. WooCommerce Integration + +When WooCommerce active, theme provides: +- `woocommerce/archive-product.php` — SAG-structured shop page +- `woocommerce/single-product.php` — Enhanced product page +- `woocommerce/taxonomy-product_cat.php` — Rich category landing page +- `woocommerce/content-product.php` — Product card in archives +- Cart, checkout, account template overrides + +### 25. Design System & Build Execution + +**theme.json:** Complete design token system — colors (primary palette + extended), typography (heading + body from curated list), spacing scale, shadows, border radius, transitions. Custom tokens for term pages and interlinking components. + +**CSS:** BEM naming `.tn-block__element--modifier`. Total CSS budget <35KB gzipped. +**JS:** ES6+, vanilla JS, no jQuery on frontend. Each feature in own file, conditionally loaded. Total JS budget <15KB gzipped. + +**Performance targets:** FCP <1.0s, LCP <1.5s, TBT <50ms, CLS <0.05, PageSpeed 95+ mobile. + +--- + +## 26. Toolkit Plugin — All 5 Modules {#26-toolkit} + +### File Structure + +``` +theme-name-toolkit/ +├── theme-name-toolkit.php # Plugin header, module loader +├── readme.txt +├── includes/ +│ ├── class-toolkit.php # Main class +│ ├── class-module-manager.php # Module toggle system +│ ├── modules/ +│ │ ├── performance/ # Page cache, asset optimizer, image optimizer, +│ │ │ # critical CSS, HTML minifier, browser cache, preload +│ │ ├── forms/ # Form builder, renderer, processor, notifications, +│ │ │ # entries admin, anti-spam +│ │ ├── security/ # Login protection, firewall, hardening, headers, audit log +│ │ ├── smtp/ # SMTP mailer, email log, test email +│ │ └── woocommerce/ # Quick view, wishlist, AJAX cart, product filters, gallery +│ └── admin/ +│ ├── class-dashboard.php # Module toggle dashboard +│ └── views/dashboard.php +└── languages/ +``` + +Each module: independent enable/disable toggle from toolkit dashboard. Zero frontend impact when disabled. + +--- + +## 27. Free vs Premium Split {#27-free-premium} + +### Theme + +| Feature | Free (WordPress.org) | Premium | +|---------|---------------------|---------| +| All 7 CPTs + taxonomies | ✅ | ✅ | +| All term landing page templates | ✅ | ✅ | +| Basic interlinking components | ✅ | ✅ | +| Landing page sections | 3 (hero, content-block, cta-band) | All 15 | +| Landing page presets | 2 (generic, service) | All 8 | +| Block patterns | 10 (2 per category) | All 50+ | +| Starter templates | 2 (blog, corporate) | All 5 | +| WooCommerce templates | ❌ | ✅ | +| Setup wizard + demo import | ❌ | ✅ | +| IGNY8 plugin bridge | ✅ Full | ✅ Full | + +### Toolkit Plugin + +| Feature | Free | Premium | +|---------|------|---------| +| Performance: page cache + HTML minification | ✅ | ✅ | +| Performance: full suite (critical CSS, image opt, WebP, assets) | ❌ | ✅ | +| Security: basic hardening + login protection | ✅ | ✅ | +| Security: full suite (firewall, audit log, 2FA) | ❌ | ✅ | +| Forms: basic (5 field types) | ✅ | ✅ | +| Forms: full suite (conditional logic, multi-step, file upload) | ❌ | ✅ | +| SMTP: basic mail override | ✅ | ✅ | +| SMTP: full suite (email log, templates) | ❌ | ✅ | +| WooCommerce enhancements | ❌ | ✅ | + +--- + +## 28. Theme ↔ Plugin Contract {#28-theme-plugin-contract} + +### What Theme Reads from Plugin + +| Data | Source | Used For | +|------|--------|---------| +| SEO title | `igny8()->seo->get_title()` | `<title>` tag (theme defers to plugin) | +| Breadcrumbs | `igny8()->seo->get_breadcrumbs()` | Breadcrumb display | +| Related links | `_igny8_related_links` post meta | Related Articles section | +| Cluster navigation | `igny8()->linking->get_cluster_navigation()` | "More in this topic" section | +| Term landing content | `_igny8_term_content` term meta | Term archive hero section | +| Term FAQs | `_igny8_term_faq` term meta | FAQ accordion on term pages | +| Related terms | `_igny8_term_related_terms` term meta | "Related topics" block | +| SAG attribute label | `_igny8_term_sag_attribute` term meta | Attribute navigation sections | +| Share buttons | `igny8()->socializer->render_share_buttons()` | Social sharing section | +| Schema | `igny8()->schema->get_json_ld()` | Theme does NOT render schema (plugin owns `<head>`) | + +### Graceful Degradation + +```php +// Theme pattern for ALL plugin data reads: +if (function_exists('igny8')) { + $data = igny8()->module->get_data($id); +} else { + $data = theme_fallback_function($id); +} +``` + +When plugin is NOT installed: breadcrumbs use theme's simple implementation, related content uses category-based matching, term pages show standard WP description, share buttons don't render, schema doesn't output. + +--- + +## 29. Plugin ↔ IGNY8 SaaS Communication {#29-saas-communication} + +### Authentication + +- Plugin stores `igny8_api_key` (from setup wizard Step 5) +- All requests to IGNY8 SaaS include `Authorization: Bearer {api_key}` +- All requests FROM IGNY8 SaaS to plugin include `X-IGNY8-API-KEY` header +- Plugin validates against `igny8_api_key` option + +### Outbound (Plugin → SaaS) + +| Event | Endpoint on SaaS | Payload | +|-------|------------------|---------| +| Site structure sync (daily) | `POST /v1/integration/integrations/{id}/update-structure/` | Post types, taxonomies, counts | +| Incremental data sync | `POST /v1/integration/integrations/{id}/sync-data/` | Modified posts since last sync | +| Full site scan (weekly) | `POST /v1/integration/integrations/{id}/full-scan/` | All posts, products, taxonomies | +| Content publish confirmation | `POST /v1/integration/integrations/{id}/publish-confirm/` | WP post ID, URL, status | +| Taxonomy creation report | `POST /v1/integration/integrations/{id}/taxonomy-report/` | Created taxonomy slugs + term IDs | + +### Inbound (SaaS → Plugin) + +| Event | Plugin Endpoint | Payload | +|-------|----------------|---------| +| Push content | `POST /wp-json/igny8/v1/sync/push` | Content HTML, meta, images, content_type | +| Push blueprint | `POST /wp-json/igny8/v1/sag/sync-blueprint` | Full SAG blueprint JSON | +| Create taxonomies | `POST /wp-json/igny8/v1/sag/create-taxonomies` | Taxonomy definitions + terms | +| Push term content | `POST /wp-json/igny8/v1/terms/{id}/content` | HTML content + meta for term | +| Push schemas | `POST /wp-json/igny8/v1/schema/bulk-update` | Schema JSON-LD per post | +| Push GSC statuses | `POST /wp-json/igny8/v1/gsc/status-sync` | URL index statuses | +| Push events | `POST /wp-json/igny8/v1/event` | task_ready, link_suggestion, etc. | + +### Sync Architecture + +``` +IGNY8 SaaS (api.igny8.com) + │ + │ Outbound webhooks (push content, blueprints, schemas, statuses) + ▼ +WordPress Plugin (site.com/wp-json/igny8/v1/*) + │ + │ Periodic sync (structure, data, confirmations) + ▼ +IGNY8 SaaS (api.igny8.com/v1/integration/*) +``` + +All communication is HTTPS. Plugin-side: async via WP Cron (never blocks page load). SaaS-side: async via Celery tasks (never blocks API response). + +--- + +## Reference Documents + +| Document | Purpose | +|----------|---------| +| **IGNY8-Plugin-Build-Plan.md** | Complete plugin plan — modules, features, phases, file structure | +| **Theme-Build-Plan.md** | Complete theme plan — CPTs, taxonomies, templates, patterns, toolkit | +| **IGNY8-Current-State.md** | Current IGNY8 SaaS state — integration layer, plugin distribution, sync architecture | +| **Doc A — SAG Architecture Dev Guide** | SAG models, blueprints — what the plugin receives in connected mode | +| **Doc B — Platform Modules Dev Guide** | SaaS modules — what generates content/schemas/links pushed to plugin | + +--- + +*End of Doc C — WordPress Ecosystem Development Guide* diff --git a/docs/plans/final-dev-guides-of-futute-implementation/DocD-Business-Services-Dev-Guide.md b/docs/plans/final-dev-guides-of-futute-implementation/DocD-Business-Services-Dev-Guide.md new file mode 100644 index 00000000..578a7539 --- /dev/null +++ b/docs/plans/final-dev-guides-of-futute-implementation/DocD-Business-Services-Dev-Guide.md @@ -0,0 +1,813 @@ +# Doc D — Business & Services: Development Guide for Claude Code + +**Version:** 1.0 +**Date:** March 2026 +**For:** Claude Code (Opus 4.6) in VSCode on IGNY8 repo +**Purpose:** Implementation guide for the business/revenue layer — Managed Services Add-On, Backlink Service Tiers, client onboarding workflows, white-label reporting, and billing integration for services +**Scope:** Managed Add-On tiers (Lite $100, Pro $399/site/month), Backlink service packaging (self-service + managed), Alorig client portfolio servicing, billing models and margin tracking +**Rule:** Core IGNY8 SaaS subscription plans (Free/Starter/Growth/Scale) are unchanged. Managed services are add-ons purchased per site, layered on top of existing plans. All service delivery uses existing IGNY8 platform features — no separate tool stack. +**Dependency:** Doc A (SAG Architecture) provides blueprints and campaign generation. Doc B (Platform Modules) provides content pipeline, GSC, Socializer. Doc C (WordPress Ecosystem) provides plugin infrastructure for delivery. + +--- + +## Table of Contents + +1. [Business Context — Current Revenue Model](#1-business-context) +2. [Managed Services Add-On — Product Definition](#2-managed-addon) +3. [Backlink Services — Product Definition](#3-backlink-services) +4. [Implementation: Backend Models & Billing](#4-backend-models) +5. [Implementation: Frontend — Service Management UI](#5-frontend-ui) +6. [Implementation: Service Delivery Workflow](#6-delivery-workflow) +7. [Implementation: Client Onboarding Automation](#7-onboarding) +8. [Implementation: Reporting & White-Label](#8-reporting) +9. [Implementation: Alorig Client Portfolio Servicing](#9-alorig-portfolio) +10. [API Endpoints](#10-api-endpoints) +11. [Celery Tasks](#11-celery-tasks) +12. [Feature Flags](#12-feature-flags) +13. [Margin Tracking & Business Intelligence](#13-margin-tracking) + +--- + +## 1. Business Context — Current Revenue Model {#1-business-context} + +### 1.1 Existing Subscription Plans + +| Plan | Price | Sites | Users | Credits/Month | +|------|-------|-------|-------|---------------| +| Free | $0 | 1 | 1 | 100 | +| Starter | $49 | 3 | 3 | 1,000 | +| Growth | $149 | 10 | 10 | 5,000 | +| Scale | $349 | Unlimited | Unlimited | 25,000 | + +**Payment:** Stripe and PayPal integrated (pending production credentials). Manual payment methods available. + +**Billing models:** `modules/billing/` (API layer), `business/billing/` (services). `CreditService` manages all credit operations. `Plan` model in `auth/models.py`. + +### 1.2 Revenue Expansion Opportunities + +The current model is pure SaaS subscription + credits. Two service layers add high-margin revenue without changing the core platform: + +1. **Managed Services Add-On** — Alorig team operates the IGNY8 platform on behalf of clients. Client pays subscription + managed fee. Alorig does the work. +2. **Backlink Services** — Link building packages using FatGrid/PR distribution. Self-service (client buys intelligence, executes themselves) or managed (Alorig team executes). + +Both use the existing platform. No separate tools needed. The "service" is human expertise + platform operation — not new software features. + +### 1.3 Existing Infrastructure to Leverage + +| What Exists | How Services Use It | +|-------------|-------------------| +| SAG Site Builder (Doc A Phase 4) | Managed: Alorig runs wizard for client. Self-service: client runs it themselves. | +| Content Pipeline (Doc B Modules 1-2) | Managed: Alorig configures and runs automation. Client gets published content. | +| Backlink Campaign Generator (Doc A Phase 10) | Both: Platform generates campaign plan. Managed: Alorig executes. Self-service: client executes. | +| GSC Integration (Doc B Module 4) | Managed: Alorig monitors indexing, submits URLs. Reports to client. | +| Socializer (Doc B Module 6) | Managed Pro: Alorig configures social posting for client. | +| Rich Schema (Doc B Module 5) | Managed: Alorig runs retroactive enhancement on client sites. | +| WordPress Plugin (Doc C) | Both: Plugin installed on client site. Managed: Alorig configures connected mode. | + +--- + +## 2. Managed Services Add-On — Product Definition {#2-managed-addon} + +### 2.1 Tiers + +| Tier | Price | What Client Gets | What Alorig Does | +|------|-------|------------------|-----------------| +| **Managed Lite** | $100/site/month | 10 articles/month, basic SEO setup, monthly report | Run SAG wizard, configure automation for 10 articles, publish to WordPress, basic optimization, email monthly report | +| **Managed Pro** | $399/site/month | 30 articles/month, full SAG architecture, backlink campaign management, social posting, weekly report, dedicated account manager | Full SAG build, configure all automation stages, manage backlink campaign execution, configure socializer, run retroactive schema enhancement, weekly report with KPIs | + +### 2.2 What's Included in Each Tier + +**Managed Lite ($100/site/month):** +- Initial SAG blueprint generation (one-time, first month) +- 10 articles/month through the content pipeline +- Basic WordPress taxonomy setup from blueprint +- Content published to WordPress (auto or scheduled) +- Monthly PDF report: articles published, keywords tracked, basic traffic metrics +- Email support (48hr response) + +**Managed Pro ($399/site/month):** +- Everything in Lite, plus: +- Full SAG architecture with detailed mode (not quick mode) +- 30 articles/month (hub pages + supporting content per blueprint execution priority) +- Taxonomy term content generation (term landing pages) +- Backlink campaign management: plan generation, link sourcing via FatGrid, quality verification, anchor text management +- Monthly backlink budget: separate from service fee, passed through at cost + 20% markup +- Social media content generation + scheduling across configured platforms +- Retroactive schema enhancement on existing site pages +- GSC monitoring: auto-indexing, re-inspection, issue alerts +- Weekly PDF report: content published, backlinks built, indexing status, keyword rankings, traffic, DR progress +- Dedicated Slack channel or email thread (24hr response) + +### 2.3 Client Requirements + +The client must provide or enable: +- WordPress admin access (or install IGNY8 plugin themselves) +- Domain/hosting (Alorig does not host client sites) +- Business data for SAG wizard (products/services, brands, locations, problems solved — per Doc A Section 9.3) +- Approval on SAG blueprint before execution (Alorig presents, client approves) +- Social media account access (for Managed Pro social posting) +- Backlink budget approval (for Managed Pro, separate from service fee) + +### 2.4 Margin Analysis + +| Component | Managed Lite | Managed Pro | +|-----------|-------------|-------------| +| Service fee | $100/month | $399/month | +| IGNY8 platform cost (credits) | ~$15-25/month (10 articles, basic images) | ~$50-80/month (30 articles, quality images, social, schema) | +| Human time (Alorig team) | ~2-3 hrs/month | ~8-12 hrs/month | +| Effective hourly rate | $25-40/hr | $25-35/hr | +| Gross margin | ~75% | ~70-80% (excluding backlink pass-through) | + +Backlink costs are pass-through with 20% markup — not included in the service fee. + +--- + +## 3. Backlink Services — Product Definition {#3-backlink-services} + +### 3.1 Two Modes + +**Self-Service Mode:** +Client uses IGNY8's backlink campaign module (Doc A Phase 10) to generate campaign plans, browse FatGrid publishers, and track links. IGNY8 provides the intelligence. Client executes link building themselves. + +No additional subscription needed — included with Scale plan or as a credit-based add-on. + +**Managed Mode:** +Client submits campaign to Alorig team. Alorig sources links, manages quality, tracks progress, generates white-label reports. Client pays per-link or monthly retainer. + +### 3.2 Service Tiers (Managed Mode) + +| Tier | Service | IGNY8/Alorig Cost | Client Price | Margin | +|------|---------|-------------------|-------------|--------| +| **Basic Guest Post** | DR 30-50 via FatGrid | $30-80 | $150-300 | 3-5x | +| **Standard Guest Post** | DR 50-70 via FatGrid | $100-300 | $400-800 | 2-3x | +| **Premium Guest Post** | DR 70+ via FatGrid | $500-2,000 | $1,500-5,000 | 2-3x | +| **PR Basic** | 300+ outlets via EIN Presswire | $99-499 | $500-1,500 | 3-5x | +| **PR Premium** | Yahoo/Bloomberg/Fox via PRNews.io/Linking News | $500-5,000 | $2,000-15,000 | 3-4x | + +### 3.3 Monthly Packages (Managed Mode) + +| Package | Links/Month | DR Range | Monthly Cost | Typical Site Size | +|---------|------------|----------|-------------|------------------| +| **Starter** | 5-8 links | DR 30-50 | $800-1,500 | Small sites, PK market | +| **Growth** | 10-15 links | DR 30-70 mix | $2,000-4,000 | Medium sites, UK/CA market | +| **Authority** | 15-25 links | DR 40-70+ mix + PR | $4,000-8,000 | Large sites, USA market | +| **Enterprise** | Custom | Custom | Custom | Multi-site, agency clients | + +### 3.4 Niche Surcharges + +| Niche | Multiplier | Reason | +|-------|-----------|--------| +| Crypto/Casino | 2-3x | Limited publishers, high competition | +| Finance/Insurance | 1.5-2x | YMYL, stricter publisher requirements | +| Health/Medical | 1.5-2x | YMYL, content quality requirements | +| Tech/SaaS | 1.2-1.5x | Moderate competition | +| General | 1x (baseline) | Standard pricing | + +--- + +## 4. Implementation: Backend Models & Billing {#4-backend-models} + +### 4.1 New Models + +Add to existing billing module or create new services module: + +```python +# modules/billing/models.py or new modules/services/models.py + +class ManagedServiceSubscription(AccountBaseModel): + """Managed service add-on subscription per site.""" + id = models.UUIDField(primary_key=True, default=uuid4) + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE, related_name='managed_subscriptions') + tier = models.CharField(max_length=20, choices=[ + ('lite', 'Managed Lite'), + ('pro', 'Managed Pro'), + ]) + status = models.CharField(max_length=20, choices=[ + ('pending', 'Pending Setup'), + ('active', 'Active'), + ('paused', 'Paused'), + ('cancelled', 'Cancelled'), + ], default='pending') + monthly_price = models.DecimalField(max_digits=8, decimal_places=2) + articles_per_month = models.IntegerField() + + # Assigned team member + account_manager = models.ForeignKey('auth.User', null=True, blank=True, on_delete=models.SET_NULL, + related_name='managed_clients') + + # Tracking + current_month_articles_published = models.IntegerField(default=0) + current_month_start = models.DateField(null=True, blank=True) + + # Service config + service_config = models.JSONField(default=dict, help_text='Per-site service configuration: automation settings, social platforms, backlink budget, report schedule') + + started_at = models.DateTimeField(null=True, blank=True) + cancelled_at = models.DateTimeField(null=True, blank=True) + next_billing_date = models.DateField(null=True, blank=True) + +class BacklinkServiceOrder(AccountBaseModel): + """Individual backlink service order or monthly retainer.""" + id = models.UUIDField(primary_key=True, default=uuid4) + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE) + campaign = models.ForeignKey('sag.SAGCampaign', null=True, blank=True, on_delete=models.SET_NULL) + + order_type = models.CharField(max_length=20, choices=[ + ('one_time', 'One-Time Order'), + ('monthly', 'Monthly Retainer'), + ]) + package = models.CharField(max_length=30, choices=[ + ('starter', 'Starter (5-8 links)'), + ('growth', 'Growth (10-15 links)'), + ('authority', 'Authority (15-25 links)'), + ('enterprise', 'Enterprise (custom)'), + ('custom', 'Custom Order'), + ], blank=True) + + # Financial + client_price = models.DecimalField(max_digits=10, decimal_places=2) + actual_cost = models.DecimalField(max_digits=10, decimal_places=2, default=0) + margin = models.DecimalField(max_digits=10, decimal_places=2, default=0) + niche_surcharge = models.FloatField(default=1.0, help_text='Multiplier: 1.0 = baseline') + + # Delivery + links_ordered = models.IntegerField(default=0) + links_delivered = models.IntegerField(default=0) + links_live = models.IntegerField(default=0) + + status = models.CharField(max_length=20, choices=[ + ('draft', 'Draft'), + ('approved', 'Approved'), + ('in_progress', 'In Progress'), + ('delivered', 'Delivered'), + ('completed', 'Completed'), + ], default='draft') + + # Tracking + ordered_at = models.DateTimeField(null=True, blank=True) + delivered_at = models.DateTimeField(null=True, blank=True) + notes = models.TextField(blank=True) + +class ServiceReport(AccountBaseModel): + """Generated report for a managed service client.""" + id = models.UUIDField(primary_key=True, default=uuid4) + site = models.ForeignKey('auth.Site', on_delete=models.CASCADE) + managed_subscription = models.ForeignKey(ManagedServiceSubscription, null=True, blank=True, on_delete=models.SET_NULL) + + report_type = models.CharField(max_length=20, choices=[ + ('weekly', 'Weekly Report'), + ('monthly', 'Monthly Report'), + ('quarterly', 'Quarterly Review'), + ]) + period_start = models.DateField() + period_end = models.DateField() + + # Report data + report_data = models.JSONField(default=dict, help_text='All metrics for this period') + report_pdf_url = models.URLField(blank=True, help_text='Generated PDF stored in S3') + + # White-label + is_white_label = models.BooleanField(default=False) + brand_name = models.CharField(max_length=200, blank=True, help_text='Client-facing brand name (if white-label)') + brand_logo_url = models.URLField(blank=True) + + generated_at = models.DateTimeField(auto_now_add=True) + sent_at = models.DateTimeField(null=True, blank=True) +``` + +### 4.2 Billing Integration + +Managed services integrate with the existing billing system: + +```python +# business/billing/managed_billing_service.py # NEW + +class ManagedBillingService: + def create_managed_subscription(self, site, tier, payment_method): + """Create managed service subscription + first invoice.""" + # 1. Create ManagedServiceSubscription record + # 2. Create Stripe/PayPal subscription or manual invoice + # 3. Deduct from account credit balance OR charge directly + # 4. Set next_billing_date + pass + + def process_monthly_billing(self): + """Celery task: process all active managed subscriptions monthly.""" + # For each active subscription: + # 1. Generate invoice + # 2. Charge payment method + # 3. Reset current_month_articles_published + # 4. Update current_month_start + pass + + def process_backlink_order(self, order): + """Process payment for a backlink service order.""" + # 1. Calculate total: client_price × niche_surcharge + # 2. Charge payment method + # 3. Update order status to 'approved' + pass + + def calculate_margin(self, order): + """Calculate and store margin on a completed backlink order.""" + order.margin = order.client_price - order.actual_cost + order.save() +``` + +### 4.3 Service Configuration Storage + +The `service_config` JSON field on ManagedServiceSubscription stores per-client settings: + +```json +{ + "automation": { + "schedule": "weekly", + "articles_per_run": 3, + "content_types": ["post", "cluster_hub", "taxonomy_landing"], + "auto_publish": false, + "review_required": true + }, + "backlinks": { + "monthly_budget": 2000, + "target_country": "US", + "package": "growth", + "auto_approve_under": 200 + }, + "social": { + "platforms": ["linkedin", "twitter"], + "auto_post_on_publish": true, + "posting_schedule": "best_time" + }, + "reporting": { + "frequency": "weekly", + "format": "pdf", + "white_label": false, + "recipients": ["client@example.com"], + "include_backlinks": true, + "include_rankings": true, + "include_traffic": true + } +} +``` + +--- + +## 5. Implementation: Frontend — Service Management UI {#5-frontend-ui} + +### 5.1 Admin-Only Service Dashboard + +This is an internal Alorig team interface, not client-facing. + +``` +frontend/src/pages/ +└── Services/ # NEW page (admin only) + ├── ServicesDashboard.tsx # Overview: all managed clients, revenue summary + │ ├── ClientList.tsx # All managed subscriptions with status + │ ├── RevenueSummary.tsx # MRR, active clients, margin totals + │ └── UpcomingActions.tsx # Tasks due: reports, renewals, content due + ├── ClientDetail.tsx # Single client management view + │ ├── ClientConfig.tsx # Service config editor (automation, social, backlinks) + │ ├── ContentTracker.tsx # Articles published this month vs target + │ ├── BacklinkTracker.tsx # Links ordered vs delivered vs live + │ ├── ReportHistory.tsx # Generated reports with resend option + │ └── BillingHistory.tsx # Invoices, payments, margin + ├── BacklinkOrders.tsx # All backlink orders across clients + │ ├── OrderList.tsx # Filterable by client, status, package + │ └── OrderDetail.tsx # Individual order with link-by-link tracking + └── ReportGenerator.tsx # Generate reports for any client/period +``` + +**Sidebar addition (admin only):** +``` +ADMIN + ├── Sector Templates + └── Managed Services (NEW — admin only) +``` + +### 5.2 Client-Facing View (Optional) + +Managed clients who also have IGNY8 app access see a simplified view: + +``` +frontend/src/pages/ +└── ManagedService/ # NEW page (for managed clients) + ├── ServiceOverview.tsx # What's included, current month progress + ├── ReportViewer.tsx # View past reports + └── ApprovalQueue.tsx # Approve blueprint, content (if review_required) +``` + +This page appears in the client's sidebar only if they have an active `ManagedServiceSubscription`: +``` +ACCOUNT + ├── Account Settings + ├── Plans & Billing + ├── Managed Service (NEW — if managed subscription active) + ├── Usage + └── AI Models +``` + +--- + +## 6. Implementation: Service Delivery Workflow {#6-delivery-workflow} + +### 6.1 Managed Lite — Monthly Workflow + +``` +Month Start + │ + ├── Check: blueprint exists? If not → run SAG wizard for client (first month) + │ + ├── Run automation pipeline (10 articles): + │ 1. Blueprint check → load unfulfilled content needs + │ 2. Generate ideas from blueprint (execution priority order) + │ 3. Create tasks (content_type based on blueprint) + │ 4. Generate content (type-specific prompts) + │ 5. Generate images + │ 6. → Review queue + │ + ├── Alorig team reviews content (manual quality check) + │ - Approve or edit in Writer → Review tab + │ - Publish approved content to WordPress + │ + ├── Update ManagedServiceSubscription.current_month_articles_published + │ + └── Month End: + ├── Generate monthly report (ServiceReport) + ├── Send to client via email + └── Process next month billing +``` + +### 6.2 Managed Pro — Monthly Workflow + +``` +Month Start + │ + ├── Everything from Lite, PLUS: + │ + ├── Run automation for 30 articles (hub pages prioritized in early months) + │ + ├── Backlink campaign management: + │ 1. Load this month's plan from SAGCampaign + │ 2. Browse FatGrid for publishers matching plan criteria + │ 3. Place orders on FatGrid/PR platforms + │ 4. Track delivery: ordered → pending → live + │ 5. Quality check each delivered link + │ 6. Log in SAGBacklink records + │ 7. Run dead link check on previous links + │ + ├── Social media: + │ 1. Generate social posts for published content + │ 2. Schedule across configured platforms + │ 3. Monitor engagement metrics + │ + ├── Schema enhancement: + │ 1. Run retroactive schema scan on any new/updated pages + │ 2. Generate and push schemas to WordPress + │ + ├── GSC monitoring: + │ 1. Check indexing status of all published content + │ 2. Re-request indexing for pending items + │ 3. Flag issues to client if needed + │ + └── Week End (weekly report): + ├── Generate weekly report (ServiceReport) + ├── Include: articles published, backlinks built, indexing status, ranking changes + └── Send to client +``` + +### 6.3 Backlink Order Workflow (Managed Mode) + +``` +Client approves monthly backlink budget + │ + ├── Alorig loads this month's campaign plan from IGNY8 + │ - Target pages, DR ranges, anchor text mix, link count + │ + ├── Browse FatGrid publishers: + │ - Filter by: country, niche, DR range, budget + │ - Compare prices across marketplaces + │ - Select best-value publishers + │ + ├── Place orders: + │ - Guest post orders on FatGrid + │ - PR distribution on EIN Presswire / PRNews.io + │ - Create BacklinkServiceOrder record + │ + ├── Track delivery: + │ - Monitor publisher for content creation + │ - Verify link is live (HTTP check) + │ - Quality check: DR, traffic, niche relevance, outbound links + │ - Log each link as SAGBacklink + │ + ├── Quality scoring: + │ - Auto-score where possible (Ahrefs/FatGrid data) + │ - Manual checks: content quality, relevance, link placement + │ - Flag issues if quality below threshold + │ + └── Update campaign: + - BacklinkServiceOrder.links_delivered++ + - SAGCampaign KPI update + - Calculate margin: client_price - actual_cost +``` + +--- + +## 7. Implementation: Client Onboarding Automation {#7-onboarding} + +### 7.1 Managed Client Onboarding Flow + +When a managed service subscription is created: + +```python +# business/services/onboarding_service.py # NEW + +class ManagedOnboardingService: + def onboard_client(self, subscription): + """Automated onboarding for new managed client.""" + site = subscription.site + + # Step 1: Ensure IGNY8 plugin is installed and connected + # Check site.wp_api_key exists → if not, send installation guide email + + # Step 2: Run SAG Site Builder if no blueprint exists + if not site.sag_blueprint_id: + # Queue Celery task to generate blueprint + # Notification to account manager: "Blueprint ready for review" + pass + + # Step 3: Configure automation based on service_config + # Set AutomationConfig schedule, stages, content types + + # Step 4: Send welcome email to client + # Include: what to expect, how to approve content, contact info + + # Step 5: Create first month tasks in internal queue + # Notification to account manager: "New client onboarded, first content due" + + # Step 6: Update subscription status: pending → active +``` + +### 7.2 Client Intake Form + +For collecting business data (feeds into SAG wizard): + +``` +frontend/src/pages/Services/ +└── components/ + └── ClientIntakeForm.tsx # NEW — admin fills this during client onboarding +``` + +Collects per Doc A Section 9.3: +- Site URL, industry, sectors +- Products/services list +- Problems solved +- Brands (if e-commerce) +- Locations (if service-based) +- Competitors +- Target countries (for backlink campaigns) +- Social media accounts +- Current SEO status (any existing plugins, backlink profile) + +This data feeds directly into the SAG wizard's business data inputs. + +--- + +## 8. Implementation: Reporting & White-Label {#8-reporting} + +### 8.1 Report Generation Service + +```python +# business/services/report_service.py # NEW + +class ReportService: + def generate_report(self, site, period_start, period_end, report_type, white_label=False): + """Generate a service report for a managed client.""" + report_data = { + 'content': self._get_content_metrics(site, period_start, period_end), + 'backlinks': self._get_backlink_metrics(site, period_start, period_end), + 'indexing': self._get_indexing_metrics(site, period_start, period_end), + 'rankings': self._get_ranking_metrics(site, period_start, period_end), + 'traffic': self._get_traffic_metrics(site, period_start, period_end), + 'social': self._get_social_metrics(site, period_start, period_end), + 'health': self._get_sag_health(site), + } + + # Generate PDF + pdf_url = self._render_pdf(report_data, white_label, site) + + # Create ServiceReport record + report = ServiceReport.objects.create( + site=site, report_type=report_type, + period_start=period_start, period_end=period_end, + report_data=report_data, report_pdf_url=pdf_url, + is_white_label=white_label, + ) + return report + + def _get_content_metrics(self, site, start, end): + """Articles published, content types breakdown, word count total.""" + pass + + def _get_backlink_metrics(self, site, start, end): + """Links built, DR distribution, cost, quality scores.""" + pass + + def _get_indexing_metrics(self, site, start, end): + """Pages indexed, pending, errors (from GSC module).""" + pass + + def _get_ranking_metrics(self, site, start, end): + """Keywords in top 10/20/50, position changes (from GSC module).""" + pass + + def _get_traffic_metrics(self, site, start, end): + """Organic traffic, impressions, CTR (from GSC module).""" + pass + + def _get_social_metrics(self, site, start, end): + """Posts published, engagement, clicks (from Socializer module).""" + pass + + def _get_sag_health(self, site): + """SAG health score, cluster completion (from SAG module).""" + pass +``` + +### 8.2 PDF Report Template + +Reports generated as PDF using a template system. Stored in S3/media storage. + +**Report sections (configurable per client):** +1. Executive Summary — key wins this period +2. Content Performance — articles published, type breakdown +3. Indexing Status — indexed/pending/error counts with trend +4. Keyword Rankings — top movers, new entries, lost positions +5. Organic Traffic — clicks, impressions, CTR with month-over-month +6. Backlink Campaign (if active) — links built, DR distribution, budget spent, quality +7. Social Media (if active) — posts, engagement, top performers +8. SAG Health — overall score, cluster completion, recommendations +9. Next Month Plan — what's coming, what client needs to approve + +### 8.3 White-Label Support + +For agency clients reselling IGNY8 services: +- `ServiceReport.brand_name` replaces "IGNY8" / "Alorig" throughout PDF +- `ServiceReport.brand_logo_url` replaces logo in PDF header +- Report footer shows agency contact info, not Alorig +- White-label reports generated via Linking News API for backlink reporting + +--- + +## 9. Implementation: Alorig Client Portfolio Servicing {#9-alorig-portfolio} + +### 9.1 Current Alorig Clients (from Rich Schema doc) + +| Client | Type | Site | Priority Services | +|--------|------|------|------------------| +| Banner Printing (UK) | Service/eCommerce | ~50 pages | FAQ Schema, Breadcrumbs, Local Business Schema, Review markup | +| Aterna Advisors (CA) | Finance content | ~135 pages | Article + Author Schema (YMYL), FAQ, TL;DR, Definition blocks | +| Seva Mattress | WooCommerce | Product catalog | Product Schema, AggregateRating, FAQ, Pros & Cons | +| VAINO | WooCommerce + brand | Product + brand pages | Product Schema, Breadcrumbs, FAQ, Review markup | +| African Fair Trade Society | Nonprofit content | Content + service pages | Article Schema, FAQ, Organization Schema, Breadcrumbs | +| Halal VPN | Blog + product | Blog + product pages | Article, HowTo, FAQ, Comparison Tables, Pros & Cons | + +### 9.2 Per-Client Service Plan + +Each Alorig client can be onboarded as a Managed Service subscriber: + +``` +For each client: + 1. Create ManagedServiceSubscription (Lite or Pro based on scope) + 2. Run client intake → collect business data + 3. Run SAG Site Builder → generate blueprint + 4. Install/update IGNY8 plugin on client site + 5. Run retroactive schema enhancement (Rich Schema module) + 6. Configure content pipeline based on gaps + 7. Set up reporting schedule + 8. (Pro clients) Generate backlink campaign, begin execution +``` + +### 9.3 Internal Service Tracking + +The admin Services Dashboard provides at-a-glance view of all Alorig clients: +- Client name, site, tier, status +- This month: articles target vs published, backlinks target vs delivered +- Overdue items: reports not sent, content not published, links behind schedule +- Revenue: MRR from managed services, backlink revenue, total margin + +--- + +## 10. API Endpoints {#10-api-endpoints} + +### Managed Services + +``` +GET /api/v1/services/subscriptions/ # List managed subscriptions (admin) +POST /api/v1/services/subscriptions/ # Create subscription +GET /api/v1/services/subscriptions/{id}/ # Subscription detail +PATCH /api/v1/services/subscriptions/{id}/ # Update config, status +POST /api/v1/services/subscriptions/{id}/onboard/ # Trigger onboarding workflow +POST /api/v1/services/subscriptions/{id}/pause/ # Pause subscription +POST /api/v1/services/subscriptions/{id}/cancel/ # Cancel subscription +``` + +### Backlink Orders + +``` +GET /api/v1/services/backlink-orders/ # List orders (admin) +POST /api/v1/services/backlink-orders/ # Create order +GET /api/v1/services/backlink-orders/{id}/ # Order detail +PATCH /api/v1/services/backlink-orders/{id}/ # Update status, delivery +GET /api/v1/services/backlink-orders/{id}/links/ # Links in this order +``` + +### Reports + +``` +GET /api/v1/services/reports/ # List reports (admin + client) +POST /api/v1/services/reports/generate/ # Generate report +GET /api/v1/services/reports/{id}/ # Report detail + PDF URL +POST /api/v1/services/reports/{id}/send/ # Email report to client +``` + +### Dashboard (Admin) + +``` +GET /api/v1/services/dashboard/ # Revenue summary, client overview +GET /api/v1/services/dashboard/overdue/ # Overdue tasks across clients +GET /api/v1/services/dashboard/margin/ # Margin tracking summary +``` + +--- + +## 11. Celery Tasks {#11-celery-tasks} + +| Task | Schedule | Purpose | +|------|----------|---------| +| `process_managed_billing` | Monthly (1st of month) | Invoice all active managed subscriptions | +| `generate_weekly_reports` | Weekly (Monday 6am) | Generate reports for all Pro clients | +| `generate_monthly_reports` | Monthly (1st of month) | Generate reports for all Lite + Pro clients | +| `send_pending_reports` | Daily | Email any generated but unsent reports | +| `check_overdue_deliverables` | Daily | Flag any managed clients behind on content/links | +| `reset_monthly_counters` | Monthly (1st of month) | Reset current_month_articles_published | +| `check_backlink_delivery` | Daily | Check FatGrid/publisher status on open orders | + +--- + +## 12. Feature Flags {#12-feature-flags} + +| Flag | Controls | Default | +|------|---------|---------| +| `managed_services_enabled` | Services admin page, subscription management, onboarding | `False` | +| `backlink_orders_enabled` | Backlink order management (independent of campaign module) | `False` | +| `white_label_reports` | White-label branding on reports | `False` | + +--- + +## 13. Margin Tracking & Business Intelligence {#13-margin-tracking} + +### 13.1 What to Track + +| Metric | Source | Aggregation | +|--------|--------|-------------| +| Managed Services MRR | Sum of active ManagedServiceSubscription.monthly_price | Monthly | +| Backlink Revenue | Sum of BacklinkServiceOrder.client_price (completed orders) | Monthly | +| Backlink Cost | Sum of BacklinkServiceOrder.actual_cost | Monthly | +| Backlink Margin | Revenue - Cost per order, aggregated | Monthly | +| Blended Margin % | (Total Revenue - Total Cost) / Total Revenue | Monthly | +| Cost Per Article | Platform credits used / articles published per client | Monthly | +| Team Hours (manual tracking) | Time spent per client | Monthly | +| Effective Hourly Rate | (Revenue - Platform Costs) / Hours | Monthly | +| Client Retention | Active subscriptions / Total ever created | Lifetime | +| Average Revenue Per Client | Total revenue / Active clients | Monthly | + +### 13.2 Admin Dashboard Metrics + +The Services Dashboard (admin-only) shows: +- Total MRR from managed services +- Total backlink revenue (monthly) +- Blended margin percentage +- Client count by tier (Lite vs Pro) +- Top 5 clients by revenue +- Clients behind on deliverables +- Month-over-month growth + +### 13.3 Future: Automated Margin Calculation + +When FatGrid API integration is complete (Doc A Phase 10), backlink order costs can be auto-populated from actual FatGrid transaction data, making margin tracking fully automated instead of manually entered. + +--- + +## Reference Documents + +| Document | Purpose | +|----------|---------| +| **IGNY8-Current-State.md** | Billing system, credit costs, subscription plans | +| **SAG-Doc4-External-Backlink-Campaign-PLAN.md** | Campaign generation, FatGrid tiers, service pricing | +| **IGNY8-Rich-Schema-SERP-Enhancement-Module.docx** | Client portfolio with retroactive enhancement opportunities | +| **Doc A — SAG Architecture Dev Guide** | Campaign module (Phase 10), SAG Site Builder (Phase 4) | +| **Doc B — Platform Modules Dev Guide** | GSC, Socializer, Rich Schema — features delivered to managed clients | +| **Doc C — WordPress Ecosystem Dev Guide** | Plugin installation and configuration for managed sites | + +--- + +*End of Doc D — Business & Services Development Guide*