# SiteBuilder Removal - Complete Migration Guide **Date:** December 1, 2025 **Status:** Code changes completed, database migration pending --- ## Summary All SiteBuilder and Blueprint functionality has been removed from the IGNY8 system. The taxonomy system has been simplified to use the direct `Content.taxonomy_terms` many-to-many relationship with the `ContentTaxonomy` model. --- ## What Was Removed ### Backend Models (Django) - ✅ `SiteBlueprint` - Site structure blueprints - ✅ `PageBlueprint` - Individual page definitions - ✅ `SiteBlueprintCluster` - Cluster to blueprint mappings - ✅ `SiteBlueprintTaxonomy` - Blueprint taxonomy definitions - ✅ `BusinessType`, `AudienceProfile`, `BrandPersonality`, `HeroImageryDirection` - SiteBuilder metadata options - ✅ `ContentTaxonomyMap` - Replaced by `Content.taxonomy_terms` M2M field ### Backend Modules - ✅ Removed entire `igny8_core.modules.site_builder` module - ✅ Removed from `INSTALLED_APPS` in settings.py - ✅ Removed `/api/v1/site-builder/` URL patterns - ✅ Cleaned up `site_building/models.py`, `site_building/admin.py` ### Backend Services & Views - ✅ Updated `PublisherService` - removed `publish_to_sites()` method - ✅ Updated `PublisherViewSet` - removed blueprint publishing actions - ✅ Updated `DeploymentRecordViewSet` - removed blueprint references - ✅ Updated `PublishingRecord` model - removed `site_blueprint` field - ✅ Updated `DeploymentRecord` model - removed `site_blueprint` field - ✅ Fixed `metadata_mapping_service.py` - removed ContentTaxonomyMap - ✅ Fixed `candidate_engine.py` - uses `Content.taxonomy_terms` now - ✅ Fixed `sites_renderer_adapter.py` - uses M2M taxonomy relationship - ✅ Fixed `planner/serializers.py` - removed SiteBlueprintTaxonomy import ### Frontend - ✅ Removed `frontend/src/modules/siteBuilder/` directory - ✅ Removed `frontend/src/types/siteBuilder.ts` - ✅ Removed `frontend/src/services/siteBuilder.api.ts` - ✅ Removed SiteBlueprint API functions from `services/api.ts` - ✅ Removed SiteBuilder routes from navigation --- ## Current Taxonomy System ### Simplified Architecture **Before (Complex - SiteBuilder era):** ``` Content → ContentTaxonomyMap → SiteBlueprintTaxonomy → Clusters (through table) (blueprint planning) ``` **After (Simplified - Current):** ``` Content ←→ ContentTaxonomy (many-to-many direct relationship) ↓ Cluster (foreign key) ``` ### ContentTaxonomy Model **Location:** `backend/igny8_core/business/content/models.py` **Fields:** - `name` - Term name (e.g., "Outdoor Living Design") - `slug` - URL-safe version - `taxonomy_type` - Choices: `category`, `tag` - `external_id` - WordPress term_id for sync - `external_taxonomy` - WordPress taxonomy slug (category, post_tag) - `description` - Term description - `account`, `site`, `sector` - Multi-tenancy fields **Relationship:** - `Content.taxonomy_terms` - ManyToManyField to ContentTaxonomy - Categories/tags are AI-generated and linked directly to Content --- ## How Content Taxonomy Works Now ### Publishing Flow (IGNY8 → WordPress) ```python # In wordpress_publishing.py task # STEP 4: Get categories from Content.taxonomy_terms categories = [ term.name for term in content.taxonomy_terms.filter(taxonomy_type='category') ] # Fallback to cluster if no taxonomy_terms if not categories and content.cluster: categories.append(content.cluster.name) # STEP 5: Get tags from taxonomy_terms + keywords tags = [ term.name for term in content.taxonomy_terms.filter(taxonomy_type='tag') ] # Add keywords as tags if content.primary_keyword not in tags: tags.append(content.primary_keyword) for keyword in content.secondary_keywords: if keyword not in tags: tags.append(keyword) ``` ### Data Flow ``` Keywords → Clusters → Ideas → Tasks → Content ├── taxonomy_terms (M2M) │ ├── Categories │ └── Tags ├── cluster (FK) ├── primary_keyword └── secondary_keywords ↓ WordPress Publish ├── Categories (from taxonomy_terms + cluster) └── Tags (from taxonomy_terms + keywords) ``` --- ## Django Admin **ContentTaxonomy is registered** in `backend/igny8_core/modules/writer/admin.py`: - View at: `/admin/writer/contenttaxonomy/` - Shows: name, taxonomy_type, slug, external_id, external_taxonomy, site, sector - Searchable by: name, slug, external_taxonomy - Filterable by: taxonomy_type, site, sector --- ## Database Migration (PENDING) **Migration File:** `backend/igny8_core/business/site_building/migrations/0002_remove_blueprint_models.py` **Status:** Created but not applied (requires external PostgreSQL access) ### Manual SQL Commands Run these SQL commands directly on your production PostgreSQL database: ```sql -- Drop foreign key constraints first ALTER TABLE igny8_publishing_records DROP CONSTRAINT IF EXISTS igny8_publishing_recor_site_blueprint_id_9f4e8c7a_fk_igny8_sit CASCADE; ALTER TABLE igny8_deployment_records DROP CONSTRAINT IF EXISTS igny8_deployment_recor_site_blueprint_id_3a2b7c1d_fk_igny8_sit CASCADE; -- Drop blueprint tables DROP TABLE IF EXISTS igny8_site_blueprint_taxonomies CASCADE; DROP TABLE IF EXISTS igny8_site_blueprint_clusters CASCADE; DROP TABLE IF EXISTS igny8_page_blueprints CASCADE; DROP TABLE IF EXISTS igny8_site_blueprints CASCADE; -- Drop SiteBuilder metadata tables DROP TABLE IF EXISTS igny8_site_builder_business_types CASCADE; DROP TABLE IF EXISTS igny8_site_builder_audience_profiles CASCADE; DROP TABLE IF EXISTS igny8_site_builder_brand_personalities CASCADE; DROP TABLE IF EXISTS igny8_site_builder_hero_imagery CASCADE; -- Drop site_blueprint_id columns ALTER TABLE igny8_publishing_records DROP COLUMN IF EXISTS site_blueprint_id CASCADE; ALTER TABLE igny8_deployment_records DROP COLUMN IF EXISTS site_blueprint_id CASCADE; -- Drop indexes DROP INDEX IF EXISTS igny8_publishing_recor_site_blueprint_id_des_b7c4e5f8_idx; -- Mark migration as applied INSERT INTO django_migrations (app, name, applied) VALUES ('site_building', '0002_remove_blueprint_models', NOW()) ON CONFLICT DO NOTHING; ``` --- ## Files Modified ### Backend Python Files (24 files) 1. `backend/igny8_core/business/site_building/models.py` - All models removed 2. `backend/igny8_core/business/site_building/admin.py` - All admin classes removed 3. `backend/igny8_core/business/publishing/models.py` - Removed site_blueprint FK 4. `backend/igny8_core/business/publishing/services/publisher_service.py` - Removed publish_to_sites 5. `backend/igny8_core/business/publishing/services/adapters/sites_renderer_adapter.py` - Updated taxonomy usage 6. `backend/igny8_core/business/content/services/metadata_mapping_service.py` - Removed ContentTaxonomyMap 7. `backend/igny8_core/business/linking/services/candidate_engine.py` - Updated to M2M taxonomy 8. `backend/igny8_core/business/optimization/services/analyzer.py` - Updated taxonomy check 9. `backend/igny8_core/modules/publisher/views.py` - Removed blueprint actions 10. `backend/igny8_core/modules/planner/serializers.py` - Removed SiteBlueprintTaxonomy 11. `backend/igny8_core/tasks/wordpress_publishing.py` - Uses Content.taxonomy_terms 12. `backend/igny8_core/urls.py` - Removed site-builder URL 13. `backend/igny8_core/settings.py` - Removed site_builder from INSTALLED_APPS ### Frontend TypeScript Files (3 files) 1. `frontend/src/services/api.ts` - Removed SiteBlueprint API functions 2. Removed: `frontend/src/types/siteBuilder.ts` 3. Removed: `frontend/src/services/siteBuilder.api.ts` 4. Removed: `frontend/src/modules/siteBuilder/` directory ### Migrations 1. Created: `backend/igny8_core/business/site_building/migrations/0002_remove_blueprint_models.py` --- ## Testing Checklist ### Backend Health Check ```bash # Check if backend starts successfully docker compose -f docker-compose.app.yml logs igny8_backend | grep -i "error\|exception" # Should show no import errors ``` ### Taxonomy Workflow Test 1. **Check ContentTaxonomy in Admin** - Go to `/admin/writer/contenttaxonomy/` - Verify model is accessible - Check existing taxonomy terms 2. **Test Content Creation** ```bash # In Django shell from igny8_core.business.content.models import Content, ContentTaxonomy content = Content.objects.first() print(f"Taxonomy terms: {content.taxonomy_terms.count()}") print(f"Cluster: {content.cluster.name if content.cluster else 'None'}") ``` 3. **Test Publishing to WordPress** - Create/select content with taxonomy_terms - Publish to WordPress from Review page - Verify categories and tags appear in WordPress - Check logs: `tail -f backend/logs/publish-sync-logs/publish-sync.log` ### Expected Log Output ``` [2025-12-01 02:00:00] [INFO] [5-homeg8.com] STEP 4: Loading taxonomy terms... [2025-12-01 02:00:00] [INFO] [5-homeg8.com] Found 1 categories from taxonomy_terms [2025-12-01 02:00:00] [INFO] [5-homeg8.com] 📁 Category: 'Outdoor Living Design' [2025-12-01 02:00:00] [INFO] [5-homeg8.com] ✅ TOTAL categories: 1 [2025-12-01 02:00:00] [INFO] [5-homeg8.com] STEP 5: Loading tags... [2025-12-01 02:00:00] [INFO] [5-homeg8.com] 🏷️ Primary keyword: 'outdoor patio design' [2025-12-01 02:00:00] [INFO] [5-homeg8.com] 🏷️ Secondary keywords: ['outdoor living spaces', 'outdoor kitchen design'] [2025-12-01 02:00:00] [INFO] [5-homeg8.com] ✅ TOTAL tags: 3 ``` --- ## Remaining Legacy References These files contain SiteBlueprint references in **migrations only** (historical data, safe to ignore): - `backend/igny8_core/business/content/migrations/0002_stage1_refactor_task_content_taxonomy.py` - `backend/igny8_core/modules/writer/migrations/0001_initial.py` - `backend/igny8_core/modules/planner/migrations/0002_initial.py` - `backend/igny8_core/tasks/wordpress_publishing_backup.py` (backup file) - `backend/igny8_core/tasks/wordpress_publishing_new.py` (backup file) --- ## Benefits of Simplified System ### Before (Complex) - 5 models: SiteBlueprint, PageBlueprint, SiteBlueprintCluster, SiteBlueprintTaxonomy, ContentTaxonomyMap - 3-level indirection: Content → ContentTaxonomyMap → SiteBlueprintTaxonomy - Blueprint planning layer for site building - Difficult to understand taxonomy relationships ### After (Simple) - 1 model: ContentTaxonomy - Direct M2M: Content ↔ ContentTaxonomy - AI-generated categories/tags linked directly - Clear taxonomy-content relationship in Django Admin ### Performance Improvements - Fewer database queries (eliminated ContentTaxonomyMap joins) - Simpler ORM queries: `content.taxonomy_terms.filter(taxonomy_type='category')` - Easier debugging and maintenance --- ## Next Steps 1. **Apply Database Migration** - Run SQL commands on production PostgreSQL - Mark migration as applied in django_migrations table 2. **Test Publishing Workflow** - Publish content from Review page - Verify categories/tags in WordPress - Check sync logs for any errors 3. **Monitor Logs** - Backend: `/data/app/igny8/backend/logs/publish-sync-logs/` - WordPress: `/wp-content/plugins/igny8-ai-os/logs/publish-sync-logs/` 4. **Update Documentation** - Update SYSTEM-ARCHITECTURE doc to reflect simplified taxonomy - Remove SiteBuilder references from workflow docs --- ## Rollback Plan (If Needed) If issues arise, you can restore SiteBuilder functionality by: 1. Restore backup files: ```bash cd /data/app/igny8/backend/igny8_core/modules mv site_builder.backup site_builder ``` 2. Uncomment in settings.py: ```python 'igny8_core.modules.site_builder.apps.SiteBuilderConfig', ``` 3. Restore URL pattern in urls.py: ```python path('api/v1/site-builder/', include('igny8_core.modules.site_builder.urls')), ``` 4. Reverse database changes (restore from backup) --- ## Contact & Support If you encounter any issues during migration: - Check logs in `backend/logs/` and WordPress plugin `logs/` - Review Django admin for ContentTaxonomy model - Test publishing workflow step by step **Migration completed by:** GitHub Copilot **Date:** December 1, 2025 **Version:** IGNY8 v1.0 - SiteBuilder Removal