🧩 Extending the System
We built the Apptork Root System so you never feel trapped in a "black box." The architecture is fiercely modular, meaning you can swap out AI providers, add new monetization hooks, or change payment processors without ripping apart the core engine.
Here is exactly how you extend it.
⚡ Quick Reference: Where Do I Find X?
| I want to... | Where to go | Time to implement |
|---|---|---|
| Add a new AI model (e.g., Stable Diffusion 3) | Create a BasePayloadTransformer subclass in ai_core/transformers.py |
~15 min |
| Add a new AI provider (e.g., Anthropic) | Create a BaseProviderClient subclass in ai_core/providers/ |
~30 min |
| Add a new AI feature type (e.g., text2speech) | Create a new app, subclass BaseGenerationViewSet & BaseGenerationTask |
~2 hours |
| Add a new payment provider | Follow the store/ app pattern (Webhook view + Celery task) |
~2 hours |
| Add a new OAuth provider | Add to INSTALLED_APPS and SOCIALACCOUNT_PROVIDERS in config/base.py |
~10 min |
| White-label the entire system | Run python init_backend.py from the project root |
~2 min |
🏗️ The Core System & The AI Subsystem
The Root System is a complete SaaS backend first, and an AI powerhouse second. When extending the system, you'll generally be working with these key base classes depending on whether you are adding core functionality or AI features.
Core SaaS Pillars
BaseModel(core/models.py): The foundation of your database. Automatically grants your models UUID primary keys andcreated_at/updated_attimestamps. Use this for any standard relational data.APIView/ModelViewSet(Django Rest Framework): Standard endpoints for non-AI operations like user profiles, payments, or fetching data.
AI Subsystem Pillars
When you want to add entirely new AI functionality, inheriting from these classes gives you enterprise-grade infrastructure for free:
BaseGenerationViewSet(ai_core/views.py): Gives your AI endpoints rate throttling, cost calculation, wallet balance checks, and credit deductions automatically.BaseGenerationTask(ai_core/tasks.py): Gives your Celery tasks status tracking, error handling, SSE streaming updates, and auto-refunds on failure.BasePayloadTransformer(ai_core/transformers.py): Maps our unified mobile payload to a specific vendor's API format.
👩🍳 Recipe: Adding a New AI Model in 15 Minutes
Let's say Replicate just released a new image generation model, and you want to offer it to your users immediately.
Because we use a unified payload architecture, you don't need to touch your API views, serializers, or Celery tasks. You just need a Transformer.
Step 1: Write the Transformer
Create a subclass of BasePayloadTransformer in ai_core/transformers.py:
# ai_core/transformers.py
class MyNewModelTransformer(BasePayloadTransformer):
def transform_input(self, unified_payload: dict, task_instance) -> dict:
# Map our standard fields to the vendor's specific keys
return {
"prompt": unified_payload.get("prompt_text"),
"aspect_ratio": unified_payload.get("aspect_ratio", "1:1"),
"negative_prompt": "blurry, low quality",
}
def extract_output(self, vendor_response: Any) -> list[str]:
# Return a list of output URLs from the vendor's response
if isinstance(vendor_response, list) and len(vendor_response) > 0:
return [str(vendor_response[0])]
return []
Step 2: Register It
At the bottom of transformers.py, add your class to the registry:
TRANSFORMER_REGISTRY = {
# ... existing transformers ...
"my_new_model_transformer": MyNewModelTransformer,
}
Step 3: Enable it in the Django Admin
1. Go to your Django Admin → AI Core → Provider Model Configs.
2. Create a new config linking the AI Model to your Provider (e.g., Replicate).
3. Type my_new_model_transformer into the Transformer ID field.
That's it!
Your frontend can now request this new model. The system will automatically handle charging the user's wallet, running the Celery task, mapping the payload, and streaming the result back via SSE.
👩🍳 Recipe: Adding a New AI Provider in 30 Minutes
If you want to use a completely new AI API (like Anthropic, fal.ai, or a custom GPU cluster), you just need to implement a Provider Client.
Create a new file in ai_core/providers/ and inherit from BaseProviderClient:
# ai_core/providers/anthropic.py
from typing import Any, List, Optional
from .base import BaseProviderClient
class AnthropicClient(BaseProviderClient):
settings_key = "ANTHROPIC_API_KEY"
def run(self, model_id: str, vendor_payload: dict, transformer: Any, task_instance: Optional[Any] = None) -> List[str]:
# 1. Fetch your API key
api_key = self.get_api_key()
# 2. Make the HTTP request to Anthropic using vendor_payload
# ... your request logic here ...
# 3. Pass the raw response back to the transformer to extract the URLs/Text
return transformer.extract_output(raw_response)
Register it in ai_core/providers/__init__.py, add your API key to .env, and you're ready to start building transformers for it.
🎨 White-Labeling the System
We've included a powerful automation script that renames the boilerplate to your actual company name. It safely replaces folder names, module imports, and text references across the entire repository.
From the root directory, run:
Follow the interactive prompts to enter your Project Name, Django Project Name (e.g., core_api), and short description.
Do this first!
You should run this script immediately after cloning the repository, before you make any custom code changes or start your database.
To change the name of the system in emails (like OTP codes), simply update the BRAND_NAME variable in your .env file.