24 KiB
IGNY8 Backend Documentation
Version: 1.0
Last Updated: 2025-01-XX
Purpose: Complete backend documentation covering models, views, APIs, modules, serializers, tasks, and structure.
Table of Contents
- Backend Overview
- Tech Stack
- Project Structure
- Models
- ViewSets
- Serializers
- Celery Tasks
- API Endpoints
- Base Classes
- Middleware
- Utilities
- Modules
Backend Overview
The IGNY8 backend is a Django 5.2+ application using Django REST Framework (DRF) for API endpoints. The backend follows a modular architecture with clear separation of concerns, automatic account isolation, and support for asynchronous task processing via Celery.
Key Features
- Multi-Tenancy: Complete account isolation with automatic filtering
- RESTful API: DRF ViewSets with consistent response format
- Celery Integration: Asynchronous task processing for long-running operations
- Account/Site/Sector Hierarchy: Hierarchical data organization
- AI Integration: Unified AIProcessor for all AI operations
- Progress Tracking: Real-time progress updates for Celery tasks
Tech Stack
Core Technologies
- Django 5.2+: Web framework
- Django REST Framework: API framework
- PostgreSQL: Database
- Celery: Asynchronous task queue
- Redis: Celery broker and caching
Key Libraries
- django-filter: Advanced filtering
- djangorestframework-simplejwt: JWT authentication
- requests: HTTP client for external APIs
- python-dotenv: Environment variable management
Project Structure
backend/igny8_core/
├── auth/ # Multi-tenancy and authentication
│ ├── models.py # Account, User, Plan, Site, Sector, Industry models
│ ├── views.py # Account, User, Site, Sector ViewSets
│ ├── serializers.py # Account, User, Plan serializers
│ └── urls.py # Auth module URLs
├── modules/ # Feature modules
│ ├── planner/ # Keywords, Clusters, Ideas
│ │ ├── models.py # Keywords, Clusters, ContentIdeas models
│ │ ├── views.py # KeywordViewSet, ClusterViewSet, ContentIdeasViewSet
│ │ ├── tasks.py # Celery tasks for AI operations
│ │ ├── serializers.py # Model serializers
│ │ └── urls.py # Planner module URLs
│ ├── writer/ # Tasks, Content, Images
│ │ ├── models.py # Tasks, Content, Images models
│ │ ├── views.py # TasksViewSet
│ │ ├── tasks.py # Celery tasks for content/image generation
│ │ └── urls.py # Writer module URLs
│ ├── system/ # Settings, Prompts, Integration
│ │ ├── models.py # AIPrompt, IntegrationSettings, AuthorProfile, Strategy
│ │ ├── views.py # AIPromptViewSet, AuthorProfileViewSet
│ │ ├── integration_views.py # IntegrationSettingsViewSet, task_progress
│ │ ├── utils.py # Default prompts, prompt loading
│ │ └── urls.py # System module URLs
│ └── billing/ # Credits, Transactions, Usage
│ ├── models.py # CreditTransaction, UsageLog models
│ ├── views.py # Billing ViewSets
│ └── services.py # CreditService
├── api/ # API base classes
│ ├── base.py # AccountModelViewSet, SiteSectorModelViewSet
│ └── pagination.py # CustomPageNumberPagination
├── utils/ # Shared utilities
│ ├── ai_processor.py # Unified AI interface
│ └── content_normalizer.py # Content processing utilities
├── middleware/ # Custom middleware
│ ├── account.py # AccountContextMiddleware (sets request.account)
│ └── resource_tracker.py # ResourceTrackerMiddleware (API metrics)
├── settings.py # Django settings
├── urls.py # Root URL configuration
└── celery.py # Celery configuration
Models
Base Models
AccountBaseModel
File: auth/models.py
Purpose: Base model for all account-isolated models.
Fields:
account: ForeignKey to Accountcreated_at: DateTimeField (auto_now_add)updated_at: DateTimeField (auto_now)
Usage: All models that need account isolation inherit from this.
SiteSectorBaseModel
File: auth/models.py
Purpose: Base model for models that belong to Site and Sector.
Fields:
- Inherits from
AccountBaseModel site: ForeignKey to Sitesector: ForeignKey to Sector
Methods:
save(): Automatically setsaccountfromsite.accountand validates sector belongs to site
Usage: Models like Keywords, Clusters, ContentIdeas, Tasks inherit from this.
Auth Models
Account
File: auth/models.py
Table: igny8_accounts
Fields:
name: CharFieldslug: SlugField (unique)owner: ForeignKey to Userstripe_customer_id: CharField (optional)plan: ForeignKey to Plancredits: IntegerField (default: 0)status: CharField (choices: active, suspended, trial, cancelled)
Methods:
is_system_account(): Returns True if account is system account (aws-admin, default-account, default)
User
File: auth/models.py
Table: igny8_users
Fields:
- Inherits from
AbstractUser email: EmailField (unique, USERNAME_FIELD)account: ForeignKey to Accountrole: CharField (choices: developer, owner, admin, editor, viewer, system_bot)
Methods:
has_role(*roles): Check if user has any of the specified rolesis_owner_or_admin(): Returns True if role is owner or adminis_developer(): Returns True if role is developer or is_superuseris_admin_or_developer(): Returns True if role is admin or developeris_system_account_user(): Returns True if user belongs to system accountget_accessible_sites(): Returns QuerySet of sites user can access
Plan
File: auth/models.py
Table: igny8_plans
Fields:
name: CharFieldslug: SlugField (unique)price: DecimalFieldbilling_cycle: CharField (choices: monthly, annual)features: JSONField (array of feature strings)max_users: IntegerFieldmax_sites: IntegerFieldmax_keywords: IntegerFieldmax_clusters: IntegerFieldmax_content_ideas: IntegerFielddaily_cluster_limit: IntegerFieldmonthly_cluster_ai_credits: IntegerFielddaily_content_tasks: IntegerFielddaily_ai_requests: IntegerFieldmonthly_word_count_limit: IntegerFieldmonthly_content_ai_credits: IntegerFieldmonthly_image_count: IntegerFielddaily_image_generation_limit: IntegerFieldmonthly_image_ai_credits: IntegerFieldmax_images_per_task: IntegerFieldimage_model_choices: JSONFieldincluded_credits: IntegerFieldextra_credit_price: DecimalField- And more...
Methods:
clean(): Validates plan limitsget_effective_credits_per_month(): Returns included_credits or credits_per_month
Site
File: auth/models.py
Table: igny8_sites
Fields:
- Inherits from
AccountBaseModel name: CharFieldslug: SlugField (unique per account)domain: URLField (optional)industry: ForeignKey to Industry (optional)is_active: BooleanFieldstatus: CharField (choices: active, inactive, suspended)wp_url: URLField (optional, WordPress integration)wp_username: CharField (optional)wp_app_password: CharField (optional)
Methods:
get_active_sectors_count(): Get count of active sectorscan_add_sector(): Check if site can add another sector (max 5)
Sector
File: auth/models.py
Table: igny8_sectors
Fields:
- Inherits from
AccountBaseModel site: ForeignKey to Siteindustry_sector: ForeignKey to IndustrySector (optional, template reference)name: CharFieldslug: SlugField (unique per site)is_active: BooleanFieldstatus: CharField (choices: active, inactive)
Planner Models
Keywords
File: modules/planner/models.py
Table: igny8_keywords
Fields:
- Inherits from
SiteSectorBaseModel keyword: CharFieldvolume: IntegerFielddifficulty: IntegerFieldintent: CharField (choices: informational, navigational, commercial, transactional)cluster: ForeignKey to Clusters (optional)status: CharField (choices: active, pending, archived)
Clusters
File: modules/planner/models.py
Table: igny8_clusters
Fields:
- Inherits from
SiteSectorBaseModel name: CharField (unique)description: TextFieldkeywords_count: IntegerFieldvolume: IntegerFieldmapped_pages: IntegerFieldstatus: CharField
ContentIdeas
File: modules/planner/models.py
Table: igny8_content_ideas
Fields:
- Inherits from
SiteSectorBaseModel idea_title: CharFielddescription: TextFieldcontent_structure: CharField (choices: cluster_hub, landing_page, pillar_page, supporting_page)content_type: CharField (choices: blog_post, article, guide, tutorial)target_keywords: CharField (comma-separated, legacy)keyword_objects: ManyToManyField to Keywordskeyword_cluster: ForeignKey to Clustersstatus: CharField (choices: new, scheduled, published)estimated_word_count: IntegerField
Writer Models
Tasks
File: modules/writer/models.py
Table: igny8_tasks
Fields:
- Inherits from
SiteSectorBaseModel title: CharFielddescription: TextFieldkeywords: CharField (comma-separated, legacy)keyword_objects: ManyToManyField to Keywordscluster: ForeignKey to Clustersidea: ForeignKey to ContentIdeascontent_structure: CharFieldcontent_type: CharFieldstatus: CharField (choices: queued, in_progress, draft, review, published, completed)content: TextField (generated content)word_count: IntegerFieldmeta_title: CharFieldmeta_description: TextFieldassigned_post_id: IntegerField (WordPress post ID)post_url: URLField
Content
File: modules/writer/models.py
Table: igny8_content
Fields:
- Inherits from
SiteSectorBaseModel task: OneToOneField to Taskshtml_content: TextFieldword_count: IntegerFieldmetadata: JSONField
Methods:
save(): Automatically sets account, site, sector from task
Images
File: modules/writer/models.py
Table: igny8_images
Fields:
- Inherits from
SiteSectorBaseModel task: ForeignKey to Tasksimage_type: CharField (choices: featured, desktop, mobile, in_article)image_url: URLFieldimage_path: CharField (local path)prompt: TextFieldstatus: CharFieldposition: IntegerField
Methods:
save(): Automatically sets account, site, sector from task
System Models
AIPrompt
File: modules/system/models.py
Table: igny8_ai_prompts
Fields:
- Inherits from
AccountBaseModel prompt_type: CharField (choices: clustering, ideas, content_generation, image_prompt_extraction, image_prompt_template, negative_prompt)prompt_value: TextFielddefault_prompt: TextFieldis_active: BooleanField
Unique Constraint: (account, prompt_type)
IntegrationSettings
File: modules/system/models.py
Table: igny8_integration_settings
Fields:
- Inherits from
AccountBaseModel integration_type: CharField (choices: openai, runware, gsc, image_generation)config: JSONField (API keys, settings, etc.)is_active: BooleanField
Unique Constraint: (account, integration_type)
AuthorProfile
File: modules/system/models.py
Table: igny8_author_profiles
Fields:
- Inherits from
AccountBaseModel name: CharFielddescription: TextFieldtone: CharFieldlanguage: CharFieldstructure_template: JSONFieldis_active: BooleanField
Strategy
File: modules/system/models.py
Table: igny8_strategies
Fields:
- Inherits from
AccountBaseModel name: CharFielddescription: TextFieldsector: ForeignKey to Sector (optional)prompt_types: JSONFieldsection_logic: JSONFieldis_active: BooleanField
ViewSets
Base ViewSets
AccountModelViewSet
File: api/base.py
Purpose: Base ViewSet with automatic account filtering.
Methods:
get_queryset(): Filters queryset byrequest.account(with admin/developer override)perform_create(): Sets account on created objectsget_serializer_context(): Adds account to serializer context
Access Control:
- Admin/Developer users: Bypass account filtering
- System account users: Bypass account filtering
- Regular users: Only see data from their account
SiteSectorModelViewSet
File: api/base.py
Purpose: Base ViewSet with site/sector filtering and access control.
Inherits: AccountModelViewSet
Methods:
get_queryset(): Filters by account, accessible sites, and optional site_id/sector_idperform_create(): Validates site access and sector-site relationshipget_serializer_context(): Adds accessible sites and sectors to context
Access Control:
- Developers: All active sites
- System account users: All active sites
- Owners/Admins: All sites in their account
- Editors/Viewers: Only sites granted via
SiteUserAccess
Planner ViewSets
KeywordViewSet
File: modules/planner/views.py
Inherits: SiteSectorModelViewSet
Actions:
list(): List keywords with filteringcreate(): Create keywordretrieve(): Get keyword detailsupdate(): Update keyworddestroy(): Delete keywordauto_cluster(): Auto-cluster keywords using AIbulk_delete(): Bulk delete keywordsbulk_update_status(): Bulk update keyword statusexport_csv(): Export keywords to CSVimport_csv(): Import keywords from CSV
Filtering:
- Search:
keywordfield - Filters:
status,cluster_id,intent - Custom:
difficulty_min,difficulty_max,volume_min,volume_max - Ordering:
created_at,volume,difficulty
ClusterViewSet
File: modules/planner/views.py
Inherits: SiteSectorModelViewSet
Actions:
list(): List clusterscreate(): Create clusterretrieve(): Get cluster detailsupdate(): Update clusterdestroy(): Delete clusterauto_generate_ideas(): Auto-generate content ideas for clusters
ContentIdeasViewSet
File: modules/planner/views.py
Inherits: SiteSectorModelViewSet
Actions:
list(): List content ideascreate(): Create content idearetrieve(): Get content idea detailsupdate(): Update content ideadestroy(): Delete content idea
Writer ViewSets
TasksViewSet
File: modules/writer/views.py
Inherits: SiteSectorModelViewSet
Actions:
list(): List taskscreate(): Create taskretrieve(): Get task detailsupdate(): Update taskdestroy(): Delete taskauto_generate_content(): Auto-generate content for tasksauto_generate_images(): Auto-generate images for tasksbulk_delete(): Bulk delete tasksbulk_update(): Bulk update task status
Filtering:
- Search:
title,keywords - Filters:
status,cluster_id,content_type,content_structure - Ordering:
title,created_at,word_count,status
System ViewSets
IntegrationSettingsViewSet
File: modules/system/integration_views.py
Inherits: viewsets.ViewSet
Actions:
list(): List integrationsretrieve(): Get integration settingsupdate(): Save integration settingssave_post(): Save integration settings (POST)test_connection(): Test API connectiontest_openai(): Test OpenAI connectiontest_runware(): Test Runware connectiongenerate_image(): Test image generationtask_progress(): Get Celery task progress
AIPromptViewSet
File: modules/system/views.py
Inherits: AccountModelViewSet
Actions:
list(): List promptscreate(): Create promptretrieve(): Get prompt detailsupdate(): Update promptdestroy(): Delete promptreset_to_default(): Reset prompt to default value
AuthorProfileViewSet
File: modules/system/views.py
Inherits: AccountModelViewSet
Actions:
list(): List author profilescreate(): Create author profileretrieve(): Get author profile detailsupdate(): Update author profiledestroy(): Delete author profile
Serializers
Planner Serializers
KeywordSerializer
File: modules/planner/serializers.py
Fields: All Keyword model fields
Validation: Validates keyword uniqueness, cluster belongs to same sector
ClusterSerializer
File: modules/planner/cluster_serializers.py
Fields: All Cluster model fields
Read-Only Fields: keywords_count, volume (calculated)
ContentIdeasSerializer
File: modules/planner/serializers.py
Fields: All ContentIdeas model fields
Writer Serializers
TasksSerializer
File: modules/writer/serializers.py
Fields: All Tasks model fields
ContentSerializer
File: modules/writer/serializers.py
Fields: All Content model fields
ImagesSerializer
File: modules/writer/serializers.py
Fields: All Images model fields
System Serializers
AIPromptSerializer
File: modules/system/serializers.py
Fields: All AIPrompt model fields
IntegrationSettingsSerializer
File: modules/system/serializers.py
Fields: All IntegrationSettings model fields
Celery Tasks
Planner Tasks
auto_cluster_keywords_task
File: modules/planner/tasks.py
Purpose: Auto-cluster keywords using AI.
Parameters:
keyword_ids: List of keyword IDsaccount_id: Account IDsite_id: Site IDsector_id: Sector ID
Progress Tracking: Updates progress with request_steps and response_steps
Calls: _auto_cluster_keywords_core()
auto_generate_ideas_task
File: modules/planner/tasks.py
Purpose: Auto-generate content ideas for clusters.
Parameters:
cluster_ids: List of cluster IDsaccount_id: Account ID
Progress Tracking: Updates progress for each cluster
Calls: _generate_single_idea_core() for each cluster
Writer Tasks
auto_generate_content_task
File: modules/writer/tasks.py
Purpose: Auto-generate content for tasks.
Parameters:
task_ids: List of task IDsaccount_id: Account ID
Progress Tracking: Updates progress for each task
Calls: AIProcessor.generate_content()
auto_generate_images_task
File: modules/writer/tasks.py
Purpose: Auto-generate images for tasks.
Parameters:
task_ids: List of task IDsaccount_id: Account ID
Progress Tracking: Updates progress for each task
Calls: AIProcessor.extract_image_prompts() and AIProcessor.generate_image()
API Endpoints
Base URL
/api/v1/
Planner Endpoints
GET /api/v1/planner/keywords/- List keywordsPOST /api/v1/planner/keywords/- Create keywordGET /api/v1/planner/keywords/{id}/- Get keywordPUT /api/v1/planner/keywords/{id}/- Update keywordDELETE /api/v1/planner/keywords/{id}/- Delete keywordPOST /api/v1/planner/keywords/auto_cluster/- Auto-cluster keywordsPOST /api/v1/planner/keywords/bulk_delete/- Bulk delete keywordsPOST /api/v1/planner/keywords/bulk_update_status/- Bulk update statusGET /api/v1/planner/keywords/export_csv/- Export keywordsPOST /api/v1/planner/keywords/import_csv/- Import keywordsGET /api/v1/planner/clusters/- List clustersPOST /api/v1/planner/clusters/auto_generate_ideas/- Auto-generate ideasGET /api/v1/planner/ideas/- List content ideas
Writer Endpoints
GET /api/v1/writer/tasks/- List tasksPOST /api/v1/writer/tasks/auto_generate_content/- Auto-generate contentPOST /api/v1/writer/tasks/auto_generate_images/- Auto-generate images
System Endpoints
GET /api/v1/system/settings/integrations/{pk}/- Get integration settingsPUT /api/v1/system/settings/integrations/{pk}/- Save integration settingsPOST /api/v1/system/settings/integrations/{pk}/test_openai/- Test OpenAIPOST /api/v1/system/settings/integrations/{pk}/test_runware/- Test RunwarePOST /api/v1/system/settings/integrations/{pk}/generate_image/- Test image generationGET /api/v1/system/settings/task_progress/{task_id}/- Get task progress
Base Classes
AccountModelViewSet
File: api/base.py
Purpose: Base ViewSet with automatic account filtering.
Features:
- Automatic account filtering
- Admin/Developer override
- Account context in serializers
SiteSectorModelViewSet
File: api/base.py
Purpose: Base ViewSet with site/sector filtering.
Features:
- Account filtering (inherited)
- Site access control
- Sector validation
- Accessible sites/sectors in serializer context
Middleware
AccountContextMiddleware
File: middleware/account.py
Purpose: Sets request.account from JWT token.
Functionality:
- Extracts account ID from JWT token
- Loads Account object
- Sets
request.account
ResourceTrackerMiddleware
File: middleware/resource_tracker.py
Purpose: Tracks API request metrics.
Functionality:
- Tracks CPU, memory, I/O usage
- Stores metrics in cache
- Provides metrics endpoint
Utilities
AIProcessor
File: utils/ai_processor.py
Purpose: Unified AI interface for all AI operations.
Methods:
cluster_keywords(): Cluster keywords using AIgenerate_ideas(): Generate content ideasgenerate_content(): Generate text contentextract_image_prompts(): Extract image prompts from contentgenerate_image(): Generate images using OpenAI DALL-E or Runware
See: AI Functions documentation for complete details
Content Normalizer
File: utils/content_normalizer.py
Purpose: Content processing utilities.
Functions:
_extract_body_content(): Extract body content from HTML
Modules
Planner Module
Purpose: Keyword management and content planning.
Models: Keywords, Clusters, ContentIdeas
ViewSets: KeywordViewSet, ClusterViewSet, ContentIdeasViewSet
Tasks: auto_cluster_keywords_task, auto_generate_ideas_task
Writer Module
Purpose: Content generation and management.
Models: Tasks, Content, Images
ViewSets: TasksViewSet
Tasks: auto_generate_content_task, auto_generate_images_task
System Module
Purpose: System settings, prompts, and integrations.
Models: AIPrompt, IntegrationSettings, AuthorProfile, Strategy
ViewSets: AIPromptViewSet, AuthorProfileViewSet, IntegrationSettingsViewSet
Utilities: Default prompts, prompt loading
Billing Module
Purpose: Credits, transactions, and usage tracking.
Models: CreditTransaction, UsageLog
ViewSets: CreditTransactionViewSet, UsageLogViewSet
Services: CreditService
Summary
The IGNY8 backend is built on:
- Django + DRF: Robust web framework with RESTful API
- Multi-Tenancy: Complete account isolation with automatic filtering
- Modular Architecture: Clear module boundaries with shared utilities
- Celery Integration: Asynchronous task processing for long-running operations
- Base ViewSets: Consistent access control and filtering
- AI Integration: Unified AIProcessor for all AI operations
- Progress Tracking: Real-time progress updates for Celery tasks
- Account/Site/Sector Hierarchy: Hierarchical data organization
This architecture ensures scalability, maintainability, and extensibility while providing a robust API for the frontend.