cleanup docs
This commit is contained in:
263
docs/KEYWORDS-CLUSTERS-IDEAS-COMPLETE-MAPPING.md
Normal file
263
docs/KEYWORDS-CLUSTERS-IDEAS-COMPLETE-MAPPING.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Keywords, Clusters & Ideas - Complete Field Mapping
|
||||
|
||||
**Date:** December 3, 2025
|
||||
|
||||
---
|
||||
|
||||
## 📊 KEYWORDS - Complete Field Reference
|
||||
|
||||
### Backend Model Fields
|
||||
**File:** `backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field Name | Type | Default | Required | Choices | Notes |
|
||||
|------------|------|---------|----------|---------|-------|
|
||||
| `id` | Integer PK | Auto | ✅ | - | Primary key |
|
||||
| `seed_keyword` | ForeignKey | - | ✅ | - | Links to SeedKeyword (PROTECT on delete) |
|
||||
| `volume_override` | Integer | NULL | ❌ | - | Site-specific override (uses seed_keyword.volume if NULL) |
|
||||
| `difficulty_override` | Integer | NULL | ❌ | - | Site-specific override (uses seed_keyword.difficulty if NULL) |
|
||||
| `attribute_values` | JSONField | [] | ❌ | - | Optional metadata (product specs, modifiers) |
|
||||
| `cluster` | ForeignKey | NULL | ❌ | - | Parent cluster (SET_NULL on delete) |
|
||||
| `status` | CharField(50) | `pending` | ✅ | `pending`, `active`, `archived` | Keyword status |
|
||||
| `site` | ForeignKey | - | ✅ | - | Owner site (inherited) |
|
||||
| `sector` | ForeignKey | - | ✅ | - | Owner sector (inherited) |
|
||||
| `account` | ForeignKey | - | ✅ | - | Owner account (inherited) |
|
||||
| `created_at` | DateTime | Auto | ✅ | - | Auto-generated |
|
||||
| `updated_at` | DateTime | Auto | ✅ | - | Auto-updated |
|
||||
|
||||
### Frontend Table Columns
|
||||
**File:** `frontend/src/config/pages/keywords.config.tsx`
|
||||
|
||||
| Column Key | Label | Visible Default | Sortable | Render Notes |
|
||||
|----------|--------|-----------------|----------|--------------|
|
||||
| `keyword` | Keyword | ✅ Yes | ✅ Yes | From seed_keyword.keyword (links to Keywords page) |
|
||||
| `sector_name` | Sector | Conditional* | ✅ Yes | Badge (blue) - shown when viewing all sectors |
|
||||
| `volume` | Volume | ✅ Yes | ✅ Yes | Formatted as number (e.g., 1,250) |
|
||||
| `cluster_name` | Cluster | ✅ Yes | ✅ Yes | Parent cluster name or "-" |
|
||||
| `difficulty` | Difficulty | ✅ Yes | ✅ Yes | Badge (1-5): 1-2=green, 3=amber, 4-5=red |
|
||||
| `intent` | Intent | ✅ Yes | ✅ Yes | Badge colors: Transactional/Commercial=green, Navigational=amber |
|
||||
| `status` | Status | ✅ Yes | ✅ Yes | Badge: pending=amber, active=green, archived=red |
|
||||
| `created_at` | Created | ✅ Yes | ✅ Yes | Relative date (e.g., "2 hours ago") |
|
||||
| (Hidden by default) | | | | |
|
||||
| `updated_at` | Updated | ❌ No | ✅ Yes | Relative date |
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `frontend/src/config/pages/keywords.config.tsx` (Lines 310-360)
|
||||
|
||||
| Filter Key | Label | Type | Options | Dynamic |
|
||||
|-----------|-------|------|---------|---------|
|
||||
| `search` | Search | Text | N/A | - |
|
||||
| `status` | Status | Select | `pending`, `active`, `archived` | ❌ No |
|
||||
| `intent` | Intent | Select | `informational`, `navigational`, `transactional`, `commercial` | ❌ No |
|
||||
| `difficulty` | Difficulty | Select | `1-5` with labels | ❌ No |
|
||||
| `cluster` | Cluster | Select | Dynamic from database | ✅ Yes (loads clusters) |
|
||||
| `volume` | Volume Range | Custom | Min/Max number inputs | ❌ No (range picker) |
|
||||
|
||||
### Frontend Create/Edit Form
|
||||
**File:** `frontend/src/config/pages/keywords.config.tsx` (Lines 560-586)
|
||||
|
||||
| Field Key | Label | Type | Required | Default | Options |
|
||||
|-----------|-------|------|----------|---------|---------|
|
||||
| `seed_keyword_id` | Seed Keyword | Select | ✅ Yes | - | Dynamic from availableSeedKeywords |
|
||||
| `volume_override` | Volume Override | Number | ❌ No | NULL | Numeric input (optional override) |
|
||||
| `difficulty_override` | Difficulty Override | Number | ❌ No | NULL | Select 1-5 |
|
||||
| `cluster_id` | Cluster | Select | ❌ No | NULL | Dynamic from clusters array |
|
||||
| `status` | Status | Select | ✅ Yes | `pending` | `pending`, `active`, `archived` |
|
||||
|
||||
---
|
||||
|
||||
## 📊 CLUSTERS - Complete Field Reference
|
||||
|
||||
### Backend Model Fields
|
||||
**File:** `backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field Name | Type | Default | Required | Choices | Notes |
|
||||
|------------|------|---------|----------|---------|-------|
|
||||
| `id` | Integer PK | Auto | ✅ | - | Primary key |
|
||||
| `name` | CharField(255) | - | ✅ | - | Unique cluster name (unique=True) |
|
||||
| `description` | TextField | NULL | ❌ | - | Optional cluster description |
|
||||
| `keywords_count` | Integer | 0 | ✅ | - | Cached count of linked keywords |
|
||||
| `ideas_count` | Integer | 0 | ✅ | - | Cached count of linked ideas |
|
||||
| `volume` | Integer | 0 | ✅ | - | Cached total volume from keywords |
|
||||
| `mapped_pages` | Integer | 0 | ✅ | - | Number of mapped pages |
|
||||
| `status` | CharField(50) | `new` | ✅ | `new`, `idea`, `mapped` | Cluster status |
|
||||
| `site` | ForeignKey | - | ✅ | - | Owner site (inherited) |
|
||||
| `sector` | ForeignKey | - | ✅ | - | Owner sector (inherited) |
|
||||
| `account` | ForeignKey | - | ✅ | - | Owner account (inherited) |
|
||||
| `created_at` | DateTime | Auto | ✅ | - | Auto-generated |
|
||||
| `updated_at` | DateTime | Auto | ✅ | - | Auto-updated |
|
||||
|
||||
### Frontend Table Columns
|
||||
**File:** `frontend/src/config/pages/clusters.config.tsx`
|
||||
|
||||
| Column Key | Label | Visible Default | Sortable | Render Notes |
|
||||
|----------|--------|-----------------|----------|--------------|
|
||||
| `name` | Cluster Name | ✅ Yes | ✅ Yes | Link to cluster detail page |
|
||||
| `sector_name` | Sector | Conditional* | ✅ Yes | Badge (blue) - shown when viewing all sectors |
|
||||
| `keywords_count` | Keywords | ✅ Yes | ✅ Yes | Formatted as number (e.g., 45) |
|
||||
| `ideas_count` | Ideas | ✅ Yes | ✅ Yes | Formatted as number (e.g., 12) |
|
||||
| `volume` | Volume | ✅ Yes | ✅ Yes | Formatted as number (e.g., 5,280) |
|
||||
| `difficulty` | Difficulty | ✅ Yes | ✅ Yes | Badge (1-5): 1-2=green, 3=amber, 4-5=red |
|
||||
| `content_count` | Content | ✅ Yes | ✅ Yes | Formatted as number |
|
||||
| `status` | Status | ✅ Yes | ✅ Yes | Badge: new=amber, idea=blue, mapped=green |
|
||||
| `created_at` | Created | ✅ Yes | ✅ Yes | Relative date |
|
||||
| (Hidden by default) | | | | |
|
||||
| `description` | Description | ❌ No | ❌ No | Text truncated to 250px |
|
||||
| `mapped_pages` | Mapped Pages | ❌ No | ✅ Yes | Formatted number |
|
||||
| `updated_at` | Updated | ❌ No | ✅ Yes | Relative date |
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `frontend/src/config/pages/clusters.config.tsx` (Lines 240-290)
|
||||
|
||||
| Filter Key | Label | Type | Options | Dynamic |
|
||||
|-----------|-------|------|---------|---------|
|
||||
| `search` | Search | Text | N/A | - |
|
||||
| `status` | Status | Select | `new`, `idea`, `mapped` | ❌ No |
|
||||
| `difficulty` | Difficulty | Select | `1-5` with labels | ❌ No |
|
||||
| `volume` | Volume Range | Custom | Min/Max number inputs | ❌ No (range picker) |
|
||||
|
||||
### Frontend Create/Edit Form
|
||||
**File:** `frontend/src/config/pages/clusters.config.tsx` (Lines 405-418)
|
||||
|
||||
| Field Key | Label | Type | Required | Default | Options |
|
||||
|-----------|-------|------|----------|---------|---------|
|
||||
| `name` | Cluster Name | Text | ✅ Yes | - | Text input (placeholder: "Enter cluster name") |
|
||||
| `description` | Description | Textarea | ❌ No | NULL | Textarea (placeholder: "Enter cluster description") |
|
||||
| `status` | Status | Select | ✅ Yes | `new` | `new`, `idea`, `mapped` |
|
||||
|
||||
---
|
||||
|
||||
## 📊 CONTENT IDEAS - Complete Field Reference
|
||||
|
||||
### Backend Model Fields
|
||||
**File:** `backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field Name | Type | Default | Required | Choices | Notes |
|
||||
|------------|------|---------|----------|---------|-------|
|
||||
| `id` | Integer PK | Auto | ✅ | - | Primary key |
|
||||
| `idea_title` | CharField(255) | - | ✅ | - | Content idea title |
|
||||
| `description` | TextField | NULL | ❌ | - | Content outline/description |
|
||||
| `target_keywords` | CharField(500) | '' | ❌ | - | Comma-separated keywords (legacy) |
|
||||
| `keyword_objects` | M2M(Keywords) | - | ❌ | - | Individual keywords linked to idea |
|
||||
| `keyword_cluster` | ForeignKey(Clusters) | NULL | ❌ | - | Parent cluster (SET_NULL on delete) |
|
||||
| `status` | CharField(50) | `new` | ✅ | `new`, `scheduled`, `completed`, `published` | Idea workflow status |
|
||||
| `estimated_word_count` | Integer | 1000 | ✅ | - | Target article length |
|
||||
| `content_type` | CharField(50) | `post` | ✅ | `post`, `page`, `product`, `taxonomy` | Content type |
|
||||
| `content_structure` | CharField(50) | `article` | ✅ | See structures below | Content format/structure |
|
||||
| `site` | ForeignKey | - | ✅ | - | Owner site (inherited) |
|
||||
| `sector` | ForeignKey | - | ✅ | - | Owner sector (inherited) |
|
||||
| `account` | ForeignKey | - | ✅ | - | Owner account (inherited) |
|
||||
| `created_at` | DateTime | Auto | ✅ | - | Auto-generated |
|
||||
| `updated_at` | DateTime | Auto | ✅ | - | Auto-updated |
|
||||
|
||||
**Content Structure Choices (based on content_type):**
|
||||
- **Post:** `article`, `guide`, `comparison`, `review`, `listicle`
|
||||
- **Page:** `landing_page`, `business_page`, `service_page`, `general`, `cluster_hub`
|
||||
- **Product:** `product_page`
|
||||
- **Taxonomy:** `category_archive`, `tag_archive`, `attribute_archive`
|
||||
|
||||
### Frontend Table Columns
|
||||
**File:** `frontend/src/config/pages/ideas.config.tsx`
|
||||
|
||||
| Column Key | Label | Visible Default | Sortable | Render Notes |
|
||||
|----------|--------|-----------------|----------|--------------|
|
||||
| `idea_title` | Title | ✅ Yes | ✅ Yes | Expandable (shows description) |
|
||||
| `sector_name` | Sector | Conditional* | ✅ Yes | Badge (blue) - shown when viewing all sectors |
|
||||
| `content_structure` | Structure | ✅ Yes | ✅ Yes | Badge (purple): article, guide, guide, etc. |
|
||||
| `content_type` | Type | ✅ Yes | ✅ Yes | Badge (blue): post, page, product, taxonomy |
|
||||
| `target_keywords` | Target Keywords | ✅ Yes | ❌ No | Text truncated to 250px |
|
||||
| `keyword_cluster_name` | Cluster | ✅ Yes | ✅ Yes | Parent cluster name or "-" |
|
||||
| `status` | Status | ✅ Yes | ✅ Yes | Badge: new=amber, scheduled=blue, completed=blue, published=green |
|
||||
| `estimated_word_count` | Words | ✅ Yes | ✅ Yes | Formatted as number (e.g., 1,500) |
|
||||
| `created_at` | Created | ✅ Yes | ✅ Yes | Relative date |
|
||||
| (Hidden by default) | | | | |
|
||||
| `updated_at` | Updated | ❌ No | ✅ Yes | Relative date |
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `frontend/src/config/pages/ideas.config.tsx` (Lines 218-270)
|
||||
|
||||
| Filter Key | Label | Type | Options | Dynamic |
|
||||
|-----------|-------|------|---------|---------|
|
||||
| `search` | Search | Text | N/A | - |
|
||||
| `status` | Status | Select | `new`, `scheduled`, `completed`, `published` | ❌ No |
|
||||
| `content_structure` | Structure | Select | article, guide, comparison, etc. (all 13 options) | ❌ No |
|
||||
| `content_type` | Type | Select | `post`, `page`, `product`, `taxonomy` | ❌ No |
|
||||
| `cluster` | Cluster | Select | Dynamic from database | ✅ Yes (loads clusters) |
|
||||
|
||||
### Frontend Create/Edit Form
|
||||
**File:** `frontend/src/config/pages/ideas.config.tsx` (Lines 372-417)
|
||||
|
||||
| Field Key | Label | Type | Required | Default | Options |
|
||||
|-----------|-------|------|----------|---------|---------|
|
||||
| `idea_title` | Title | Text | ✅ Yes | - | Text input (placeholder: "Enter idea title") |
|
||||
| `description` | Description | Textarea | ❌ No | NULL | Textarea (placeholder: "Enter content outline") |
|
||||
| `content_type` | Content Type | Select | ✅ Yes | `post` | `post`, `page`, `product`, `taxonomy` |
|
||||
| `content_structure` | Content Structure | Select | ✅ Yes | `article` | 13 structure options (depends on content_type) |
|
||||
| `target_keywords` | Target Keywords | Text | ❌ No | NULL | Text input (comma-separated) |
|
||||
| `keyword_cluster_id` | Cluster | Select | ❌ No | NULL | Dynamic from clusters array |
|
||||
| `status` | Status | Select | ✅ Yes | `new` | `new`, `scheduled`, `completed`, `published` |
|
||||
| `estimated_word_count` | Word Count | Number | ❌ No | 1000 | Numeric input |
|
||||
|
||||
---
|
||||
|
||||
## 📝 SUMMARY COMPARISON
|
||||
|
||||
### Status Fields
|
||||
| Module | Backend Default | Backend Choices | Frontend Form Default | Frontend Form Choices |
|
||||
|--------|-----------------|-----------------|----------------------|----------------------|
|
||||
| **Keywords** | `pending` | pending, active, archived | `pending` | pending, active, archived |
|
||||
| **Clusters** | `new` | new, idea, mapped | `new` | new, idea, mapped |
|
||||
| **Ideas** | `new` | new, scheduled, completed, published | `new` | new, scheduled, completed, published |
|
||||
|
||||
### Required Fields (Must be filled)
|
||||
| Module | Required Fields |
|
||||
|--------|-----------------|
|
||||
| **Keywords** | seed_keyword_id, status, site, sector, account |
|
||||
| **Clusters** | name, status, site, sector, account |
|
||||
| **Ideas** | idea_title, status, content_type, content_structure, estimated_word_count, site, sector, account |
|
||||
|
||||
### Optional Fields
|
||||
| Module | Optional Fields |
|
||||
|--------|-----------------|
|
||||
| **Keywords** | volume_override, difficulty_override, attribute_values, cluster_id |
|
||||
| **Clusters** | description |
|
||||
| **Ideas** | description, target_keywords, keyword_objects, keyword_cluster_id |
|
||||
|
||||
### Dynamic Dropdowns (Loaded from DB)
|
||||
| Module | Filter | Form |
|
||||
|--------|--------|------|
|
||||
| **Keywords** | cluster (dropdown) | seed_keyword_id (all available), cluster_id (all clusters for sector) |
|
||||
| **Clusters** | - | - |
|
||||
| **Ideas** | cluster (dropdown) | keyword_cluster_id (all clusters for sector) |
|
||||
|
||||
### Visible-by-Default Table Columns
|
||||
| Module | Count | Primary Columns |
|
||||
|--------|-------|-----------------|
|
||||
| **Keywords** | 9 | keyword, volume, cluster, difficulty, intent, status, created_at |
|
||||
| **Clusters** | 11 | name, keywords_count, ideas_count, volume, difficulty, content_count, status, created_at |
|
||||
| **Ideas** | 10 | idea_title, content_structure, content_type, target_keywords, cluster, status, word_count, created_at |
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Key Differences
|
||||
|
||||
### Keywords
|
||||
- **Uses:** SeedKeyword (global pool) - one keyword per site/sector
|
||||
- **Overrideable:** volume, difficulty (site-specific)
|
||||
- **Links to:** Clusters (via cluster FK)
|
||||
- **Status:** pending (awaiting cluster), active (clustered), archived
|
||||
|
||||
### Clusters
|
||||
- **Type:** Pure topic clusters (semantic groupings)
|
||||
- **Auto-updated:** keywords_count, ideas_count, volume (cached from keywords)
|
||||
- **Status:** new (no ideas), idea (has ideas), mapped (has content)
|
||||
- **No overrides:** All values are cached/calculated
|
||||
|
||||
### Ideas
|
||||
- **Type:** Content concepts ready for production
|
||||
- **Links:** Cluster (required for workflow), Keywords (optional M2M)
|
||||
- **Customizable:** content_type, content_structure, word_count
|
||||
- **Status:** new → scheduled (queued to writer) → completed (content generated) → published
|
||||
|
||||
---
|
||||
|
||||
**END OF COMPLETE FIELD MAPPING**
|
||||
@@ -1,351 +0,0 @@
|
||||
# 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
|
||||
@@ -1,364 +0,0 @@
|
||||
# SiteBuilder/Blueprint Removal Summary
|
||||
|
||||
**Date:** December 1, 2025
|
||||
**Status:** ✅ Complete - Backend Healthy
|
||||
|
||||
## Overview
|
||||
|
||||
Successfully removed all SiteBuilder and Blueprint functionality from IGNY8 system while maintaining the core planner-writer-publisher workflow and WordPress integration.
|
||||
|
||||
---
|
||||
|
||||
## What Was Removed
|
||||
|
||||
### 1. Django Models (backend/igny8_core/business/site_building/models.py)
|
||||
- ❌ `SiteBlueprint` - Legacy site planning model
|
||||
- ❌ `PageBlueprint` - Legacy page planning model
|
||||
- ❌ `SiteBlueprintCluster` - Blueprint-cluster relationship
|
||||
- ❌ `SiteBlueprintTaxonomy` - Blueprint-taxonomy relationship
|
||||
- ❌ `ContentTaxonomyMap` - Replaced with direct M2M
|
||||
|
||||
### 2. Django Module
|
||||
- ❌ `backend/igny8_core/business/site_builder/` - Entire module removed from INSTALLED_APPS (settings.py line 60)
|
||||
- ⚠️ Directory still exists with tests/services but not loaded by Django
|
||||
|
||||
### 3. Frontend Components
|
||||
- ❌ `frontend/src/modules/siteBuilder/` - Entire directory removed
|
||||
- ❌ `frontend/src/services/api.ts` - SiteBlueprint interfaces and functions removed (replaced with comment)
|
||||
|
||||
### 4. API Endpoints (backend/igny8_core/modules/publisher/views.py)
|
||||
- ❌ `PublisherViewSet.publish_to_sites()` - Blueprint publishing action
|
||||
- ❌ `PublisherViewSet.deployment_readiness()` - Blueprint readiness check
|
||||
- ❌ `PublisherViewSet.deploy()` - Blueprint deployment action
|
||||
|
||||
### 5. Publishing Service Methods (backend/igny8_core/business/publishing/services/publisher_service.py)
|
||||
- ❌ `PublisherService.publish_to_sites()` - Blueprint publishing
|
||||
- ❌ `PublisherService.get_deployment_status()` - Blueprint deployment status
|
||||
|
||||
### 6. Publishing Models Foreign Keys
|
||||
- ❌ `PublishingRecord.site_blueprint` - FK removed
|
||||
- ❌ `DeploymentRecord.site_blueprint` - FK removed
|
||||
|
||||
---
|
||||
|
||||
## What Was Simplified
|
||||
|
||||
### Taxonomy Architecture Change
|
||||
|
||||
**Before (Complex):**
|
||||
```
|
||||
Content → ContentTaxonomyMap → ContentTaxonomy
|
||||
(through table with FK)
|
||||
```
|
||||
|
||||
**After (Simple):**
|
||||
```
|
||||
Content ↔ ContentTaxonomy
|
||||
(many-to-many via ContentTaxonomyRelation)
|
||||
```
|
||||
|
||||
**Files Changed:**
|
||||
1. `backend/igny8_core/business/content/models.py`
|
||||
- Added `Content.taxonomy_terms` M2M field
|
||||
- Through model: `ContentTaxonomyRelation`
|
||||
|
||||
2. `backend/igny8_core/tasks/wordpress_publishing.py`
|
||||
- Updated to use `content.taxonomy_terms.filter(taxonomy_type='category')`
|
||||
- Updated to use `content.taxonomy_terms.filter(taxonomy_type='tag')`
|
||||
|
||||
3. `backend/igny8_core/business/planning/services/candidate_engine.py`
|
||||
- Changed from `ContentTaxonomyMap.objects.filter(content=...)`
|
||||
- To: `content.taxonomy_terms.values_list('id', flat=True)`
|
||||
|
||||
---
|
||||
|
||||
## Current System Architecture
|
||||
|
||||
### ✅ Planner-Writer-Publisher Workflow (Intact)
|
||||
|
||||
```
|
||||
1. PLANNER (Phase 1-3)
|
||||
Keywords → Clusters → Ideas
|
||||
|
||||
2. WRITER (Phase 4)
|
||||
Ideas → Tasks → Content
|
||||
|
||||
3. PUBLISHER (Phase 5)
|
||||
Content → WordPress/Sites
|
||||
```
|
||||
|
||||
### ✅ Content Taxonomy Model
|
||||
|
||||
**Location:** `backend/igny8_core/business/content/models.py`
|
||||
|
||||
**Model: ContentTaxonomy**
|
||||
```python
|
||||
class ContentTaxonomy(SiteSectorBaseModel):
|
||||
# Core fields
|
||||
name CharField(255) # "Technology", "Tutorial"
|
||||
slug SlugField(255) # "technology", "tutorial"
|
||||
taxonomy_type CharField(50) # "category" or "tag"
|
||||
description TextField # Term description
|
||||
count IntegerField # Usage count
|
||||
|
||||
# WordPress sync fields
|
||||
external_taxonomy CharField(100) # "category", "post_tag"
|
||||
external_id IntegerField # WordPress term_id
|
||||
|
||||
# Metadata
|
||||
metadata JSONField # AI generation details
|
||||
|
||||
# Relationships
|
||||
contents M2M(Content) # Related content
|
||||
```
|
||||
|
||||
**Model: Content**
|
||||
```python
|
||||
class Content(SiteSectorBaseModel):
|
||||
# Core fields
|
||||
title CharField(255)
|
||||
content_html TextField
|
||||
word_count IntegerField
|
||||
|
||||
# SEO
|
||||
meta_title CharField(255)
|
||||
meta_description TextField
|
||||
primary_keyword CharField(255)
|
||||
secondary_keywords JSONField
|
||||
|
||||
# Relationships
|
||||
cluster FK(Clusters) # Required parent cluster
|
||||
taxonomy_terms M2M(ContentTaxonomy) # Categories & tags
|
||||
|
||||
# Type/Structure
|
||||
content_type CharField(50) # post, page, product
|
||||
content_structure CharField(50) # article, guide, review, etc.
|
||||
|
||||
# WordPress sync
|
||||
external_id CharField(255) # WordPress post ID
|
||||
external_url URLField # WordPress URL
|
||||
external_type CharField(100) # WordPress post type
|
||||
sync_status CharField(50) # Sync status
|
||||
|
||||
# Source & Status
|
||||
source CharField(50) # igny8 or wordpress
|
||||
status CharField(50) # draft, review, published
|
||||
```
|
||||
|
||||
**Through Model: ContentTaxonomyRelation**
|
||||
```python
|
||||
class ContentTaxonomyRelation(models.Model):
|
||||
content FK(Content)
|
||||
taxonomy FK(ContentTaxonomy)
|
||||
created_at DateTimeField
|
||||
updated_at DateTimeField
|
||||
|
||||
unique_together = [['content', 'taxonomy']]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## WordPress Integration (Unchanged)
|
||||
|
||||
### Bidirectional Sync Still Works
|
||||
|
||||
**From IGNY8 → WordPress:**
|
||||
```python
|
||||
# File: backend/igny8_core/tasks/wordpress_publishing.py
|
||||
categories = [
|
||||
term.name
|
||||
for term in content.taxonomy_terms.filter(taxonomy_type='category')
|
||||
]
|
||||
tags = [
|
||||
term.name
|
||||
for term in content.taxonomy_terms.filter(taxonomy_type='tag')
|
||||
]
|
||||
```
|
||||
|
||||
**From WordPress → IGNY8:**
|
||||
- WordPress plugin continues to sync content back
|
||||
- External IDs maintained in `Content.external_id` and `ContentTaxonomy.external_id`
|
||||
- Logging system intact: `[5-homeg8.com] [POST] ...`
|
||||
|
||||
---
|
||||
|
||||
## Database Migration
|
||||
|
||||
### Migration File Created
|
||||
**Location:** `backend/igny8_core/business/site_building/migrations/0002_remove_blueprint_models.py`
|
||||
|
||||
**Operations:**
|
||||
1. Drop table: `site_building_siteblueprint`
|
||||
2. Drop table: `site_building_pageblueprint`
|
||||
3. Drop table: `site_building_siteblueprintcluster`
|
||||
4. Drop table: `site_building_siteblueprinttaxonomy`
|
||||
5. Remove FK: `publishing_publishingrecord.site_blueprint_id`
|
||||
6. Remove FK: `publishing_deploymentrecord.site_blueprint_id`
|
||||
|
||||
### ⚠️ Migration Status: NOT YET APPLIED
|
||||
|
||||
**Reason:** PostgreSQL database is external (not in docker-compose)
|
||||
|
||||
**To Apply Manually:**
|
||||
```bash
|
||||
# Connect to your PostgreSQL database and run:
|
||||
cd /data/app/igny8/backend
|
||||
docker exec -it igny8_backend python manage.py migrate
|
||||
```
|
||||
|
||||
**Or if manual SQL preferred:**
|
||||
```sql
|
||||
-- Drop blueprint tables
|
||||
DROP TABLE IF EXISTS site_building_siteblueprinttaxonomy CASCADE;
|
||||
DROP TABLE IF EXISTS site_building_siteblueprintcluster CASCADE;
|
||||
DROP TABLE IF EXISTS site_building_pageblueprint CASCADE;
|
||||
DROP TABLE IF EXISTS site_building_siteblueprint CASCADE;
|
||||
|
||||
-- Remove foreign keys from publishing tables
|
||||
ALTER TABLE publishing_publishingrecord DROP COLUMN IF EXISTS site_blueprint_id;
|
||||
ALTER TABLE publishing_deploymentrecord DROP COLUMN IF EXISTS site_blueprint_id;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files Modified (24 Backend + 3 Frontend)
|
||||
|
||||
### Backend Core
|
||||
1. `backend/igny8_core/settings.py` - Removed site_builder from INSTALLED_APPS
|
||||
2. `backend/igny8_core/business/site_building/models.py` - Emptied (placeholder comments only)
|
||||
3. `backend/igny8_core/business/site_building/admin.py` - Emptied
|
||||
4. `backend/igny8_core/business/publishing/models.py` - Removed site_blueprint FK
|
||||
5. `backend/igny8_core/business/publishing/services/publisher_service.py` - Removed blueprint methods
|
||||
6. `backend/igny8_core/modules/publisher/views.py` - Removed blueprint actions
|
||||
7. `backend/igny8_core/modules/publisher/serializers.py` - Fixed to use exclude=[]
|
||||
8. `backend/igny8_core/tasks/wordpress_publishing.py` - Updated to use M2M taxonomy
|
||||
|
||||
### Backend Services
|
||||
9. `backend/igny8_core/business/planning/services/metadata_mapping_service.py` - Removed ContentTaxonomyMap import
|
||||
10. `backend/igny8_core/business/planning/services/candidate_engine.py` - Updated to use M2M taxonomy
|
||||
|
||||
### Frontend
|
||||
11. `frontend/src/services/api.ts` - Removed SiteBlueprint interfaces/functions
|
||||
12. `frontend/src/modules/siteBuilder/` - **DELETED DIRECTORY**
|
||||
|
||||
---
|
||||
|
||||
## Verification Steps Completed
|
||||
|
||||
### ✅ Backend Health Check
|
||||
```bash
|
||||
$ docker ps --filter "name=igny8_backend"
|
||||
igny8_backend Up 27 seconds (healthy)
|
||||
```
|
||||
|
||||
### ✅ Celery Worker Health
|
||||
```bash
|
||||
$ docker ps --filter "name=igny8_celery"
|
||||
igny8_celery_worker Up About a minute
|
||||
igny8_celery_beat Up 3 hours
|
||||
```
|
||||
|
||||
### ✅ Backend Startup Logs
|
||||
```
|
||||
[2025-12-01 02:03:31] [INFO] Starting gunicorn 23.0.0
|
||||
[2025-12-01 02:03:31] [INFO] Listening at: http://0.0.0.0:8010
|
||||
[2025-12-01 02:03:31] [INFO] Using worker: sync
|
||||
[2025-12-01 02:03:31] [INFO] Booting worker with pid: 7
|
||||
[2025-12-01 02:03:31] [INFO] Booting worker with pid: 8
|
||||
[2025-12-01 02:03:31] [INFO] Booting worker with pid: 9
|
||||
[2025-12-01 02:03:31] [INFO] Booting worker with pid: 10
|
||||
```
|
||||
|
||||
### ✅ No Import Errors
|
||||
No `NameError: name 'SiteBlueprint' is not defined` errors
|
||||
|
||||
---
|
||||
|
||||
## Remaining References (Harmless)
|
||||
|
||||
**Where:** site_building tests and services (not loaded)
|
||||
- `backend/igny8_core/business/site_building/tests/` - Test files (not executed)
|
||||
- `backend/igny8_core/business/site_building/services/` - Service files (not imported)
|
||||
- `backend/igny8_core/business/planning/models.py` - Comment only
|
||||
|
||||
**Why Harmless:** site_builder module removed from INSTALLED_APPS so Django never loads these files.
|
||||
|
||||
---
|
||||
|
||||
## Django Admin Access
|
||||
|
||||
### ✅ ContentTaxonomy Available
|
||||
**URL:** `http://your-domain/admin/writer/contenttaxonomy/`
|
||||
|
||||
**Features:**
|
||||
- Create/edit categories and tags
|
||||
- Set taxonomy_type (category/tag)
|
||||
- Configure WordPress sync (external_id, external_taxonomy)
|
||||
- View count and metadata
|
||||
|
||||
### ✅ Content Available
|
||||
**URL:** `http://your-domain/admin/writer/content/`
|
||||
|
||||
**Features:**
|
||||
- View all content
|
||||
- Edit taxonomy_terms M2M relationships
|
||||
- See cluster relationships
|
||||
- WordPress sync status
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (Optional)
|
||||
|
||||
### 1. Apply Database Migration
|
||||
```bash
|
||||
docker exec -it igny8_backend python manage.py migrate
|
||||
```
|
||||
|
||||
### 2. Clean Up Remaining Files (Optional)
|
||||
```bash
|
||||
# Remove site_building directory entirely if not needed for history
|
||||
rm -rf backend/igny8_core/business/site_building/
|
||||
|
||||
# Or keep for git history but add .gitignore
|
||||
echo "backend/igny8_core/business/site_building/" >> .gitignore
|
||||
```
|
||||
|
||||
### 3. Test WordPress Publishing
|
||||
1. Create test content in Django admin
|
||||
2. Assign categories/tags via taxonomy_terms M2M
|
||||
3. Publish to WordPress
|
||||
4. Verify categories/tags appear correctly
|
||||
5. Check sync logs: `backend/logs/publish-sync-logs/*.log`
|
||||
|
||||
---
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Python Bytecode Cache Issue Resolved
|
||||
**Problem:** Docker container cached old .pyc files with SiteBlueprint references
|
||||
**Solution:** Used `docker compose up -d --force-recreate igny8_backend` to clear cache
|
||||
|
||||
### Import Structure Clean
|
||||
- No circular imports
|
||||
- No missing dependencies
|
||||
- All type hints cleaned from removed models
|
||||
|
||||
### Multi-Tenant Architecture Intact
|
||||
```
|
||||
Account → Site → Sector → Content/Taxonomy
|
||||
```
|
||||
All models inherit from `SiteSectorBaseModel` with proper filtering.
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions about this removal:
|
||||
1. Check backend logs: `docker logs igny8_backend`
|
||||
2. Check celery logs: `docker logs igny8_celery_worker`
|
||||
3. Check publish logs: `backend/logs/publish-sync-logs/`
|
||||
4. Refer to: `docs/02-PLANNER-WRITER-WORKFLOW-TECHNICAL-GUIDE.md`
|
||||
|
||||
---
|
||||
|
||||
**Summary:** All SiteBuilder/Blueprint functionality successfully removed. Backend healthy. WordPress publishing intact. Taxonomy simplified to direct M2M relationship. Migration file created but not yet applied.
|
||||
335
docs/STATUS-IMPLEMENTATION-TABLES.md
Normal file
335
docs/STATUS-IMPLEMENTATION-TABLES.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# Status Implementation Tables - Complete Reference
|
||||
|
||||
**Date:** December 3, 2025
|
||||
|
||||
---
|
||||
|
||||
## 🎯 KEYWORDS MODULE
|
||||
|
||||
### Backend Model
|
||||
**File:** `/backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field | Type | Choices | Default | Required | Description |
|
||||
|-------|------|---------|---------|----------|-------------|
|
||||
| `status` | CharField(50) | `new`, `mapped` | `new` | ✅ Yes | Workflow status |
|
||||
| `disabled` | BooleanField | - | `False` | ✅ Yes | Filter control (exclude from processes) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Table Column
|
||||
**File:** `/frontend/src/config/pages/keywords.config.tsx` (Lines ~230-248)
|
||||
|
||||
| Status Value | Badge Color | Badge Label | Display When |
|
||||
|--------------|-------------|-------------|--------------|
|
||||
| `new` | Amber/Yellow | New | Keyword not yet clustered |
|
||||
| `mapped` | Green | Mapped | Keyword assigned to cluster |
|
||||
| *(disabled=true)* | Red/Gray | Disabled | User manually disabled (optional display) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `/frontend/src/config/pages/keywords.config.tsx` (Lines ~310-318)
|
||||
|
||||
| Filter Type | Options | Default | Description |
|
||||
|-------------|---------|---------|-------------|
|
||||
| Status Select | `new`, `mapped` | All | Workflow status filter |
|
||||
| Disabled Checkbox | Show/Hide disabled | Hide disabled | Filter control |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Form Fields
|
||||
**File:** `/frontend/src/config/pages/keywords.config.tsx` (Lines ~560-570)
|
||||
|
||||
| Field | Type | Options | Default | Required | Editable |
|
||||
|-------|------|---------|---------|----------|----------|
|
||||
| Status | Select | `new`, `mapped` | `new` | ✅ Yes | ✅ Yes |
|
||||
| Disabled | Checkbox | true/false | `false` | ❌ No | ✅ Yes |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 CLUSTERS MODULE
|
||||
|
||||
### Backend Model
|
||||
**File:** `/backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field | Type | Choices | Default | Required | Description |
|
||||
|-------|------|---------|---------|----------|-------------|
|
||||
| `status` | CharField(50) | `new`, `mapped` | `new` | ✅ Yes | Workflow status |
|
||||
| `disabled` | BooleanField | - | `False` | ✅ Yes | Filter control (exclude from processes) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Table Column
|
||||
**File:** `/frontend/src/config/pages/clusters.config.tsx` (Lines ~190-200)
|
||||
|
||||
| Status Value | Badge Color | Badge Label | Display When |
|
||||
|--------------|-------------|-------------|--------------|
|
||||
| `new` | Amber/Yellow | New | Cluster created, no ideas generated yet |
|
||||
| `mapped` | Green | Mapped | Ideas generated from cluster |
|
||||
| *(disabled=true)* | Red/Gray | Disabled | User manually disabled (optional display) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `/frontend/src/config/pages/clusters.config.tsx` (Lines ~240-253)
|
||||
|
||||
| Filter Type | Options | Default | Description |
|
||||
|-------------|---------|---------|-------------|
|
||||
| Status Select | `new`, `mapped` | All | Workflow status filter |
|
||||
| Disabled Checkbox | Show/Hide disabled | Hide disabled | Filter control |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Form Fields
|
||||
**File:** `/frontend/src/config/pages/clusters.config.tsx` (Lines ~405-418)
|
||||
|
||||
| Field | Type | Options | Default | Required | Editable |
|
||||
|-------|------|---------|---------|----------|----------|
|
||||
| Status | Select | `new`, `mapped` | `new` | ✅ Yes | ✅ Yes |
|
||||
| Disabled | Checkbox | true/false | `false` | ❌ No | ✅ Yes |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 IDEAS MODULE
|
||||
|
||||
### Backend Model
|
||||
**File:** `/backend/igny8_core/business/planning/models.py`
|
||||
|
||||
| Field | Type | Choices | Default | Required | Description |
|
||||
|-------|------|---------|---------|----------|-------------|
|
||||
| `status` | CharField(50) | `new`, `queued`, `completed` | `new` | ✅ Yes | Workflow status |
|
||||
| `disabled` | BooleanField | - | `False` | ✅ Yes | Filter control (exclude from processes) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Table Column
|
||||
**File:** `/frontend/src/config/pages/ideas.config.tsx` (Lines ~170-185)
|
||||
|
||||
| Status Value | Badge Color | Badge Label | Display When |
|
||||
|--------------|-------------|-------------|--------------|
|
||||
| `new` | Amber/Yellow | New | Idea generated, not queued yet |
|
||||
| `queued` | Blue | Queued | Task created in Writer module |
|
||||
| `completed` | Green | Completed | Content generated (Task completed) |
|
||||
| *(disabled=true)* | Red/Gray | Disabled | User manually disabled (optional display) |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Filter Dropdown
|
||||
**File:** `/frontend/src/config/pages/ideas.config.tsx` (Lines ~218-228)
|
||||
|
||||
| Filter Type | Options | Default | Description |
|
||||
|-------------|---------|---------|-------------|
|
||||
| Status Select | `new`, `queued`, `completed` | All | Workflow status filter |
|
||||
| Disabled Checkbox | Show/Hide disabled | Hide disabled | Filter control |
|
||||
|
||||
---
|
||||
|
||||
### Frontend Form Fields
|
||||
**File:** `/frontend/src/config/pages/ideas.config.tsx` (Lines ~372-385)
|
||||
|
||||
| Field | Type | Options | Default | Required | Editable |
|
||||
|-------|------|---------|---------|----------|----------|
|
||||
| Status | Select | `new`, `queued`, `completed` | `new` | ✅ Yes | ✅ Yes |
|
||||
| Disabled | Checkbox | true/false | `false` | ❌ No | ✅ Yes |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 🔄 STATUS TRANSITION TABLES
|
||||
|
||||
## KEYWORDS Status Transitions
|
||||
|
||||
| Current Status | Trigger/Action | Next Status | Auto/Manual | Updated By |
|
||||
|----------------|----------------|-------------|-------------|------------|
|
||||
| `new` | AI auto_cluster runs | `mapped` | 🤖 Auto | `auto_cluster.py` Line 297 |
|
||||
| `new` | User manually assigns to cluster | `mapped` | 👤 Manual | User form edit |
|
||||
| `new` | User toggles disabled | *(stays new)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| `mapped` | User toggles disabled | *(stays mapped)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| *(any)* | User re-enables | *(stays same)* + `disabled=false` | 👤 Manual | User form edit |
|
||||
|
||||
**Workflow Path:**
|
||||
```
|
||||
new ──[auto_cluster AI]──> mapped
|
||||
│
|
||||
└──[user toggle disabled]──> (status unchanged, disabled flag set)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CLUSTERS Status Transitions
|
||||
|
||||
| Current Status | Trigger/Action | Next Status | Auto/Manual | Updated By |
|
||||
|----------------|----------------|-------------|-------------|------------|
|
||||
| `new` | AI generate_ideas runs | `mapped` | 🤖 Auto | `generate_ideas.py` (new code) |
|
||||
| `new` | User manually creates ideas | `mapped` | 👤 Manual | User workflow |
|
||||
| `new` | User toggles disabled | *(stays new)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| `mapped` | User toggles disabled | *(stays mapped)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| *(any)* | User re-enables | *(stays same)* + `disabled=false` | 👤 Manual | User form edit |
|
||||
|
||||
**Workflow Path:**
|
||||
```
|
||||
new ──[generate_ideas AI]──> mapped
|
||||
│
|
||||
└──[user toggle disabled]──> (status unchanged, disabled flag set)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IDEAS Status Transitions
|
||||
|
||||
| Current Status | Trigger/Action | Next Status | Auto/Manual | Updated By |
|
||||
|----------------|----------------|-------------|-------------|------------|
|
||||
| `new` | User bulk-queues ideas to writer | `queued` | 👤 Manual | `views.py` Line 1084 |
|
||||
| `queued` | Writer AI generates content | `completed` | 🤖 Auto | `generate_content.py` Line 318 (syncs from Task) |
|
||||
| `queued` | Task status becomes 'completed' | `completed` | 🤖 Auto | Auto-sync from Task.status |
|
||||
| `new` | User toggles disabled | *(stays new)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| `queued` | User toggles disabled | *(stays queued)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| `completed` | User toggles disabled | *(stays completed)* + `disabled=true` | 👤 Manual | User form edit |
|
||||
| *(any)* | User re-enables | *(stays same)* + `disabled=false` | 👤 Manual | User form edit |
|
||||
|
||||
**Workflow Path:**
|
||||
```
|
||||
new ──[user bulk_queue]──> queued ──[generate_content AI]──> completed
|
||||
│ │ │
|
||||
└──[user toggle disabled]────┴───────────[user toggle]──────────┘
|
||||
(status unchanged, disabled flag set)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 📊 COMBINED STATUS OVERVIEW
|
||||
|
||||
## All Modules - Status Values
|
||||
|
||||
| Module | Workflow Statuses | Filter Status | Total Unique Values |
|
||||
|--------|-------------------|---------------|---------------------|
|
||||
| **Keywords** | `new`, `mapped` | `disabled` (boolean) | 2 status + 1 flag |
|
||||
| **Clusters** | `new`, `mapped` | `disabled` (boolean) | 2 status + 1 flag |
|
||||
| **Ideas** | `new`, `queued`, `completed` | `disabled` (boolean) | 3 status + 1 flag |
|
||||
|
||||
---
|
||||
|
||||
## Process Inclusion Matrix
|
||||
|
||||
| Status | Auto-Cluster AI | Generate-Ideas AI | Bulk-Queue | Generate-Content AI | Dashboard Metrics |
|
||||
|--------|-----------------|-------------------|------------|---------------------|-------------------|
|
||||
| Keywords: `new` | ✅ Included | ❌ N/A | ❌ N/A | ❌ N/A | ✅ Counted |
|
||||
| Keywords: `mapped` | ❌ Already clustered | ✅ Used for ideas | ❌ N/A | ❌ N/A | ✅ Counted |
|
||||
| Keywords: `disabled=true` | ❌ Excluded | ❌ Excluded | ❌ N/A | ❌ N/A | ❌ Excluded |
|
||||
| Clusters: `new` | ❌ N/A | ✅ Included | ❌ N/A | ❌ N/A | ✅ Counted |
|
||||
| Clusters: `mapped` | ❌ N/A | ❌ Already has ideas | ✅ Ideas can queue | ❌ N/A | ✅ Counted |
|
||||
| Clusters: `disabled=true` | ❌ N/A | ❌ Excluded | ❌ Excluded | ❌ N/A | ❌ Excluded |
|
||||
| Ideas: `new` | ❌ N/A | ❌ N/A | ✅ Included | ❌ N/A | ✅ Counted |
|
||||
| Ideas: `queued` | ❌ N/A | ❌ N/A | ❌ Already queued | ✅ Included | ✅ Counted |
|
||||
| Ideas: `completed` | ❌ N/A | ❌ N/A | ❌ Already done | ❌ Already done | ✅ Counted |
|
||||
| Ideas: `disabled=true` | ❌ N/A | ❌ N/A | ❌ Excluded | ❌ Excluded | ❌ Excluded |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 🔄 DATA MIGRATION TRANSITION TABLE
|
||||
|
||||
## Keywords Migration
|
||||
|
||||
| Old Status | New Status | New Disabled Flag | Logic |
|
||||
|------------|------------|-------------------|-------|
|
||||
| `pending` | `new` | `false` | Direct mapping |
|
||||
| `active` | `mapped` | `false` | Keyword was clustered |
|
||||
| `archived` | `mapped` | `true` | Preserve data, mark as disabled |
|
||||
|
||||
**SQL Preview:**
|
||||
```sql
|
||||
-- Keywords migration
|
||||
UPDATE igny8_keywords
|
||||
SET status = 'new', disabled = false
|
||||
WHERE status = 'pending';
|
||||
|
||||
UPDATE igny8_keywords
|
||||
SET status = 'mapped', disabled = false
|
||||
WHERE status = 'active';
|
||||
|
||||
UPDATE igny8_keywords
|
||||
SET status = 'mapped', disabled = true
|
||||
WHERE status = 'archived';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Clusters Migration
|
||||
|
||||
| Old Status | New Status | New Disabled Flag | Logic |
|
||||
|------------|------------|-------------------|-------|
|
||||
| `active` (with ideas_count > 0) | `mapped` | `false` | Cluster has ideas |
|
||||
| `active` (with ideas_count = 0) | `new` | `false` | Cluster has no ideas yet |
|
||||
| *(no archived status exists)* | - | - | - |
|
||||
|
||||
**SQL Preview:**
|
||||
```sql
|
||||
-- Clusters migration
|
||||
UPDATE igny8_clusters
|
||||
SET status = 'mapped', disabled = false
|
||||
WHERE ideas_count > 0;
|
||||
|
||||
UPDATE igny8_clusters
|
||||
SET status = 'new', disabled = false
|
||||
WHERE ideas_count = 0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ideas Migration
|
||||
|
||||
| Old Status | New Status | New Disabled Flag | Logic |
|
||||
|------------|------------|-------------------|-------|
|
||||
| `new` | `new` | `false` | No change |
|
||||
| `scheduled` | `queued` | `false` | Rename to match writer workflow |
|
||||
| `published` | `completed` | `false` | Publishing is separate deployment |
|
||||
| *(no archived status)* | - | - | - |
|
||||
|
||||
**SQL Preview:**
|
||||
```sql
|
||||
-- Ideas migration
|
||||
UPDATE igny8_content_ideas
|
||||
SET status = 'new', disabled = false
|
||||
WHERE status = 'new';
|
||||
|
||||
UPDATE igny8_content_ideas
|
||||
SET status = 'queued', disabled = false
|
||||
WHERE status = 'scheduled';
|
||||
|
||||
UPDATE igny8_content_ideas
|
||||
SET status = 'completed', disabled = false
|
||||
WHERE status = 'published';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 📋 SUMMARY COMPARISON TABLE
|
||||
|
||||
## Before vs After
|
||||
|
||||
| Module | Current Status Values | New Status Values | Current Filter | New Filter |
|
||||
|--------|----------------------|-------------------|----------------|------------|
|
||||
| **Keywords** | `pending`, `active`, `archived` | `new`, `mapped` | Status dropdown | Status dropdown + disabled checkbox |
|
||||
| **Clusters** | `active` (hardcoded, no choices) | `new`, `mapped` | Status dropdown | Status dropdown + disabled checkbox |
|
||||
| **Ideas** | `new`, `scheduled`, `published` | `new`, `queued`, `completed` | Status dropdown | Status dropdown + disabled checkbox |
|
||||
|
||||
---
|
||||
|
||||
## Status Count Changes
|
||||
|
||||
| Module | Before | After | Change |
|
||||
|--------|--------|-------|--------|
|
||||
| **Keywords** | 3 status values | 2 workflow + 1 boolean flag | -1 status (simplified) |
|
||||
| **Clusters** | 1 hardcoded value | 2 workflow + 1 boolean flag | +1 status (proper choices) |
|
||||
| **Ideas** | 3 status values | 3 workflow + 1 boolean flag | Same count (renamed) |
|
||||
|
||||
---
|
||||
|
||||
**END OF IMPLEMENTATION TABLES**
|
||||
@@ -1,116 +0,0 @@
|
||||
Understood fully.
|
||||
|
||||
Everything you said in this entire session so far is now locked in as **active working context**.
|
||||
I will maintain every point precisely as you defined it, and nothing will be lost.
|
||||
|
||||
Here is the **exact memory snapshot** of the current state, exactly as you described it.
|
||||
No assumptions. No additions. No explanations unless you ask.
|
||||
|
||||
---
|
||||
|
||||
# **CURRENT STATE SNAPSHOT (Your Words, Consolidated Precisely)**
|
||||
|
||||
### **1. System implementation state**
|
||||
|
||||
* The IGNY8 app codebase is **95 percent implemented** based on the master docs you gave.
|
||||
* You are now finalizing cleanup and integration fixes.
|
||||
|
||||
### **2. Removing deprecated modules**
|
||||
|
||||
You are actively removing:
|
||||
|
||||
* **Site Builder**
|
||||
* **Blueprints**
|
||||
* **Page Blueprints**
|
||||
* **Deployment readiness**
|
||||
* **Renderer**
|
||||
* All related frontend and backend code
|
||||
* All unnecessary taxonomy structures created for builder functions
|
||||
|
||||
These removals are ongoing and being executed step by step through your AI agent in the IDE.
|
||||
|
||||
### **3. Active focus now (your priority list)**
|
||||
|
||||
1. **Remove Site Builder and Renderer completely**
|
||||
2. **Troubleshoot IGNY8 → WordPress Publishing issues**
|
||||
|
||||
### **4. Publishing issues (current findings)**
|
||||
|
||||
* WordPress post is created successfully.
|
||||
* **Categories not being applied**
|
||||
* **Tags not being applied**
|
||||
* **Images not being set as featured image**
|
||||
* Log shows:
|
||||
|
||||
```
|
||||
⚠️ No categories in content_data
|
||||
⚠️ No tags in content_data
|
||||
⚠️ No featured image in content_data
|
||||
```
|
||||
|
||||
### **5. Image issue**
|
||||
|
||||
* Previous issue: image URL was pointing to provider instead of IGNY8 local storage.
|
||||
* You fixed the storage path code.
|
||||
* **Not tested yet**.
|
||||
|
||||
### **6. Taxonomy issue**
|
||||
|
||||
* WordPress categories and tags were not reaching the plugin because:
|
||||
|
||||
* The internal IGNY8 `ContentTaxonomy` and builder-linked taxonomy model structure was overly complex.
|
||||
* Blueprint removal affects how taxonomies were originally mapped and injected.
|
||||
* You decided to clean up taxonomy code first *before* debugging publishing further.
|
||||
|
||||
### **7. Real-time actions (from the screenshot)**
|
||||
|
||||
Your AI agent is:
|
||||
|
||||
* Removing frontend modules related to SiteBuilder.
|
||||
* Searching and deleting folders.
|
||||
* Cleaning routes and navigation.
|
||||
* Cleaning backend references (serializers, views, models).
|
||||
* Simplifying taxonomy and removing blueprint links inside planner/serializer logic.
|
||||
|
||||
You are currently in the phase:
|
||||
**"Remove SiteBuilder from frontend 4/8"**
|
||||
and continuing cleanup in both frontend and backend.
|
||||
|
||||
### **8. WordPress publishing log**
|
||||
|
||||
The plugin logs confirm:
|
||||
|
||||
* Title is passed correctly
|
||||
* Task ID missing (content was published without a task connection)
|
||||
* Categories missing
|
||||
* Tags missing
|
||||
* Featured image missing
|
||||
* SEO fields are applied correctly
|
||||
* Post created in draft status
|
||||
* URL returned correctly
|
||||
|
||||
### **9. Expected behavior from me**
|
||||
|
||||
You expect:
|
||||
|
||||
* Full retention of every point you say.
|
||||
* No drifting.
|
||||
* No assumptions.
|
||||
* Conversational flow led **only by you**.
|
||||
* No detailed answers unless requested.
|
||||
* No large explanations.
|
||||
* You will give the direction, and I follow exactly.
|
||||
|
||||
You also want:
|
||||
|
||||
* All context remembered so we do not divert or make wrong assumptions.
|
||||
|
||||
---
|
||||
|
||||
# **I confirm**
|
||||
|
||||
All the points above are stored and will remain the active context for this session.
|
||||
|
||||
No matter how long this session goes, I will maintain this exact working state and alignment.
|
||||
|
||||
You can continue with the next instruction.
|
||||
@@ -1,75 +0,0 @@
|
||||
Noted.
|
||||
Locked in as the next phase plan.
|
||||
|
||||
Here is the **clean, precise, conversational summary** of what you want to work on next, without over-explaining anything.
|
||||
|
||||
---
|
||||
|
||||
# **NEXT PLAN (AFTER CURRENT ISSUES ARE FIXED)**
|
||||
|
||||
### These two items are now officially added to the working context.
|
||||
|
||||
---
|
||||
|
||||
## **1. Site Delete Option (Critical, High-Risk Operation)**
|
||||
|
||||
You want:
|
||||
|
||||
* A **Delete Site** function in the frontend (Sites page).
|
||||
* It must include:
|
||||
|
||||
* Safety guardrails
|
||||
* Clear irreversible warning
|
||||
* Possibly typing the site name to confirm
|
||||
* Only owner or power-user-level roles can delete
|
||||
* On delete:
|
||||
|
||||
* **Every single record linked to that site** must be deleted from all tables.
|
||||
* Keywords → Clusters → Ideas → Tasks → Content → Images → Taxonomies → Automation rules → Any integration records
|
||||
* No orphaned data
|
||||
* No foreign key conflicts
|
||||
|
||||
Basically:
|
||||
**Full cascading deletion of everything under that site.**
|
||||
|
||||
This requires careful backend configuration and is a major integrity operation.
|
||||
|
||||
This point is confirmed and stored.
|
||||
|
||||
---
|
||||
|
||||
## **2. Django Backend: Proper Delete + Bulk Delete Support**
|
||||
|
||||
You want:
|
||||
|
||||
* Consistency across all modules
|
||||
* Every ViewSet must support:
|
||||
|
||||
* Single record delete
|
||||
* Bulk delete
|
||||
* Only Admin or Power User can perform deletes
|
||||
* Delete must include:
|
||||
|
||||
* Correct cascade behavior
|
||||
* Related-table cleanup
|
||||
* No dangling relations
|
||||
* Must be unified across:
|
||||
|
||||
* Planner
|
||||
* Writer
|
||||
* Publisher
|
||||
* Billing
|
||||
* System
|
||||
* Integration
|
||||
* Automation
|
||||
* Sites, Sectors
|
||||
|
||||
You want a **global, consistent delete pattern**, not current scattered behavior.
|
||||
|
||||
This point is confirmed and stored.
|
||||
|
||||
---
|
||||
|
||||
Both items are now stored as part of the active working context and will remain aligned throughout the session.
|
||||
|
||||
Tell me how you want to proceed next.
|
||||
@@ -1,424 +0,0 @@
|
||||
# Sites Container - Keep vs Remove Decision Guide
|
||||
|
||||
**Version:** 1.0
|
||||
**Date:** November 29, 2025
|
||||
|
||||
---
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
Do you need Site Builder & Sites Renderer features?
|
||||
│
|
||||
├─ NO → Remove everything (Option A: Full Removal)
|
||||
│ ├─ Delete /sites/ folder
|
||||
│ ├─ Delete /site-builder/ folder
|
||||
│ ├─ Remove backend modules
|
||||
│ ├─ Remove database tables
|
||||
│ └─ Clean up all references
|
||||
│
|
||||
└─ YES → Do you need separate container?
|
||||
│
|
||||
├─ NO → Merge into frontend (Option B: Integration)
|
||||
│ ├─ Copy files to /frontend/
|
||||
│ ├─ Update routes in App.tsx
|
||||
│ ├─ Remove /sites/ container
|
||||
│ └─ Keep backend modules
|
||||
│
|
||||
└─ YES → Keep current setup (Option C: No Changes)
|
||||
├─ Keep /sites/ container running
|
||||
├─ Keep separate ports (8021, 8024)
|
||||
└─ Maintain current architecture
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Option A: Full Removal (No Site Features)
|
||||
|
||||
### When to Choose
|
||||
- ✅ You don't need site blueprint creation
|
||||
- ✅ You don't need public site rendering
|
||||
- ✅ You only need WordPress publishing (direct to WP)
|
||||
- ✅ You want minimal feature set
|
||||
|
||||
### What Gets Removed
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
# Remove folders
|
||||
rm -rf /sites/
|
||||
rm -rf /site-builder/
|
||||
rm -rf /frontend/src/modules/siteBuilder/
|
||||
rm -rf /frontend/src/pages/Sites/ # if exists
|
||||
rm -rf /frontend/src/components/sites/ # site-specific only
|
||||
|
||||
# Remove from docker-compose
|
||||
# Delete igny8_sites service
|
||||
```
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
# Remove modules
|
||||
rm -rf backend/igny8_core/modules/site_builder/
|
||||
rm -rf backend/igny8_core/modules/publisher/ # Only if not using WP publish
|
||||
|
||||
# Remove business logic
|
||||
rm -rf backend/igny8_core/business/site_building/
|
||||
rm -rf backend/igny8_core/business/publishing/ # Be careful - WP uses this
|
||||
|
||||
# Update settings.py - remove from INSTALLED_APPS
|
||||
# 'igny8_core.modules.site_builder',
|
||||
```
|
||||
|
||||
#### Database
|
||||
```sql
|
||||
-- Drop tables (CAREFUL - NO UNDO)
|
||||
DROP TABLE site_builder_siteblueprint CASCADE;
|
||||
DROP TABLE site_builder_sitepage CASCADE;
|
||||
DROP TABLE site_builder_taxonomy CASCADE;
|
||||
DROP TABLE site_builder_cluster_blueprints CASCADE;
|
||||
-- etc.
|
||||
```
|
||||
|
||||
#### URLs
|
||||
```python
|
||||
# In backend/igny8_core/urls.py
|
||||
# Remove:
|
||||
# path('api/v1/site-builder/', include('igny8_core.modules.site_builder.urls')),
|
||||
# path('api/v1/publisher/sites/<int:site_id>/definition/', ...)
|
||||
```
|
||||
|
||||
### Files to Update
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `docker-compose.app.yml` | Remove igny8_sites service |
|
||||
| `backend/igny8_core/settings.py` | Remove site_builder from INSTALLED_APPS |
|
||||
| `backend/igny8_core/urls.py` | Remove site-builder URL patterns |
|
||||
| `frontend/src/App.tsx` | Remove site-related routes |
|
||||
| `frontend/src/components/sidebar/AppSidebar.tsx` | Remove site builder menu |
|
||||
| `frontend/package.json` | Remove site-builder dependencies (if any) |
|
||||
| `docs/MASTER_REFERENCE.md` | Update architecture section |
|
||||
|
||||
### Impact
|
||||
- ❌ No site blueprint creation
|
||||
- ❌ No public site rendering
|
||||
- ✅ WordPress publishing still works (if using direct WP API)
|
||||
- ✅ Smaller codebase
|
||||
- ✅ Fewer containers
|
||||
- ✅ Simpler deployment
|
||||
|
||||
### Rollback Difficulty
|
||||
🔴 **HARD** - Database tables deleted, requires full backup restore
|
||||
|
||||
---
|
||||
|
||||
## Option B: Merge Into Frontend (Recommended)
|
||||
|
||||
### When to Choose
|
||||
- ✅ You need site builder features
|
||||
- ✅ You need public site rendering
|
||||
- ✅ You want simpler deployment
|
||||
- ✅ You want unified authentication
|
||||
- ✅ Sites are internal or low-traffic
|
||||
|
||||
### What Changes
|
||||
|
||||
#### Keep These (Backend)
|
||||
```
|
||||
backend/igny8_core/
|
||||
├── modules/
|
||||
│ ├── site_builder/ ✅ KEEP
|
||||
│ └── publisher/ ✅ KEEP
|
||||
├── business/
|
||||
│ ├── site_building/ ✅ KEEP
|
||||
│ └── publishing/ ✅ KEEP
|
||||
└── Database tables ✅ KEEP ALL
|
||||
```
|
||||
|
||||
#### Move These (Frontend)
|
||||
```
|
||||
/sites/src/ → /frontend/src/pages/Sites/
|
||||
/sites/src/builder/ → /frontend/src/pages/Sites/Builder/
|
||||
/sites/src/utils/ → /frontend/src/utils/siteRenderer/
|
||||
```
|
||||
|
||||
#### Delete These
|
||||
```
|
||||
/sites/ folder (after copying)
|
||||
/site-builder/ folder
|
||||
/frontend/src/modules/siteBuilder/ (empty)
|
||||
igny8_sites Docker container
|
||||
```
|
||||
|
||||
### Files to Update
|
||||
|
||||
| File | Type | Changes |
|
||||
|------|------|---------|
|
||||
| `frontend/src/App.tsx` | **UPDATE** | Add site builder & renderer routes |
|
||||
| `frontend/src/services/siteRenderer.api.ts` | **CREATE** | Site renderer API client |
|
||||
| `frontend/vite.config.ts` | **UPDATE** | Add SITES_DATA_PATH env |
|
||||
| `docker-compose.app.yml` | **UPDATE** | Remove igny8_sites, update igny8_frontend |
|
||||
| `backend/igny8_core/settings.py` | **VERIFY** | CORS settings (minor) |
|
||||
|
||||
### Step-by-Step Guide
|
||||
📖 **See:** [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md) - Complete instructions
|
||||
|
||||
### Impact
|
||||
- ✅ Site builder still works (routes change)
|
||||
- ✅ Public site rendering still works (routes change)
|
||||
- ✅ Backend unchanged (100% compatible)
|
||||
- ⚠️ Public site URLs change (update links)
|
||||
- ✅ Fewer containers (simpler deployment)
|
||||
- ✅ Unified authentication
|
||||
|
||||
### Rollback Difficulty
|
||||
🟡 **MEDIUM** - Can restore from backup, backend unchanged
|
||||
|
||||
---
|
||||
|
||||
## Option C: Keep Separate Container
|
||||
|
||||
### When to Choose
|
||||
- ✅ You need performance isolation for public sites
|
||||
- ✅ You want to scale sites independently
|
||||
- ✅ You have high-traffic public sites
|
||||
- ✅ You want different deployment schedules
|
||||
- ✅ Current setup works fine
|
||||
|
||||
### What Changes
|
||||
**Nothing!** Keep current architecture.
|
||||
|
||||
### Files to Update
|
||||
**None** - No changes needed
|
||||
|
||||
### Maintenance
|
||||
- Keep `/sites/` folder
|
||||
- Keep `igny8_sites` container running
|
||||
- Keep port 8024 accessible
|
||||
- Maintain separate Docker image
|
||||
|
||||
### Impact
|
||||
- ✅ No migration risk
|
||||
- ✅ Performance isolation
|
||||
- ✅ Independent scaling
|
||||
- ❌ More containers to manage
|
||||
- ❌ More complex deployment
|
||||
|
||||
### Rollback Difficulty
|
||||
🟢 **EASY** - Already the current state
|
||||
|
||||
---
|
||||
|
||||
## Comparison Matrix
|
||||
|
||||
| Aspect | Option A: Full Removal | Option B: Merge to Frontend | Option C: Keep Separate |
|
||||
|--------|----------------------|---------------------------|------------------------|
|
||||
| **Containers** | 1 (frontend only) | 2 (frontend + backend) | 3 (frontend + sites + backend) |
|
||||
| **Site Builder** | ❌ Removed | ✅ In frontend | ✅ In sites container |
|
||||
| **Site Renderer** | ❌ Removed | ✅ In frontend | ✅ In sites container |
|
||||
| **Backend API** | ❌ Removed | ✅ Kept | ✅ Kept |
|
||||
| **Database** | ❌ Dropped | ✅ Kept | ✅ Kept |
|
||||
| **Ports** | 8021 only | 8021 only | 8021, 8024 |
|
||||
| **Deployment** | Simple | Simple | Complex |
|
||||
| **Rollback** | Hard | Medium | Easy |
|
||||
| **Performance** | N/A | Good | Best (isolated) |
|
||||
| **Complexity** | Low | Medium | High |
|
||||
| **Recommended For** | Minimal setup | Most users | High-traffic sites |
|
||||
|
||||
---
|
||||
|
||||
## Migration Difficulty
|
||||
|
||||
### Option A: Full Removal
|
||||
```
|
||||
Difficulty: ████████░░ 80%
|
||||
Time: 6-8 hours
|
||||
Risk: HIGH (data loss)
|
||||
Rollback: HARD (requires backup)
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
1. Backup database
|
||||
2. Remove frontend folders
|
||||
3. Remove backend modules
|
||||
4. Drop database tables
|
||||
5. Update URLs and settings
|
||||
6. Remove Docker services
|
||||
7. Update all documentation
|
||||
|
||||
### Option B: Merge to Frontend
|
||||
```
|
||||
Difficulty: ██████░░░░ 60%
|
||||
Time: 5-6 hours
|
||||
Risk: MEDIUM (UI changes)
|
||||
Rollback: MEDIUM (restore backup)
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
1. Backup files
|
||||
2. Copy frontend files
|
||||
3. Update routes
|
||||
4. Update Docker config
|
||||
5. Test functionality
|
||||
6. Remove old container
|
||||
7. Update documentation
|
||||
|
||||
### Option C: Keep Separate
|
||||
```
|
||||
Difficulty: ░░░░░░░░░░ 0%
|
||||
Time: 0 hours
|
||||
Risk: NONE
|
||||
Rollback: N/A (no changes)
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
1. None - keep current setup
|
||||
|
||||
---
|
||||
|
||||
## Recommendation by Use Case
|
||||
|
||||
### For Development/Testing
|
||||
**→ Option B: Merge to Frontend**
|
||||
- Simpler setup
|
||||
- Easier debugging
|
||||
- Fewer containers
|
||||
- Faster iteration
|
||||
|
||||
### For Small Production (<100 sites)
|
||||
**→ Option B: Merge to Frontend**
|
||||
- Good performance
|
||||
- Simpler deployment
|
||||
- Lower resource usage
|
||||
- Easier maintenance
|
||||
|
||||
### For Large Production (>100 sites, high traffic)
|
||||
**→ Option C: Keep Separate**
|
||||
- Performance isolation
|
||||
- Independent scaling
|
||||
- Better resource management
|
||||
- Fault isolation
|
||||
|
||||
### For Minimal Setup (No site features needed)
|
||||
**→ Option A: Full Removal**
|
||||
- Smallest footprint
|
||||
- Lowest complexity
|
||||
- Minimal maintenance
|
||||
- Only if truly not needed
|
||||
|
||||
---
|
||||
|
||||
## Red Flags - Don't Remove If:
|
||||
|
||||
🚫 **Don't choose Option A if:**
|
||||
- You have existing site blueprints in database
|
||||
- You're actively using site builder
|
||||
- You publish to sites renderer (not just WordPress)
|
||||
- You're unsure if you'll need it later
|
||||
|
||||
🚫 **Don't choose Option B if:**
|
||||
- You have high-traffic public sites (>10k visits/day)
|
||||
- You need to scale sites independently
|
||||
- You have strict performance requirements
|
||||
- You want to deploy sites on different infrastructure
|
||||
|
||||
🚫 **Don't choose Option C if:**
|
||||
- You're struggling with too many containers
|
||||
- You want simpler deployment
|
||||
- You have low-traffic sites
|
||||
- You value simplicity over isolation
|
||||
|
||||
---
|
||||
|
||||
## Safe Path Forward
|
||||
|
||||
### Recommended Approach
|
||||
|
||||
1. **Start with Option C** (Keep separate) ← You are here
|
||||
2. **Evaluate for 30 days**
|
||||
- Monitor site traffic
|
||||
- Check resource usage
|
||||
- Assess deployment complexity
|
||||
3. **If low traffic/simple needs** → **Move to Option B** (Merge)
|
||||
4. **If high traffic/complex needs** → **Stay with Option C** (Keep separate)
|
||||
5. **If features unused** → **Consider Option A** (Remove)
|
||||
|
||||
### Safe Testing Strategy
|
||||
|
||||
```bash
|
||||
# 1. Test Option B in parallel (non-destructive)
|
||||
# Keep sites container running on port 8024
|
||||
# Deploy merged version on port 8021
|
||||
# Compare functionality side-by-side
|
||||
|
||||
# 2. If Option B works well
|
||||
# Switch traffic gradually
|
||||
# Monitor for issues
|
||||
|
||||
# 3. After 30 days of stability
|
||||
# Remove sites container (Option B complete)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Decision Criteria
|
||||
|
||||
### Choose Option A (Full Removal) If:
|
||||
- [ ] No existing site blueprints in database
|
||||
- [ ] No plans to use site builder ever
|
||||
- [ ] Only using WordPress publishing (direct)
|
||||
- [ ] Want absolute minimal setup
|
||||
|
||||
### Choose Option B (Merge to Frontend) If:
|
||||
- [x] Need site builder features
|
||||
- [x] Have low-medium traffic sites
|
||||
- [x] Want simpler deployment
|
||||
- [x] Prefer fewer containers
|
||||
- [x] Sites are mostly internal
|
||||
|
||||
### Choose Option C (Keep Separate) If:
|
||||
- [ ] High-traffic public sites
|
||||
- [ ] Need performance isolation
|
||||
- [ ] Want independent scaling
|
||||
- [ ] Current setup works well
|
||||
- [ ] Have complex requirements
|
||||
|
||||
---
|
||||
|
||||
## Next Steps Based on Choice
|
||||
|
||||
### If Choosing Option A:
|
||||
1. Read [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md) Section: "Full Removal"
|
||||
2. Backup database completely
|
||||
3. Export any site data you want to keep
|
||||
4. Follow removal checklist
|
||||
5. Test thoroughly
|
||||
|
||||
### If Choosing Option B:
|
||||
1. Read [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md) - Full guide
|
||||
2. Read [SITES_REMOVAL_QUICK_REFERENCE.md](./SITES_REMOVAL_QUICK_REFERENCE.md) - Quick commands
|
||||
3. Backup files and database
|
||||
4. Follow Phase 1-7 in guide
|
||||
5. Test thoroughly before cleanup
|
||||
|
||||
### If Choosing Option C:
|
||||
1. No action needed
|
||||
2. Continue with current setup
|
||||
3. Maintain both containers
|
||||
4. Keep documentation updated
|
||||
|
||||
---
|
||||
|
||||
## Support Documentation
|
||||
|
||||
- **Full Removal & Integration Guide:** [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md)
|
||||
- **Quick Reference:** [SITES_REMOVAL_QUICK_REFERENCE.md](./SITES_REMOVAL_QUICK_REFERENCE.md)
|
||||
- **System Architecture:** [MASTER_REFERENCE.md](./MASTER_REFERENCE.md)
|
||||
- **API Reference:** [API-COMPLETE-REFERENCE.md](./API-COMPLETE-REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
**Recommendation:** Start with **Option C** (current state), evaluate needs, then move to **Option B** if appropriate.
|
||||
|
||||
**Last Updated:** November 29, 2025
|
||||
@@ -1,743 +0,0 @@
|
||||
# Sites & Site Builder Removal Guide
|
||||
|
||||
**Version:** 1.0
|
||||
**Date:** November 29, 2025
|
||||
**Purpose:** Complete guide to remove separate sites/site-builder containers and integrate functionality into main frontend app
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document provides a **safe, step-by-step process** to:
|
||||
1. Remove the `/sites/` container and folder
|
||||
2. Remove the `/site-builder/` folder (already empty/deprecated)
|
||||
3. Integrate Sites Renderer and Site Builder features into the main `/frontend/` application
|
||||
4. Update all affected components, configurations, and documentation
|
||||
|
||||
**Current State:**
|
||||
- 3 separate containers: `igny8_frontend`, `igny8_sites`, `igny8_marketing_dev`
|
||||
- Site Builder UI in separate `/sites/` container (port 8024)
|
||||
- Sites Renderer in separate `/sites/` container (port 8024)
|
||||
|
||||
**Target State:**
|
||||
- 2 containers: `igny8_frontend`, `igny8_marketing_dev`
|
||||
- Site Builder UI integrated into main frontend
|
||||
- Sites Renderer integrated into main frontend
|
||||
- Single unified application on port 8021
|
||||
|
||||
---
|
||||
|
||||
## Impact Analysis
|
||||
|
||||
### Features That Will Be Affected
|
||||
|
||||
#### 1. **Site Blueprint Management** (Site Builder)
|
||||
**Current Location:** `/sites/src/builder/`
|
||||
**Current Routes:** `/builder/*` (separate container)
|
||||
**Functionality:**
|
||||
- Site structure wizard
|
||||
- Blueprint creation and management
|
||||
- Preview canvas for site layouts
|
||||
- Blueprint history dashboard
|
||||
|
||||
**Backend Dependencies:**
|
||||
- API: `/api/v1/site-builder/blueprints/`
|
||||
- Module: `backend/igny8_core/modules/site_builder/`
|
||||
- Business Logic: `backend/igny8_core/business/site_building/`
|
||||
|
||||
**Impact:** Medium - Needs route integration into main app
|
||||
|
||||
---
|
||||
|
||||
#### 2. **Sites Renderer** (Public Site Viewing)
|
||||
**Current Location:** `/sites/src/pages/SiteRenderer.tsx`
|
||||
**Current Routes:** `/:siteSlug/:pageSlug?` (separate container)
|
||||
**Functionality:**
|
||||
- Loads site definitions from `/data/app/sites-data/`
|
||||
- Renders published sites for public viewing
|
||||
- No authentication required
|
||||
|
||||
**Backend Dependencies:**
|
||||
- API: `/api/v1/publisher/sites/{site_id}/definition/`
|
||||
- Service: `backend/igny8_core/business/publishing/services/adapters/sites_renderer_adapter.py`
|
||||
- Data: `/data/app/sites-data/clients/{site_id}/v{version}/`
|
||||
|
||||
**Impact:** High - Public-facing feature, needs careful route handling
|
||||
|
||||
---
|
||||
|
||||
#### 3. **Backend Modules** (Keep These)
|
||||
**Modules to Keep:**
|
||||
```
|
||||
backend/igny8_core/
|
||||
├── modules/
|
||||
│ ├── site_builder/ ✅ KEEP (API endpoints)
|
||||
│ └── publisher/ ✅ KEEP (publishing logic)
|
||||
└── business/
|
||||
├── site_building/ ✅ KEEP (business logic)
|
||||
└── publishing/ ✅ KEEP (renderer adapter)
|
||||
```
|
||||
|
||||
**Rationale:** Backend functionality is used by the main frontend app, just changing the UI container.
|
||||
|
||||
---
|
||||
|
||||
## Removal & Integration Plan
|
||||
|
||||
### Phase 1: Preparation & Backup
|
||||
|
||||
#### Step 1.1: Create Backup
|
||||
```bash
|
||||
# Backup current state
|
||||
cd /data/app/igny8
|
||||
tar -czf backup-sites-$(date +%Y%m%d-%H%M%S).tar.gz sites/ site-builder/
|
||||
|
||||
# Backup docker-compose
|
||||
cp docker-compose.app.yml docker-compose.app.yml.backup
|
||||
|
||||
# Verify backup
|
||||
ls -lh backup-sites-*.tar.gz
|
||||
```
|
||||
|
||||
#### Step 1.2: Document Current Routes
|
||||
```bash
|
||||
# Document current running containers
|
||||
docker ps | grep igny8 > current-containers.txt
|
||||
|
||||
# Test current site builder access
|
||||
curl -I http://localhost:8024/builder/
|
||||
|
||||
# Test current sites renderer
|
||||
curl -I http://localhost:8024/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Frontend Integration
|
||||
|
||||
#### Step 2.1: Copy Site Builder Components to Frontend
|
||||
|
||||
**Source:** `/sites/src/builder/`
|
||||
**Destination:** `/frontend/src/pages/Sites/`
|
||||
|
||||
```bash
|
||||
cd /data/app/igny8
|
||||
|
||||
# Create target directory
|
||||
mkdir -p frontend/src/pages/Sites/Builder
|
||||
|
||||
# Copy builder components
|
||||
cp -r sites/src/builder/pages/* frontend/src/pages/Sites/Builder/
|
||||
cp -r sites/src/builder/components/* frontend/src/components/sites/builder/
|
||||
|
||||
# Copy shared types if needed
|
||||
cp sites/src/types/index.ts frontend/src/types/siteBuilder.types.ts
|
||||
```
|
||||
|
||||
**Files to Copy:**
|
||||
```
|
||||
sites/src/builder/
|
||||
├── pages/
|
||||
│ ├── wizard/
|
||||
│ │ └── WizardPage.tsx → frontend/src/pages/Sites/Builder/Wizard.tsx
|
||||
│ ├── preview/
|
||||
│ │ └── PreviewCanvas.tsx → frontend/src/pages/Sites/Builder/Preview.tsx
|
||||
│ └── dashboard/
|
||||
│ └── SiteDashboard.tsx → frontend/src/pages/Sites/Builder/Dashboard.tsx
|
||||
└── components/
|
||||
└── layout/
|
||||
└── BuilderLayout.tsx → frontend/src/components/sites/BuilderLayout.tsx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 2.2: Copy Sites Renderer to Frontend
|
||||
|
||||
**Source:** `/sites/src/pages/SiteRenderer.tsx`
|
||||
**Destination:** `/frontend/src/pages/Sites/`
|
||||
|
||||
```bash
|
||||
# Copy renderer components
|
||||
cp sites/src/pages/SiteRenderer.tsx frontend/src/pages/Sites/PublicSiteRenderer.tsx
|
||||
cp sites/src/loaders/loadSiteDefinition.ts frontend/src/services/siteRenderer.api.ts
|
||||
cp -r sites/src/utils/* frontend/src/utils/siteRenderer/
|
||||
```
|
||||
|
||||
**Files to Copy:**
|
||||
```
|
||||
sites/src/
|
||||
├── pages/
|
||||
│ └── SiteRenderer.tsx → frontend/src/pages/Sites/PublicSiteRenderer.tsx
|
||||
├── loaders/
|
||||
│ └── loadSiteDefinition.ts → frontend/src/services/siteRenderer.api.ts
|
||||
└── utils/
|
||||
├── layoutRenderer.tsx → frontend/src/utils/siteRenderer/layoutRenderer.tsx
|
||||
├── pageTypeRenderer.tsx → frontend/src/utils/siteRenderer/pageTypeRenderer.tsx
|
||||
└── templateEngine.tsx → frontend/src/utils/siteRenderer/templateEngine.tsx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 2.3: Update Frontend Routes
|
||||
|
||||
**File:** `/frontend/src/App.tsx`
|
||||
|
||||
**Add these imports:**
|
||||
```tsx
|
||||
// Site Builder pages
|
||||
const SiteBuilderWizard = lazy(() => import("./pages/Sites/Builder/Wizard"));
|
||||
const SiteBuilderPreview = lazy(() => import("./pages/Sites/Builder/Preview"));
|
||||
const SiteBuilderDashboard = lazy(() => import("./pages/Sites/Builder/Dashboard"));
|
||||
|
||||
// Public Sites Renderer
|
||||
const PublicSiteRenderer = lazy(() => import("./pages/Sites/PublicSiteRenderer"));
|
||||
```
|
||||
|
||||
**Add these routes:**
|
||||
```tsx
|
||||
{/* Site Builder Routes - Protected */}
|
||||
<Route
|
||||
path="/sites/builder"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<ModuleGuard module="site_builder">
|
||||
<SiteBuilderWizard />
|
||||
</ModuleGuard>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/sites/builder/preview"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<ModuleGuard module="site_builder">
|
||||
<SiteBuilderPreview />
|
||||
</ModuleGuard>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/sites/builder/dashboard"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<ModuleGuard module="site_builder">
|
||||
<SiteBuilderDashboard />
|
||||
</ModuleGuard>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* Public Sites Renderer - No Auth Required */}
|
||||
<Route path="/sites/view/:siteSlug/:pageSlug?" element={<PublicSiteRenderer />} />
|
||||
```
|
||||
|
||||
**Note:** Public renderer routes changed from `/:siteSlug/*` to `/sites/view/:siteSlug/*` to avoid route conflicts.
|
||||
|
||||
---
|
||||
|
||||
#### Step 2.4: Update API Client for Sites Data
|
||||
|
||||
**File:** `/frontend/src/services/siteRenderer.api.ts`
|
||||
|
||||
**Update the API URL resolution:**
|
||||
```typescript
|
||||
function getApiBaseUrl(): string {
|
||||
// Use environment variable
|
||||
const envUrl = import.meta.env.VITE_API_URL || import.meta.env.VITE_BACKEND_URL;
|
||||
if (envUrl) {
|
||||
return envUrl.endsWith('/api') ? envUrl : `${envUrl}/api`;
|
||||
}
|
||||
|
||||
// Auto-detect based on current origin
|
||||
if (typeof window !== 'undefined') {
|
||||
const origin = window.location.origin;
|
||||
|
||||
// If accessing via IP, use backend port 8011
|
||||
if (/^\d+\.\d+\.\d+\.\d+/.test(origin) || origin.includes('localhost')) {
|
||||
return origin.replace(':8021', ':8011') + '/api';
|
||||
}
|
||||
}
|
||||
|
||||
// Production: use subdomain
|
||||
return 'https://api.igny8.com/api';
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 2.5: Update Navigation Menu
|
||||
|
||||
**File:** `/frontend/src/components/sidebar/AppSidebar.tsx` or navigation component
|
||||
|
||||
**Add Site Builder menu item:**
|
||||
```tsx
|
||||
{
|
||||
title: "Site Builder",
|
||||
icon: <LayoutGrid className="h-5 w-5" />,
|
||||
items: [
|
||||
{ title: "New Blueprint", path: "/sites/builder" },
|
||||
{ title: "Preview", path: "/sites/builder/preview" },
|
||||
{ title: "History", path: "/sites/builder/dashboard" },
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Docker Configuration Updates
|
||||
|
||||
#### Step 3.1: Update docker-compose.app.yml
|
||||
|
||||
**File:** `/docker-compose.app.yml`
|
||||
|
||||
**Remove the igny8_sites service:**
|
||||
```yaml
|
||||
# REMOVE THIS ENTIRE SERVICE:
|
||||
# igny8_sites:
|
||||
# image: igny8-sites-dev:latest
|
||||
# container_name: igny8_sites
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "0.0.0.0:8024:5176"
|
||||
# environment:
|
||||
# VITE_API_URL: "https://api.igny8.com/api"
|
||||
# SITES_DATA_PATH: "/sites"
|
||||
# volumes:
|
||||
# - /data/app/igny8/sites:/app:rw
|
||||
# - /data/app/sites-data:/sites:ro
|
||||
# - /data/app/igny8/frontend:/frontend:ro
|
||||
# networks: [igny8_net]
|
||||
```
|
||||
|
||||
**Update igny8_frontend service to access sites-data:**
|
||||
```yaml
|
||||
igny8_frontend:
|
||||
image: igny8-frontend-dev:latest
|
||||
container_name: igny8_frontend
|
||||
restart: always
|
||||
ports:
|
||||
- "0.0.0.0:8021:5173"
|
||||
environment:
|
||||
VITE_BACKEND_URL: "https://api.igny8.com/api"
|
||||
SITES_DATA_PATH: "/sites" # ADD THIS
|
||||
volumes:
|
||||
- /data/app/igny8/frontend:/app:rw
|
||||
- /data/app/sites-data:/sites:ro # ADD THIS - Read-only access to sites data
|
||||
depends_on:
|
||||
igny8_backend:
|
||||
condition: service_healthy
|
||||
networks: [igny8_net]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 3.2: Update Vite Configuration
|
||||
|
||||
**File:** `/frontend/vite.config.ts`
|
||||
|
||||
**Add environment variable for sites data path:**
|
||||
```typescript
|
||||
export default defineConfig({
|
||||
// ... existing config
|
||||
define: {
|
||||
'import.meta.env.SITES_DATA_PATH': JSON.stringify(
|
||||
process.env.SITES_DATA_PATH || '/sites'
|
||||
),
|
||||
},
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Backend Updates (Minor)
|
||||
|
||||
#### Step 4.1: Update CORS Settings (if needed)
|
||||
|
||||
**File:** `/backend/igny8_core/settings.py`
|
||||
|
||||
**Verify CORS allows frontend port:**
|
||||
```python
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
'http://localhost:5173', # Frontend dev server
|
||||
'http://localhost:8021', # Frontend external port
|
||||
'https://app.igny8.com',
|
||||
# Remove: 'http://localhost:8024', # Old sites container
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 4.2: Update Site Definition API (Optional Enhancement)
|
||||
|
||||
**File:** `/backend/igny8_core/modules/publisher/views.py`
|
||||
|
||||
**No changes required** - API already works, just being called from different container.
|
||||
|
||||
**Optional:** Add CORS header for public site renderer if needed:
|
||||
```python
|
||||
from rest_framework.decorators import api_view, permission_classes
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([AllowAny]) # Public endpoint
|
||||
def get_site_definition(request, site_id):
|
||||
# ... existing code
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Testing & Verification
|
||||
|
||||
#### Step 5.1: Build Updated Frontend
|
||||
```bash
|
||||
cd /data/app/igny8/frontend
|
||||
|
||||
# Install any new dependencies (if added)
|
||||
npm install
|
||||
|
||||
# Build to verify no errors
|
||||
npm run build
|
||||
|
||||
# Rebuild Docker image
|
||||
cd /data/app/igny8/frontend
|
||||
docker build -t igny8-frontend-dev:latest -f Dockerfile.dev .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 5.2: Stop Old Container
|
||||
```bash
|
||||
# Stop and remove sites container
|
||||
docker stop igny8_sites
|
||||
docker rm igny8_sites
|
||||
|
||||
# Verify it's stopped
|
||||
docker ps | grep sites
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 5.3: Start Updated Stack
|
||||
```bash
|
||||
cd /data/app/igny8
|
||||
|
||||
# Start with updated docker-compose
|
||||
docker compose -f docker-compose.app.yml up -d igny8_frontend
|
||||
|
||||
# Check logs
|
||||
docker logs -f igny8_frontend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 5.4: Test Functionality
|
||||
|
||||
**Test Site Builder:**
|
||||
```bash
|
||||
# Test builder routes (should require auth)
|
||||
curl -I http://localhost:8021/sites/builder
|
||||
|
||||
# Test in browser:
|
||||
# http://localhost:8021/sites/builder (wizard)
|
||||
# http://localhost:8021/sites/builder/preview
|
||||
# http://localhost:8021/sites/builder/dashboard
|
||||
```
|
||||
|
||||
**Test Sites Renderer:**
|
||||
```bash
|
||||
# Test public site renderer
|
||||
curl -I http://localhost:8021/sites/view/test-site
|
||||
|
||||
# Test in browser:
|
||||
# http://localhost:8021/sites/view/{siteSlug}
|
||||
# http://localhost:8021/sites/view/{siteSlug}/{pageSlug}
|
||||
```
|
||||
|
||||
**Test Existing API:**
|
||||
```bash
|
||||
# Verify site builder API still works
|
||||
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
http://localhost:8011/api/v1/site-builder/blueprints/
|
||||
|
||||
# Verify site definition API
|
||||
curl http://localhost:8011/api/v1/publisher/sites/1/definition/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 6: Cleanup
|
||||
|
||||
#### Step 6.1: Remove Folders (After Verification)
|
||||
|
||||
**Only after confirming everything works:**
|
||||
```bash
|
||||
cd /data/app/igny8
|
||||
|
||||
# Remove sites folder
|
||||
rm -rf sites/
|
||||
|
||||
# Remove site-builder folder (already empty)
|
||||
rm -rf site-builder/
|
||||
|
||||
# Remove empty frontend module
|
||||
rm -rf frontend/src/modules/siteBuilder/
|
||||
|
||||
# Verify removal
|
||||
ls -la | grep -E "site-builder|sites"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 6.2: Remove Docker Image (Optional)
|
||||
```bash
|
||||
# Remove unused sites image
|
||||
docker rmi igny8-sites-dev:latest
|
||||
|
||||
# Verify
|
||||
docker images | grep sites
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 6.3: Clean Up Build Instructions
|
||||
|
||||
**File:** `/docker-compose.app.yml` (comments at top)
|
||||
|
||||
**Remove this line:**
|
||||
```yaml
|
||||
# Remove:
|
||||
# cd /data/app/igny8/sites && docker build -t igny8-sites-dev:latest -f Dockerfile.dev .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 7: Update Documentation
|
||||
|
||||
#### Step 7.1: Update Files List
|
||||
|
||||
**Files to update:**
|
||||
|
||||
1. **README.md**
|
||||
- Remove references to `/sites/` container
|
||||
- Update port mapping (remove 8024)
|
||||
- Update build instructions
|
||||
|
||||
2. **CHANGELOG.md**
|
||||
- Add entry: "Merged Sites & Site Builder into main frontend app"
|
||||
|
||||
3. **docs/MASTER_REFERENCE.md**
|
||||
- Update architecture diagram
|
||||
- Remove igny8_sites container reference
|
||||
- Update route documentation
|
||||
|
||||
4. **docs/API-COMPLETE-REFERENCE.md**
|
||||
- Update base URLs if needed
|
||||
- Verify endpoint documentation
|
||||
|
||||
---
|
||||
|
||||
#### Step 7.2: Update Architecture Diagram
|
||||
|
||||
**In MASTER_REFERENCE.md, update:**
|
||||
|
||||
**OLD:**
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||||
│ Frontend (8021) │ │ Sites (8024) │ │ Backend (8011) │
|
||||
└──────────────────┘ └──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
**NEW:**
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ Frontend (8021) │ │ Backend (8011) │
|
||||
│ - Main App │ │ - Django API │
|
||||
│ - Site Builder │ │ - Celery │
|
||||
│ - Site Renderer │ │ │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files & Folders Impact Summary
|
||||
|
||||
### Files to Modify
|
||||
|
||||
| File | Action | Reason |
|
||||
|------|--------|--------|
|
||||
| `/frontend/src/App.tsx` | **UPDATE** | Add site builder and renderer routes |
|
||||
| `/frontend/src/services/siteRenderer.api.ts` | **CREATE** | Site renderer API client |
|
||||
| `/frontend/src/pages/Sites/Builder/` | **CREATE** | Copy from sites/src/builder/ |
|
||||
| `/frontend/src/components/sites/builder/` | **CREATE** | Builder components |
|
||||
| `/frontend/vite.config.ts` | **UPDATE** | Add SITES_DATA_PATH env var |
|
||||
| `/docker-compose.app.yml` | **UPDATE** | Remove igny8_sites service |
|
||||
| `/backend/igny8_core/settings.py` | **VERIFY** | CORS settings (minor) |
|
||||
| `/README.md` | **UPDATE** | Architecture docs |
|
||||
| `/docs/MASTER_REFERENCE.md` | **UPDATE** | Remove sites container refs |
|
||||
|
||||
---
|
||||
|
||||
### Files to Delete (After Verification)
|
||||
|
||||
| File/Folder | Safe to Delete | Notes |
|
||||
|-------------|----------------|-------|
|
||||
| `/sites/` | ✅ YES | After copying to frontend |
|
||||
| `/site-builder/` | ✅ YES | Already empty |
|
||||
| `/frontend/src/modules/siteBuilder/` | ✅ YES | Empty folders |
|
||||
| `docker-compose.app.yml.backup` | ✅ YES | After successful migration |
|
||||
| `backup-sites-*.tar.gz` | ⚠️ KEEP | Keep for 30 days as rollback |
|
||||
|
||||
---
|
||||
|
||||
### Backend Files - NO CHANGES NEEDED
|
||||
|
||||
**These stay exactly as they are:**
|
||||
```
|
||||
backend/igny8_core/
|
||||
├── modules/
|
||||
│ ├── site_builder/ ✅ KEEP - No changes
|
||||
│ └── publisher/ ✅ KEEP - No changes
|
||||
├── business/
|
||||
│ ├── site_building/ ✅ KEEP - No changes
|
||||
│ └── publishing/ ✅ KEEP - No changes
|
||||
└── api/
|
||||
└── wordpress_publishing.py ✅ KEEP - No changes
|
||||
```
|
||||
|
||||
**Rationale:** Backend APIs remain unchanged; only the frontend UI container changes.
|
||||
|
||||
---
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues occur, rollback is simple:
|
||||
|
||||
### Option 1: Quick Rollback (Docker)
|
||||
```bash
|
||||
# Restore backup docker-compose
|
||||
cp docker-compose.app.yml.backup docker-compose.app.yml
|
||||
|
||||
# Restart sites container
|
||||
docker compose -f docker-compose.app.yml up -d igny8_sites
|
||||
|
||||
# Verify
|
||||
docker ps | grep sites
|
||||
curl -I http://localhost:8024/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Full Rollback (Restore Files)
|
||||
```bash
|
||||
# Extract backup
|
||||
cd /data/app/igny8
|
||||
tar -xzf backup-sites-YYYYMMDD-HHMMSS.tar.gz
|
||||
|
||||
# Rebuild image
|
||||
cd sites
|
||||
docker build -t igny8-sites-dev:latest -f Dockerfile.dev .
|
||||
|
||||
# Restart
|
||||
docker compose -f docker-compose.app.yml up -d igny8_sites
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Checklist
|
||||
|
||||
**Pre-Migration:**
|
||||
- [ ] Backup `/sites/` folder
|
||||
- [ ] Backup `/docker-compose.app.yml`
|
||||
- [ ] Document current container ports
|
||||
- [ ] Test current site builder functionality
|
||||
- [ ] Test current sites renderer functionality
|
||||
|
||||
**Migration Steps:**
|
||||
- [ ] Copy site builder components to `/frontend/src/pages/Sites/Builder/`
|
||||
- [ ] Copy sites renderer to `/frontend/src/pages/Sites/PublicSiteRenderer.tsx`
|
||||
- [ ] Copy utilities to `/frontend/src/utils/siteRenderer/`
|
||||
- [ ] Update `/frontend/src/App.tsx` with new routes
|
||||
- [ ] Create `/frontend/src/services/siteRenderer.api.ts`
|
||||
- [ ] Update `/frontend/vite.config.ts`
|
||||
- [ ] Update `/docker-compose.app.yml` (remove igny8_sites, update igny8_frontend)
|
||||
- [ ] Rebuild frontend Docker image
|
||||
- [ ] Stop igny8_sites container
|
||||
- [ ] Start updated igny8_frontend container
|
||||
|
||||
**Testing:**
|
||||
- [ ] Test site builder wizard at `/sites/builder`
|
||||
- [ ] Test site builder preview at `/sites/builder/preview`
|
||||
- [ ] Test site builder dashboard at `/sites/builder/dashboard`
|
||||
- [ ] Test public site renderer at `/sites/view/{siteSlug}`
|
||||
- [ ] Verify API calls work from frontend
|
||||
- [ ] Check browser console for errors
|
||||
- [ ] Test with authenticated user
|
||||
- [ ] Test without authentication (public renderer)
|
||||
|
||||
**Post-Migration:**
|
||||
- [ ] Verify all tests pass
|
||||
- [ ] Update documentation (README, MASTER_REFERENCE)
|
||||
- [ ] Remove `/sites/` folder
|
||||
- [ ] Remove `/site-builder/` folder
|
||||
- [ ] Remove empty `/frontend/src/modules/siteBuilder/`
|
||||
- [ ] Remove Docker image `igny8-sites-dev:latest`
|
||||
- [ ] Keep backup for 30 days
|
||||
- [ ] Update portable package documentation
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
### Q: Will this break existing site blueprints?
|
||||
**A:** No. Backend database and APIs remain unchanged. Only the UI container changes.
|
||||
|
||||
### Q: What about published sites in `/data/app/sites-data/`?
|
||||
**A:** They remain accessible. The frontend will mount `/sites-data` and load from there.
|
||||
|
||||
### Q: Do I need to update WordPress integration?
|
||||
**A:** No. WordPress talks to backend API, which doesn't change.
|
||||
|
||||
### Q: What if I want to keep sites as separate container?
|
||||
**A:** Keep current setup. This migration is optional for simplification.
|
||||
|
||||
### Q: Will public site URLs change?
|
||||
**A:** Yes, from `http://localhost:8024/:siteSlug` to `http://localhost:8021/sites/view/:siteSlug`. Update any hardcoded links.
|
||||
|
||||
### Q: Can I run both containers during transition?
|
||||
**A:** Yes, for testing. Run sites on 8024 and updated frontend on 8021, compare functionality.
|
||||
|
||||
---
|
||||
|
||||
## Support & Troubleshooting
|
||||
|
||||
### Issue: Routes not working after migration
|
||||
**Solution:** Check route order in `App.tsx`. Public renderer routes should be after protected routes.
|
||||
|
||||
### Issue: API calls failing
|
||||
**Solution:** Verify `VITE_BACKEND_URL` in environment and check CORS settings.
|
||||
|
||||
### Issue: Sites data not loading
|
||||
**Solution:** Verify `/data/app/sites-data` is mounted in docker-compose frontend service.
|
||||
|
||||
### Issue: Build errors
|
||||
**Solution:** Run `npm install` to ensure dependencies match between sites and frontend.
|
||||
|
||||
---
|
||||
|
||||
## Timeline Estimate
|
||||
|
||||
| Phase | Time | Complexity |
|
||||
|-------|------|------------|
|
||||
| Phase 1: Preparation | 30 min | Low |
|
||||
| Phase 2: Frontend Integration | 2-3 hours | Medium |
|
||||
| Phase 3: Docker Updates | 30 min | Low |
|
||||
| Phase 4: Backend Updates | 15 min | Low |
|
||||
| Phase 5: Testing | 1-2 hours | Medium |
|
||||
| Phase 6: Cleanup | 15 min | Low |
|
||||
| Phase 7: Documentation | 1 hour | Low |
|
||||
| **Total** | **5-7 hours** | **Medium** |
|
||||
|
||||
---
|
||||
|
||||
**End of Document**
|
||||
@@ -1,329 +0,0 @@
|
||||
# Sites Container Removal - Quick Reference
|
||||
|
||||
**Version:** 1.0
|
||||
**Date:** November 29, 2025
|
||||
|
||||
> **Full Guide:** See [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md) for complete step-by-step instructions
|
||||
|
||||
---
|
||||
|
||||
## TL;DR - What Changes
|
||||
|
||||
### Current Architecture (3 Containers)
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Frontend │ │ Sites │ │ Backend │
|
||||
│ Port: 8021 │ │ Port: 8024 │ │ Port: 8011 │
|
||||
│ │ │ - Site Builder │ │ │
|
||||
│ │ │ - Renderer │ │ │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### Target Architecture (2 Containers)
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Frontend │ │ Backend │
|
||||
│ Port: 8021 │ │ Port: 8011 │
|
||||
│ - Main App │ │ │
|
||||
│ - Site Builder │ │ │
|
||||
│ - Renderer │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What Gets Removed
|
||||
|
||||
❌ **Deleted:**
|
||||
- `/sites/` folder (after copying to frontend)
|
||||
- `/site-builder/` folder (empty, deprecated)
|
||||
- `/frontend/src/modules/siteBuilder/` (empty)
|
||||
- `igny8_sites` Docker container
|
||||
- Port 8024
|
||||
|
||||
✅ **Kept:**
|
||||
- Backend `/api/v1/site-builder/` endpoints
|
||||
- Backend `/api/v1/publisher/` endpoints
|
||||
- Backend modules: `site_builder/`, `publisher/`
|
||||
- Backend business logic: `site_building/`, `publishing/`
|
||||
- Database tables (no changes)
|
||||
- `/data/app/sites-data/` directory
|
||||
|
||||
---
|
||||
|
||||
## What Gets Moved
|
||||
|
||||
### File Movements
|
||||
|
||||
| From (Sites Container) | To (Frontend) |
|
||||
|------------------------|---------------|
|
||||
| `sites/src/builder/pages/wizard/` | `frontend/src/pages/Sites/Builder/Wizard.tsx` |
|
||||
| `sites/src/builder/pages/preview/` | `frontend/src/pages/Sites/Builder/Preview.tsx` |
|
||||
| `sites/src/builder/pages/dashboard/` | `frontend/src/pages/Sites/Builder/Dashboard.tsx` |
|
||||
| `sites/src/builder/components/layout/` | `frontend/src/components/sites/BuilderLayout.tsx` |
|
||||
| `sites/src/pages/SiteRenderer.tsx` | `frontend/src/pages/Sites/PublicSiteRenderer.tsx` |
|
||||
| `sites/src/loaders/loadSiteDefinition.ts` | `frontend/src/services/siteRenderer.api.ts` |
|
||||
| `sites/src/utils/layoutRenderer.tsx` | `frontend/src/utils/siteRenderer/layoutRenderer.tsx` |
|
||||
| `sites/src/utils/pageTypeRenderer.tsx` | `frontend/src/utils/siteRenderer/pageTypeRenderer.tsx` |
|
||||
| `sites/src/utils/templateEngine.tsx` | `frontend/src/utils/siteRenderer/templateEngine.tsx` |
|
||||
|
||||
---
|
||||
|
||||
## Route Changes
|
||||
|
||||
### Site Builder Routes
|
||||
|
||||
| Old Route (Port 8024) | New Route (Port 8021) | Auth |
|
||||
|----------------------|----------------------|------|
|
||||
| `/builder` | `/sites/builder` | Required ✅ |
|
||||
| `/builder/preview` | `/sites/builder/preview` | Required ✅ |
|
||||
| `/builder/dashboard` | `/sites/builder/dashboard` | Required ✅ |
|
||||
|
||||
### Sites Renderer Routes
|
||||
|
||||
| Old Route (Port 8024) | New Route (Port 8021) | Auth |
|
||||
|----------------------|----------------------|------|
|
||||
| `/:siteSlug` | `/sites/view/:siteSlug` | None ❌ |
|
||||
| `/:siteSlug/:pageSlug` | `/sites/view/:siteSlug/:pageSlug` | None ❌ |
|
||||
|
||||
**⚠️ Important:** Public site URLs will change! Update any hardcoded links.
|
||||
|
||||
---
|
||||
|
||||
## Files to Update
|
||||
|
||||
### Critical Files (Must Update)
|
||||
|
||||
1. **`/frontend/src/App.tsx`**
|
||||
- Add site builder routes
|
||||
- Add public renderer routes
|
||||
- Add lazy imports
|
||||
|
||||
2. **`/docker-compose.app.yml`**
|
||||
- Remove `igny8_sites` service
|
||||
- Add `/sites-data` volume mount to `igny8_frontend`
|
||||
- Add `SITES_DATA_PATH` env var to `igny8_frontend`
|
||||
|
||||
3. **`/frontend/vite.config.ts`**
|
||||
- Add `SITES_DATA_PATH` environment variable
|
||||
|
||||
### Optional Files (Verify/Update)
|
||||
|
||||
4. **`/backend/igny8_core/settings.py`**
|
||||
- Verify CORS settings (remove port 8024)
|
||||
|
||||
5. **`/frontend/src/components/sidebar/AppSidebar.tsx`**
|
||||
- Add site builder menu items
|
||||
|
||||
---
|
||||
|
||||
## Critical Commands
|
||||
|
||||
### 1. Backup First
|
||||
```bash
|
||||
cd /data/app/igny8
|
||||
tar -czf backup-sites-$(date +%Y%m%d-%H%M%S).tar.gz sites/ site-builder/
|
||||
cp docker-compose.app.yml docker-compose.app.yml.backup
|
||||
```
|
||||
|
||||
### 2. Copy Files
|
||||
```bash
|
||||
# Create directories
|
||||
mkdir -p frontend/src/pages/Sites/Builder
|
||||
mkdir -p frontend/src/components/sites/builder
|
||||
mkdir -p frontend/src/utils/siteRenderer
|
||||
|
||||
# Copy builder pages
|
||||
cp sites/src/builder/pages/wizard/WizardPage.tsx frontend/src/pages/Sites/Builder/Wizard.tsx
|
||||
cp sites/src/builder/pages/preview/PreviewCanvas.tsx frontend/src/pages/Sites/Builder/Preview.tsx
|
||||
cp sites/src/builder/pages/dashboard/SiteDashboard.tsx frontend/src/pages/Sites/Builder/Dashboard.tsx
|
||||
|
||||
# Copy renderer
|
||||
cp sites/src/pages/SiteRenderer.tsx frontend/src/pages/Sites/PublicSiteRenderer.tsx
|
||||
cp sites/src/loaders/loadSiteDefinition.ts frontend/src/services/siteRenderer.api.ts
|
||||
|
||||
# Copy utilities
|
||||
cp -r sites/src/utils/* frontend/src/utils/siteRenderer/
|
||||
```
|
||||
|
||||
### 3. Rebuild & Restart
|
||||
```bash
|
||||
# Rebuild frontend
|
||||
cd /data/app/igny8/frontend
|
||||
docker build -t igny8-frontend-dev:latest -f Dockerfile.dev .
|
||||
|
||||
# Stop sites container
|
||||
docker stop igny8_sites
|
||||
docker rm igny8_sites
|
||||
|
||||
# Start updated frontend
|
||||
cd /data/app/igny8
|
||||
docker compose -f docker-compose.app.yml up -d igny8_frontend
|
||||
```
|
||||
|
||||
### 4. Test
|
||||
```bash
|
||||
# Test site builder (requires auth)
|
||||
curl -I http://localhost:8021/sites/builder
|
||||
|
||||
# Test public renderer
|
||||
curl -I http://localhost:8021/sites/view/test-site
|
||||
|
||||
# Check logs
|
||||
docker logs -f igny8_frontend
|
||||
```
|
||||
|
||||
### 5. Cleanup (After Verification)
|
||||
```bash
|
||||
cd /data/app/igny8
|
||||
rm -rf sites/
|
||||
rm -rf site-builder/
|
||||
rm -rf frontend/src/modules/siteBuilder/
|
||||
docker rmi igny8-sites-dev:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact on Other Features
|
||||
|
||||
### ✅ No Impact (These Still Work)
|
||||
|
||||
| Feature | Why No Impact |
|
||||
|---------|---------------|
|
||||
| Planner module | Uses only backend API |
|
||||
| Writer module | Uses only backend API |
|
||||
| Linker module | Uses only backend API |
|
||||
| Optimizer module | Uses only backend API |
|
||||
| WordPress Publishing | Talks to backend, not affected |
|
||||
| Authentication | Frontend change only |
|
||||
| Billing/Credits | Backend only |
|
||||
| AI Content Generation | Backend/Celery only |
|
||||
|
||||
### ⚠️ Needs Update (After Migration)
|
||||
|
||||
| Feature | What to Update | Impact |
|
||||
|---------|----------------|--------|
|
||||
| Site Builder UI | Routes change to `/sites/builder/*` | Low - Internal only |
|
||||
| Public Site Links | URLs change to `/sites/view/{slug}` | Medium - External links |
|
||||
| Navigation Menu | Add site builder menu items | Low - UI only |
|
||||
| Tests | Update route tests if any | Low - Dev only |
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose Changes
|
||||
|
||||
### Before (3 Services)
|
||||
```yaml
|
||||
services:
|
||||
igny8_frontend: # Port 8021
|
||||
igny8_sites: # Port 8024 ❌ REMOVE THIS
|
||||
igny8_backend: # Port 8011
|
||||
igny8_celery_worker:
|
||||
igny8_celery_beat:
|
||||
```
|
||||
|
||||
### After (2 Services)
|
||||
```yaml
|
||||
services:
|
||||
igny8_frontend: # Port 8021 (updated)
|
||||
# igny8_sites removed
|
||||
igny8_backend: # Port 8011
|
||||
igny8_celery_worker:
|
||||
igny8_celery_beat:
|
||||
```
|
||||
|
||||
### Frontend Service Update
|
||||
```yaml
|
||||
igny8_frontend:
|
||||
image: igny8-frontend-dev:latest
|
||||
container_name: igny8_frontend
|
||||
ports:
|
||||
- "0.0.0.0:8021:5173"
|
||||
environment:
|
||||
VITE_BACKEND_URL: "https://api.igny8.com/api"
|
||||
SITES_DATA_PATH: "/sites" # ← ADD THIS
|
||||
volumes:
|
||||
- /data/app/igny8/frontend:/app:rw
|
||||
- /data/app/sites-data:/sites:ro # ← ADD THIS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
**Before Migration:**
|
||||
- [ ] Site builder wizard works at `http://localhost:8024/builder`
|
||||
- [ ] Site preview works at `http://localhost:8024/builder/preview`
|
||||
- [ ] Public site loads at `http://localhost:8024/{siteSlug}`
|
||||
|
||||
**After Migration:**
|
||||
- [ ] Site builder wizard works at `http://localhost:8021/sites/builder`
|
||||
- [ ] Site preview works at `http://localhost:8021/sites/builder/preview`
|
||||
- [ ] Blueprint dashboard works at `http://localhost:8021/sites/builder/dashboard`
|
||||
- [ ] Public site loads at `http://localhost:8021/sites/view/{siteSlug}`
|
||||
- [ ] Auth required for builder routes
|
||||
- [ ] No auth required for public renderer
|
||||
- [ ] API calls succeed from frontend
|
||||
- [ ] No console errors in browser
|
||||
- [ ] Sites data loads from `/data/app/sites-data/`
|
||||
|
||||
---
|
||||
|
||||
## Rollback (If Needed)
|
||||
|
||||
```bash
|
||||
# Quick rollback
|
||||
cp docker-compose.app.yml.backup docker-compose.app.yml
|
||||
docker compose -f docker-compose.app.yml up -d igny8_sites
|
||||
|
||||
# Full rollback
|
||||
cd /data/app/igny8
|
||||
tar -xzf backup-sites-YYYYMMDD-HHMMSS.tar.gz
|
||||
cd sites
|
||||
docker build -t igny8-sites-dev:latest -f Dockerfile.dev .
|
||||
docker compose -f docker-compose.app.yml up -d igny8_sites
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estimation
|
||||
|
||||
| Task | Time |
|
||||
|------|------|
|
||||
| Backup & Prep | 30 min |
|
||||
| Copy Files & Update Routes | 2 hours |
|
||||
| Docker Config Updates | 30 min |
|
||||
| Rebuild & Deploy | 30 min |
|
||||
| Testing | 1-2 hours |
|
||||
| Cleanup & Docs | 1 hour |
|
||||
| **Total** | **5-6 hours** |
|
||||
|
||||
---
|
||||
|
||||
## Decision Matrix
|
||||
|
||||
### Keep Separate Sites Container If:
|
||||
- ❌ You need different deployment schedules for sites vs main app
|
||||
- ❌ You want sites on different infrastructure
|
||||
- ❌ You have high traffic public sites (performance isolation)
|
||||
- ❌ You want to scale sites independently
|
||||
|
||||
### Merge Into Frontend If:
|
||||
- ✅ You want simpler deployment (fewer containers)
|
||||
- ✅ You want unified routing and authentication
|
||||
- ✅ Sites are internal/low traffic
|
||||
- ✅ You want easier development (single app)
|
||||
- ✅ You want to reduce port complexity
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
**Full Documentation:** [SITES_REMOVAL_GUIDE.md](./SITES_REMOVAL_GUIDE.md)
|
||||
**Architecture Reference:** [MASTER_REFERENCE.md](./MASTER_REFERENCE.md)
|
||||
**API Reference:** [API-COMPLETE-REFERENCE.md](./API-COMPLETE-REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** November 29, 2025
|
||||
**Status:** Ready for implementation
|
||||
Reference in New Issue
Block a user