# 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**