259 lines
15 KiB
Markdown
259 lines
15 KiB
Markdown
# Content Taxonomy Relationship Diagram
|
|
|
|
## Current Architecture (Simplified)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ IGNY8 Content System │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Multi-Tenant Hierarchy │
|
|
│ │
|
|
│ Account ──┬── Site ──┬── Sector ──┬── Keywords │
|
|
│ │ │ ├── Clusters │
|
|
│ │ │ ├── Ideas │
|
|
│ │ │ ├── Tasks │
|
|
│ │ │ ├── Content │
|
|
│ │ │ └── ContentTaxonomy │
|
|
│ │ └── Sector 2 │
|
|
│ └── Site 2 │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Planner → Writer → Publisher Workflow │
|
|
│ │
|
|
│ Phase 1-3: PLANNER │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
│ │ Keywords │ ──> │ Clusters │ ──> │ Ideas │ │
|
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
│ │ │ │ │
|
|
│ │ │ │ │
|
|
│ Phase 4: WRITER │
|
|
│ │ │ │ │
|
|
│ └─────────────────┴─────────────────┘ │
|
|
│ │ │
|
|
│ v │
|
|
│ ┌──────────┐ ┌──────────┐ │
|
|
│ │ Tasks │ ──> │ Content │ │
|
|
│ └──────────┘ └──────────┘ │
|
|
│ │ │
|
|
│ │ │
|
|
│ Phase 5: PUBLISHER │ │
|
|
│ v │
|
|
│ ┌─────────────┐ │
|
|
│ │ WordPress │ │
|
|
│ │ Shopify │ │
|
|
│ │ Sites │ │
|
|
│ └─────────────┘ │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Content ↔ Taxonomy Relationship (Many-to-Many) │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────┐
|
|
│ Content Model │
|
|
│─────────────────────────────────│
|
|
│ PK: id │
|
|
│ FK: site_id ──────┐ │
|
|
│ FK: sector_id │ │
|
|
│ FK: cluster_id │ │
|
|
│ │ │
|
|
│ title │ │
|
|
│ content_html │ │
|
|
│ word_count │ │
|
|
│ meta_title │ │
|
|
│ meta_description │ │
|
|
│ │ │
|
|
│ content_type │ │
|
|
│ content_structure │ │
|
|
│ │ │
|
|
│ external_id │ │
|
|
│ external_url │ │
|
|
│ sync_status │ │
|
|
│ │ │
|
|
│ source │ │
|
|
│ status │ │
|
|
└───────────┬───────┘ │
|
|
│ │
|
|
│ Many-to-Many │
|
|
│ (via ContentTaxonomyRelation)
|
|
│ │
|
|
v │
|
|
┌─────────────────────────────────┐│
|
|
│ ContentTaxonomyRelation Model ││
|
|
│─────────────────────────────────││
|
|
│ PK: id ││
|
|
│ FK: content_id ──────────────────┘
|
|
│ FK: taxonomy_id ────────────┐
|
|
│ │
|
|
│ created_at │
|
|
│ updated_at │
|
|
│ │
|
|
│ UNIQUE(content, taxonomy) │
|
|
└─────────────────────────────┘
|
|
│
|
|
│
|
|
v
|
|
┌─────────────────────────────────┐
|
|
│ ContentTaxonomy Model │
|
|
│─────────────────────────────────│
|
|
│ PK: id │
|
|
│ FK: site_id ─────┐ │
|
|
│ FK: sector_id │ │
|
|
│ │ │
|
|
│ name │ │
|
|
│ slug │ │
|
|
│ taxonomy_type │ ◄─── "category" or "tag"
|
|
│ description │ │
|
|
│ count │ │
|
|
│ │ │
|
|
│ WordPress Sync: │ │
|
|
│ external_taxonomy│ ◄─── "category", "post_tag"
|
|
│ external_id │ ◄─── WordPress term_id
|
|
│ │ │
|
|
│ metadata (JSON) │ │
|
|
└──────────────────┘ │
|
|
│ │
|
|
│ │
|
|
UNIQUE(site, slug, taxonomy_type)│
|
|
UNIQUE(site, external_id, external_taxonomy)
|
|
│ │
|
|
└──────────────┘
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Usage Example │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
# Get all categories for a content piece
|
|
categories = content.taxonomy_terms.filter(taxonomy_type='category')
|
|
|
|
# Get all tags for a content piece
|
|
tags = content.taxonomy_terms.filter(taxonomy_type='tag')
|
|
|
|
# Add a category to content
|
|
tech_category = ContentTaxonomy.objects.get(name='Technology')
|
|
content.taxonomy_terms.add(tech_category)
|
|
|
|
# Get all content with a specific tag
|
|
tutorial_tag = ContentTaxonomy.objects.get(name='Tutorial')
|
|
contents = tutorial_tag.contents.all()
|
|
|
|
# WordPress publishing (automatic)
|
|
wp_categories = [term.name for term in content.taxonomy_terms.filter(taxonomy_type='category')]
|
|
wp_tags = [term.name for term in content.taxonomy_terms.filter(taxonomy_type='tag')]
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ WordPress Integration (Bidirectional Sync) │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
IGNY8 → WordPress:
|
|
─────────────────
|
|
1. Content created in IGNY8
|
|
2. Categories/tags assigned via taxonomy_terms M2M
|
|
3. Publishing task created
|
|
4. wordpress_publishing.py extracts:
|
|
- categories = content.taxonomy_terms.filter(taxonomy_type='category')
|
|
- tags = content.taxonomy_terms.filter(taxonomy_type='tag')
|
|
5. REST API creates WordPress post with terms
|
|
6. external_id saved back to Content model
|
|
7. Log: [5-homeg8.com] [POST] Published: "Article Title" (ID: 123)
|
|
|
|
WordPress → IGNY8:
|
|
─────────────────
|
|
1. WordPress plugin detects post update
|
|
2. REST API sends post data + terms to IGNY8
|
|
3. Content updated/created with external_id
|
|
4. ContentTaxonomy created/updated with external_id
|
|
5. ContentTaxonomyRelation created linking them
|
|
6. Log: [5-homeg8.com] [SYNC] Imported: "Article Title"
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Database Tables Summary │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
igny8_content
|
|
├─ id (PK)
|
|
├─ site_id (FK → sites)
|
|
├─ sector_id (FK → sectors)
|
|
├─ cluster_id (FK → clusters)
|
|
├─ title, content_html, word_count
|
|
├─ meta_title, meta_description, keywords
|
|
├─ content_type, content_structure
|
|
├─ external_id, external_url, sync_status
|
|
└─ source, status, timestamps
|
|
|
|
igny8_content_taxonomy_relations (Through Table)
|
|
├─ id (PK)
|
|
├─ content_id (FK → igny8_content)
|
|
├─ taxonomy_id (FK → igny8_content_taxonomy_terms)
|
|
└─ timestamps
|
|
UNIQUE(content_id, taxonomy_id)
|
|
|
|
igny8_content_taxonomy_terms
|
|
├─ id (PK)
|
|
├─ site_id (FK → sites)
|
|
├─ sector_id (FK → sectors)
|
|
├─ name, slug
|
|
├─ taxonomy_type ('category' | 'tag')
|
|
├─ description, count
|
|
├─ external_taxonomy ('category' | 'post_tag')
|
|
├─ external_id (WordPress term_id)
|
|
├─ metadata (JSON)
|
|
└─ timestamps
|
|
UNIQUE(site_id, slug, taxonomy_type)
|
|
UNIQUE(site_id, external_id, external_taxonomy)
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Before vs After Comparison │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
BEFORE (Complex - with SiteBlueprint):
|
|
────────────────────────────────────
|
|
SiteBlueprint ──┬── SiteBlueprintCluster ──> Clusters
|
|
├── SiteBlueprintTaxonomy ──> ContentTaxonomy
|
|
└── PageBlueprint ──> Content
|
|
|
|
Content ──> ContentTaxonomyMap ──> ContentTaxonomy
|
|
(separate table with FK)
|
|
|
|
PublishingRecord ──┬── content_id
|
|
└── site_blueprint_id
|
|
|
|
DeploymentRecord ──┬── content_id
|
|
└── site_blueprint_id
|
|
|
|
|
|
AFTER (Simple - SiteBlueprint Removed):
|
|
──────────────────────────────────────
|
|
Keywords ──> Clusters ──> Ideas ──> Tasks ──> Content
|
|
|
|
Content ↔ ContentTaxonomy
|
|
(M2M via ContentTaxonomyRelation)
|
|
|
|
PublishingRecord ──> content_id
|
|
|
|
DeploymentRecord ──> content_id
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ Key Benefits │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
|
|
✅ Simpler architecture - removed 4 models
|
|
✅ Direct M2M relationship - easier to query
|
|
✅ Less database joins - better performance
|
|
✅ Clear taxonomy model in Django admin
|
|
✅ WordPress sync unchanged - still works perfectly
|
|
✅ Planner-Writer-Publisher workflow intact
|
|
✅ Multi-tenant security maintained
|
|
✅ No circular dependencies
|
|
✅ Clean codebase - no legacy blueprint code
|