docs updates

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-03 13:03:14 +00:00
parent 316cafab1b
commit de425e0e93
13 changed files with 2203 additions and 682 deletions

View File

@@ -0,0 +1,362 @@
# Quick Reference: Content & Taxonomy After SiteBuilder Removal
## Django Admin URLs
```
Content Management:
http://your-domain/admin/writer/content/
Taxonomy Management:
http://your-domain/admin/writer/contenttaxonomy/
Tasks Queue:
http://your-domain/admin/writer/tasks/
```
## Common Django ORM Queries
### Working with Content
```python
from igny8_core.business.content.models import Content, ContentTaxonomy
# Get content with its taxonomy
content = Content.objects.get(id=1)
categories = content.taxonomy_terms.filter(taxonomy_type='category')
tags = content.taxonomy_terms.filter(taxonomy_type='tag')
# Create content with taxonomy
content = Content.objects.create(
account=account,
site=site,
sector=sector,
cluster=cluster,
title="My Article",
content_html="<p>Content here</p>",
content_type='post',
content_structure='article'
)
# Add categories and tags
tech_cat = ContentTaxonomy.objects.get(name='Technology', taxonomy_type='category')
tutorial_tag = ContentTaxonomy.objects.get(name='Tutorial', taxonomy_type='tag')
content.taxonomy_terms.add(tech_cat, tutorial_tag)
# Remove taxonomy
content.taxonomy_terms.remove(tech_cat)
# Clear all taxonomy
content.taxonomy_terms.clear()
```
### Working with Taxonomy
```python
# Create category
category = ContentTaxonomy.objects.create(
account=account,
site=site,
sector=sector,
name='Technology',
slug='technology',
taxonomy_type='category',
description='Tech-related content'
)
# Create tag
tag = ContentTaxonomy.objects.create(
account=account,
site=site,
sector=sector,
name='Tutorial',
slug='tutorial',
taxonomy_type='tag'
)
# Get all content with this taxonomy
tech_content = category.contents.all()
# Get WordPress-synced taxonomy
wp_category = ContentTaxonomy.objects.get(
external_id=5,
external_taxonomy='category',
site=site
)
```
### WordPress Publishing
```python
from igny8_core.tasks.wordpress_publishing import publish_content_to_wordpress
# Publish content (categories/tags extracted automatically)
result = publish_content_to_wordpress.delay(
content_id=content.id,
site_url='https://example.com',
username='admin',
app_password='xxxx xxxx xxxx xxxx'
)
# The task automatically extracts:
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')
]
```
## API Endpoints (REST)
```
GET /api/v1/writer/content/ - List all content
POST /api/v1/writer/content/ - Create content
GET /api/v1/writer/content/{id}/ - Get content detail
PATCH /api/v1/writer/content/{id}/ - Update content
DELETE /api/v1/writer/content/{id}/ - Delete content
GET /api/v1/writer/taxonomy/ - List all taxonomy
POST /api/v1/writer/taxonomy/ - Create taxonomy
GET /api/v1/writer/taxonomy/{id}/ - Get taxonomy detail
PATCH /api/v1/writer/taxonomy/{id}/ - Update taxonomy
DELETE /api/v1/writer/taxonomy/{id}/ - Delete taxonomy
POST /api/v1/publisher/publish/ - Publish content
```
## Database Schema
### Content Table (igny8_content)
| Column | Type | Description |
|--------|------|-------------|
| id | PK | Primary key |
| site_id | FK | Multi-tenant site |
| sector_id | FK | Multi-tenant sector |
| cluster_id | FK | Parent cluster (required) |
| title | VARCHAR(255) | Content title |
| content_html | TEXT | Final HTML content |
| word_count | INTEGER | Calculated word count |
| meta_title | VARCHAR(255) | SEO title |
| meta_description | TEXT | SEO description |
| primary_keyword | VARCHAR(255) | Primary SEO keyword |
| secondary_keywords | JSON | Secondary keywords |
| content_type | VARCHAR(50) | post, page, product, taxonomy |
| content_structure | VARCHAR(50) | article, guide, review, etc. |
| external_id | VARCHAR(255) | WordPress post ID |
| external_url | URL | WordPress URL |
| external_type | VARCHAR(100) | WordPress post type |
| sync_status | VARCHAR(50) | Sync status |
| source | VARCHAR(50) | igny8 or wordpress |
| status | VARCHAR(50) | draft, review, published |
### Taxonomy Table (igny8_content_taxonomy_terms)
| Column | Type | Description |
|--------|------|-------------|
| id | PK | Primary key |
| site_id | FK | Multi-tenant site |
| sector_id | FK | Multi-tenant sector |
| name | VARCHAR(255) | Term name |
| slug | VARCHAR(255) | URL slug |
| taxonomy_type | VARCHAR(50) | category or tag |
| description | TEXT | Term description |
| count | INTEGER | Usage count |
| external_taxonomy | VARCHAR(100) | category, post_tag |
| external_id | INTEGER | WordPress term_id |
| metadata | JSON | Additional metadata |
### Relation Table (igny8_content_taxonomy_relations)
| Column | Type | Description |
|--------|------|-------------|
| id | PK | Primary key |
| content_id | FK | Content reference |
| taxonomy_id | FK | Taxonomy reference |
| created_at | TIMESTAMP | Creation timestamp |
| updated_at | TIMESTAMP | Update timestamp |
**Constraints:**
- UNIQUE(content_id, taxonomy_id)
## Workflow Commands
### 1. Run Migrations (When Ready)
```bash
# Apply blueprint removal migration
docker exec -it igny8_backend python manage.py migrate
# Check migration status
docker exec -it igny8_backend python manage.py showmigrations
```
### 2. Create Test Data
```bash
# Django shell
docker exec -it igny8_backend python manage.py shell
# Then in shell:
from igny8_core.auth.models import Account, Site, Sector
from igny8_core.business.planning.models import Keywords, Clusters
from igny8_core.business.content.models import Content, ContentTaxonomy
# Get your site/sector
account = Account.objects.first()
site = account.sites.first()
sector = site.sectors.first()
cluster = Clusters.objects.filter(sector=sector).first()
# Create taxonomy
cat = ContentTaxonomy.objects.create(
account=account,
site=site,
sector=sector,
name='Tech',
slug='tech',
taxonomy_type='category'
)
tag = ContentTaxonomy.objects.create(
account=account,
site=site,
sector=sector,
name='Tutorial',
slug='tutorial',
taxonomy_type='tag'
)
# Create content
content = Content.objects.create(
account=account,
site=site,
sector=sector,
cluster=cluster,
title='Test Article',
content_html='<p>Test content</p>',
content_type='post',
content_structure='article'
)
# Add taxonomy
content.taxonomy_terms.add(cat, tag)
# Verify
print(content.taxonomy_terms.all())
```
### 3. Test WordPress Publishing
```bash
# Check celery is running
docker logs igny8_celery_worker --tail 50
# Check publish logs
tail -f backend/logs/publish-sync-logs/*.log
# Manually trigger publish (Django shell)
from igny8_core.tasks.wordpress_publishing import publish_content_to_wordpress
result = publish_content_to_wordpress.delay(
content_id=1,
site_url='https://your-site.com',
username='admin',
app_password='xxxx xxxx xxxx xxxx'
)
```
## Troubleshooting
### Backend Won't Start
```bash
# Check logs
docker logs igny8_backend --tail 100
# Force recreate (clears Python bytecode cache)
docker compose -f docker-compose.app.yml up -d --force-recreate igny8_backend
# Check for import errors
docker exec -it igny8_backend python manage.py check
```
### Celery Not Processing Tasks
```bash
# Check celery logs
docker logs igny8_celery_worker --tail 100
# Restart celery
docker compose -f docker-compose.app.yml restart igny8_celery_worker
# Test celery connection
docker exec -it igny8_backend python manage.py shell
>>> from celery import current_app
>>> current_app.connection().ensure_connection(max_retries=3)
```
### Migration Issues
```bash
# Check current migrations
docker exec -it igny8_backend python manage.py showmigrations
# Create new migration (if needed)
docker exec -it igny8_backend python manage.py makemigrations
# Fake migration (if tables already dropped manually)
docker exec -it igny8_backend python manage.py migrate site_building 0002 --fake
```
### WordPress Sync Not Working
```bash
# Check publish logs
tail -f backend/logs/publish-sync-logs/*.log
# Check WordPress plugin logs (on WordPress server)
tail -f wp-content/plugins/igny8-bridge/logs/*.log
# Test WordPress REST API manually
curl -X GET https://your-site.com/wp-json/wp/v2/posts \
-u "username:app_password"
```
## File Locations Reference
```
Backend Code:
├─ backend/igny8_core/business/content/models.py # Content & Taxonomy models
├─ backend/igny8_core/business/publishing/models.py # Publishing records
├─ backend/igny8_core/modules/publisher/views.py # Publisher API
├─ backend/igny8_core/tasks/wordpress_publishing.py # WordPress publish task
└─ backend/igny8_core/settings.py # Django settings
Frontend Code:
├─ frontend/src/services/api.ts # API client
└─ frontend/src/modules/writer/ # Writer UI
Documentation:
├─ docs/SITEBUILDER-REMOVAL-SUMMARY.md # This removal summary
├─ docs/TAXONOMY-RELATIONSHIP-DIAGRAM.md # Taxonomy diagrams
├─ docs/02-PLANNER-WRITER-WORKFLOW-TECHNICAL-GUIDE.md # Workflow guide
└─ docs/04-WORDPRESS-BIDIRECTIONAL-SYNC-REFERENCE.md # WordPress sync
Migrations:
└─ backend/igny8_core/business/site_building/migrations/0002_remove_blueprint_models.py
Logs:
├─ backend/logs/publish-sync-logs/*.log # Publishing logs
└─ igny8-wp-plugin/logs/*.log # WordPress plugin logs
```
## Support Resources
1. **Backend Logs:** `docker logs igny8_backend`
2. **Celery Logs:** `docker logs igny8_celery_worker`
3. **Publishing Logs:** `backend/logs/publish-sync-logs/`
4. **Django Admin:** `http://your-domain/admin/`
5. **API Docs:** `http://your-domain/api/v1/`
6. **Workflow Guide:** `docs/02-PLANNER-WRITER-WORKFLOW-TECHNICAL-GUIDE.md`

View File

@@ -0,0 +1,258 @@
# 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