Skip to content

🧩 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

  1. BaseModel (core/models.py): The foundation of your database. Automatically grants your models UUID primary keys and created_at / updated_at timestamps. Use this for any standard relational data.
  2. 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:

  1. BaseGenerationViewSet (ai_core/views.py): Gives your AI endpoints rate throttling, cost calculation, wallet balance checks, and credit deductions automatically.
  2. BaseGenerationTask (ai_core/tasks.py): Gives your Celery tasks status tracking, error handling, SSE streaming updates, and auto-refunds on failure.
  3. 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 CoreProvider 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:

python init_backend.py

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.