8 Phases refactor
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
**Base URL**: `https://api.igny8.com/api/v1/`
|
||||
**Version**: 1.0.0
|
||||
**Last Updated**: 2025-01-XX (Added 6 missing modules: Linker, Optimizer, Publisher, Site Builder, Automation, Integration)
|
||||
**Last Updated**: 2025-12-03 (Removed deprecated Site Builder module)
|
||||
**Status**: ✅ **100% IMPLEMENTED** - All endpoints use unified format
|
||||
|
||||
**Purpose**: Complete, unified reference for IGNY8 API covering authentication, endpoints, response formats, error handling, rate limiting, permissions, and integration examples.
|
||||
@@ -1193,106 +1193,6 @@ class KeywordViewSet(SiteSectorModelViewSet):
|
||||
}
|
||||
```
|
||||
|
||||
### Site Builder Module Endpoints
|
||||
|
||||
**Base Path**: `/api/v1/site-builder/`
|
||||
**Permission**: IsAuthenticatedAndActive + HasTenantAccess
|
||||
|
||||
#### Site Blueprints
|
||||
|
||||
**Base Path**: `/api/v1/site-builder/blueprints/`
|
||||
**Inherits**: SiteSectorModelViewSet
|
||||
|
||||
**Standard CRUD:**
|
||||
- `GET /api/v1/site-builder/blueprints/` - List site blueprints (paginated)
|
||||
- `POST /api/v1/site-builder/blueprints/` - Create site blueprint
|
||||
- `GET /api/v1/site-builder/blueprints/{id}/` - Get blueprint details
|
||||
- `PUT /api/v1/site-builder/blueprints/{id}/` - Update blueprint
|
||||
- `DELETE /api/v1/site-builder/blueprints/{id}/` - Delete blueprint
|
||||
|
||||
**Custom Actions:**
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/generate_structure/` - Generate site structure using AI
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/generate_all_pages/` - Generate all pages for blueprint
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/create_tasks/` - Create Writer tasks for pages
|
||||
- `GET /api/v1/site-builder/blueprints/{id}/progress/` - Get cluster-level completion status
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/clusters/attach/` - Attach planner clusters
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/clusters/detach/` - Detach clusters
|
||||
- `GET /api/v1/site-builder/blueprints/{id}/taxonomies/` - List taxonomies
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/taxonomies/` - Create taxonomy
|
||||
- `POST /api/v1/site-builder/blueprints/{id}/taxonomies/import/` - Import taxonomies
|
||||
- `POST /api/v1/site-builder/blueprints/bulk_delete/` - Bulk delete blueprints
|
||||
|
||||
**Filtering:**
|
||||
- `status` - Filter by blueprint status
|
||||
- `site_id` - Filter by site
|
||||
- `sector_id` - Filter by sector
|
||||
|
||||
#### Page Blueprints
|
||||
|
||||
**Base Path**: `/api/v1/site-builder/pages/`
|
||||
**Inherits**: SiteSectorModelViewSet
|
||||
|
||||
**Standard CRUD:**
|
||||
- `GET /api/v1/site-builder/pages/` - List page blueprints (paginated)
|
||||
- `POST /api/v1/site-builder/pages/` - Create page blueprint
|
||||
- `GET /api/v1/site-builder/pages/{id}/` - Get page details
|
||||
- `PUT /api/v1/site-builder/pages/{id}/` - Update page
|
||||
- `DELETE /api/v1/site-builder/pages/{id}/` - Delete page
|
||||
|
||||
**Custom Actions:**
|
||||
- `POST /api/v1/site-builder/pages/{id}/generate_content/` - Generate content for page
|
||||
- `POST /api/v1/site-builder/pages/{id}/regenerate/` - Regenerate page content
|
||||
|
||||
**Filtering:**
|
||||
- `site_blueprint_id` - Filter by site blueprint
|
||||
- `status` - Filter by page status
|
||||
|
||||
#### Site Assets
|
||||
|
||||
- `GET /api/v1/site-builder/assets/` - List files for site
|
||||
|
||||
**Query Parameters:**
|
||||
- `site_id` - Filter by site
|
||||
- `file_type` - Filter by file type
|
||||
|
||||
- `POST /api/v1/site-builder/assets/` - Upload file
|
||||
|
||||
**Request:** Multipart form data
|
||||
```json
|
||||
{
|
||||
"file": "<file>",
|
||||
"site_id": 1,
|
||||
"file_type": "image"
|
||||
}
|
||||
```
|
||||
|
||||
- `DELETE /api/v1/site-builder/assets/` - Delete file
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"file_path": "path/to/file.jpg",
|
||||
"site_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### Site Builder Metadata
|
||||
|
||||
- `GET /api/v1/site-builder/metadata/` - Get metadata (business types, audience profiles, etc.)
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"business_types": [...],
|
||||
"audience_profiles": [...],
|
||||
"brand_personalities": [...],
|
||||
"hero_imagery_directions": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Automation Module Endpoints
|
||||
|
||||
**Base Path**: `/api/v1/automation/`
|
||||
|
||||
@@ -111,7 +111,7 @@ Keywords → Clusters → Ideas → Tasks → Content → Images
|
||||
| `target_keywords` | CharField(500) | Comma-separated keywords (legacy) | - |
|
||||
| `keyword_objects` | ManyToManyField | Keywords linked to idea | Keywords |
|
||||
| `keyword_cluster_id` | ForeignKey | Parent cluster | Clusters |
|
||||
| `taxonomy_id` | ForeignKey | Optional taxonomy association | SiteBlueprintTaxonomy |
|
||||
| `taxonomy_id` | ForeignKey | Optional taxonomy association | ContentTaxonomy |
|
||||
| `status` | CharField(50) | Idea status | new, scheduled, published |
|
||||
| `estimated_word_count` | Integer | Target word count | - |
|
||||
| `site_entity_type` | CharField(50) | Target entity type | post, page, product, service, taxonomy_term |
|
||||
@@ -148,7 +148,7 @@ Keywords → Clusters → Ideas → Tasks → Content → Images
|
||||
| `idea_id` | ForeignKey | Source idea | ContentIdeas |
|
||||
| `status` | CharField(50) | Task status | queued, in_progress, completed, failed |
|
||||
| `entity_type` | CharField(50) | Content entity type | post, page, product, service, taxonomy_term |
|
||||
| `taxonomy_id` | ForeignKey | Taxonomy association | SiteBlueprintTaxonomy |
|
||||
| `taxonomy_id` | ForeignKey | Taxonomy association | ContentTaxonomy |
|
||||
| `cluster_role` | CharField(50) | Role within cluster | hub, supporting, attribute |
|
||||
| `account` | ForeignKey | Owner account | - |
|
||||
| `site` | ForeignKey | Parent site | - |
|
||||
|
||||
@@ -1,362 +0,0 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user