Workflow Type Registry Examples

Developer guide for the Enezaframework workflow engine. Part of the Workflow series.

Table of Contents

  1. Overview
  2. Example 1 — Override a Framework Workflow
  3. Example 2 — Add a Workflow with Multiple Models
  4. Example 3 — Runtime Registration in AppConfig
  5. Example 4 — Full Project Setup
  6. Related Guides

Overview

These examples show the four common registry operations: override, extend, runtime-register, and full project setup. Each uses the same model-config schema from Workflow Model Configuration.


Example 1 — Override a Framework Workflow

Project definitions replace the framework definition for the same workflow name entirely.

python
# myproject/workflowconfig.py

class WorkflowTypeConfig:
    WORKFLOW_TYPE_REGISTRY = {
        'InvoiceWorkflow': [
            {
                'slug': 'my_invoice',
                'label': 'My Custom Invoice',
                'app_label': 'billing',
                'model_name': 'MyInvoice',
                'relationships': [
                    {
                        'field_name': 'client',
                        'label': 'Client',
                        'type': 'fk',
                        'related_app': 'crm',
                        'related_model': 'Client',
                    },
                ],
            },
        ],
    }

After this, InvoiceWorkflow exposes only MyInvoice — the framework's Frameworktestdocument entry is gone.


Example 2 — Add a Workflow with Multiple Models

python
# myproject/workflowconfig.py

class WorkflowTypeConfig:
    WORKFLOW_TYPE_REGISTRY = {
        'ProcurementWorkflow': [
            {
                'slug': 'purchase_requisition',
                'label': 'Purchase Requisition',
                'app_label': 'procurement',
                'model_name': 'PurchaseRequisition',
                'relationships': [
                    {
                        'field_name': 'requester',
                        'label': 'Requester',
                        'type': 'fk',
                        'related_app': 'enezacommon',
                        'related_model': 'User',
                    },
                ],
            },
            {
                'slug': 'purchase_order',
                'label': 'Purchase Order',
                'app_label': 'procurement',
                'model_name': 'PurchaseOrder',
                'relationships': [
                    {
                        'field_name': 'vendor',
                        'label': 'Vendor',
                        'type': 'fk',
                        'related_app': 'procurement',
                        'related_model': 'Vendor',
                    },
                    {
                        'field_name': 'requisition',
                        'label': 'Requisition',
                        'type': 'fk',
                        'related_app': 'procurement',
                        'related_model': 'PurchaseRequisition',
                    },
                ],
            },
        ],
    }


class ProjectWorkflowNames(Workflownames):
    PROCUREMENTWORKFLOW = 'ProcurementWorkflow', 'Procurement Workflow'

Each entry has a unique slug; the query builder shows both models and the user picks one.


Example 3 — Runtime Registration in AppConfig

python
# myapp/apps.py
from django.apps import AppConfig


class MyAppConfig(AppConfig):
    name = 'myapp'

    def ready(self):
        from enezaworkflowengine.services.workflow_type import WorkflowTypeRegistry

        WorkflowTypeRegistry.register('MyAppWorkflow', [
            {
                'slug': 'my_app_model',
                'label': 'My App Model',
                'app_label': 'myapp',
                'model_name': 'MyAppModel',
                'relationships': [
                    {
                        'field_name': 'related_thing',
                        'label': 'Related Thing',
                        'type': 'fk',
                        'related_app': 'myapp',
                        'related_model': 'RelatedThing',
                    },
                ],
            },
        ])

Register in ready() so the entry exists before the first request. See Workflow Dynamic Registration.


Example 4 — Full Project Setup

python
# myproject/workflowconfig.py
from enezaworkflowengine.models.choices import Workflownames


class ProjectWorkflowNames(Workflownames):
    """Extended workflow names including project-specific workflows."""
    SALESORDERWORKFLOW = 'SalesOrderWorkflow', 'Sales Order Workflow'
    PROCUREMENTWORKFLOW = 'ProcurementWorkflow', 'Procurement Workflow'


class WorkflowTypeConfig:
    """Project-level workflow type registry."""
    WORKFLOW_TYPE_REGISTRY = {
        'SalesOrderWorkflow': [
            {
                'slug': 'sales_order',
                'label': 'Sales Order',
                'app_label': 'sales',
                'model_name': 'SalesOrder',
                'relationships': [
                    {
                        'field_name': 'customer',
                        'label': 'Customer',
                        'type': 'fk',
                        'related_app': 'crm',
                        'related_model': 'Customer',
                    },
                    {
                        'field_name': 'items',
                        'label': 'Order Items',
                        'type': 'm2m',
                        'related_app': 'inventory',
                        'related_model': 'InventoryItem',
                    },
                ],
            },
        ],
        'ProcurementWorkflow': [
            {
                'slug': 'purchase_order',
                'label': 'Purchase Order',
                'app_label': 'procurement',
                'model_name': 'PurchaseOrder',
                'relationships': [
                    {
                        'field_name': 'vendor',
                        'label': 'Vendor',
                        'type': 'fk',
                        'related_app': 'procurement',
                        'related_model': 'Vendor',
                    },
                ],
            },
        ],
    }
python
# myproject/settings.py
MY_PROJECT_WORKFLOWS_NAME = 'myproject.workflowconfig.ProjectWorkflowNames'
MY_PROJECT_WORKFLOWS_CONFIG = 'myproject.workflowconfig.WorkflowTypeConfig'
flowchart LR
    CFG["ProjectWorkflowNames"] --> SET1["MY_PROJECT_WORKFLOWS_NAME"]
    WTC["WorkflowTypeConfig"] --> SET2["MY_PROJECT_WORKFLOWS_CONFIG"]
    SET1 --> CHOICES["Dropdown choices"]
    SET2 --> REG["Merged registry"]
    REG --> QV["Query builder"]
    CHOICES --> QV