🧩 Components
- Django service (root:
conf/)- API:
apps/api/ - Workflow engine:
apps/workflows/ - Admin: Django Admin (
/admin/)
- API:
- Celery + Redis
- background workflow tasks and scheduler
- PostgreSQL
- storage for workflow requests/responses
- Kafka consumer
- listens to SlackNotificationEvent and starts workflows
- Integrations
- directory / manager / statistics / SSO
- Slack, link‑switcher
🔁 Workflow execution flow
High‑level flow (see apps/workflows/consumer.py and apps/workflows/base.py):
- Client calls
POST /api/v1/workflows/start - A
WorkflowFunctionRequestis created for the internal workflowstart_new_workflow - Local consumer (
run_workflow_starter) executesStartWorkflowFunction StartWorkflowFunctioncalculates the first step and redirects to the real workflowWorkflowRequestsGenerator(run_workflow_dispatcher) consumes responses and builds the next step- A new
WorkflowFunctionRequestis created for the next service/function - External services return
WorkflowRequestResponse - The last step is marked
final=True, and the result is available via API
🧱 Step model
A workflow is a sequence of steps (WorkflowStep):
- each step knows service and function
- step input data is built via mapping:
Workflow.input("field")— take a field from workflow inputprev_step.output("field")— take a field from previous step output- you can use
.map(...)and.merge(...)by keys
🧠 Routing between services
WorkflowRequestsGenerator tracks available consumers per service:
- uses
WorkflowConsumerHeartbeat - picks the consumer with the lowest load
- reassigns
PENDINGrequests if no consumer is available
🔎 Debug tracing
All workflow requests/responses are available via:
GET /api/v1/workflows/debug?request_id=<id>
This is useful to inspect step chains and data passed through the workflow.