Skip to main content

Architecture Overview

apptor flow is a multi-module platform built around an actor-based asynchronous execution engine. This page gives you the full system picture before you dive into individual modules.


System Diagram


Module Map

apptor flow is a Gradle multi-module Java project with 26 modules:

ModuleRole
apptor-flow-sdkDomain models: Node, NodeType enum, Variable, LoopCharacteristics, execution events
apptor-flow-json-parserConverts workflow JSON text → typed domain models; type mapper, parser classes per node type
apptor-flow-coreExecution engine: node handlers (24), process lifecycle, actor dispatch, variable resolution
apptor-actor-frameworkGeneric actor model: actor pools, message queues, thread management
apptor-flow-apiREST API layer: 41 controllers, Micronaut routes, filters, DTOs
apptor-flow-persistenceJPA/Hibernate entities, repositories, Liquibase changelog management
apptor-flow-configConfiguration loading, environment-specific settings
apptor-flow-messagingInternal messaging: topics, event emitter, subscriber framework
apptor-flow-bpmnBPMN-compatible process model constructs
apptor-flow-schedulerTime-based trigger scheduling
apptor-flow-pluginsPlugin execution framework for node event handlers
apptor-flow-sql-pluginSQL execution plugin (direct and AI-assisted query modes)
apptor-rest-clientHTTP client for REST API service tasks
apptor-secretsEncrypted secret storage and retrieval
apptor-flow-ragRAG pipeline: chunking, embedding, vector search
apptor-rag-sdkRAG domain models and interfaces
apptor-flow-voiceVoice call automation: Twilio integration, OpenAI voice models
apptor-mailEmail sending: SMTP, connection management
apptor-driveGoogle Drive integration for document access
apptor-drive-syncDrive document sync to knowledge base
apptor-flow-task-server-sdkSDK for building external task servers
apptor-flow-task-serverRuntime for external task servers
apptor-flow-vertical-integrationsDomain model framework: verticals, actions, provider mappings
apptor-auth-apptoridapptor ID authentication provider integration
apptor-oauthOAuth credential management for integrations
apptor-workflow-creatorAI-powered workflow generation from natural language

Request Flow: Execute a Workflow


Webhook Pipeline

Webhooks are processed through a dedicated three-stage pipeline, separate from the main REST request flow.

Verification Engine

WebhookVerifierRegistry maps each authType to its verifier. Every verifier receives all active secrets and tries each — supporting zero-downtime secret rotation where both old and new secrets are valid simultaneously.

Normalization

After verification, WebhookNormalizerRegistry extracts standard fields (event type, event ID, timestamp) from provider-specific locations. This means flows always receive {webhookEventType} and {webhookEventId} regardless of which provider sent the event.

Secret Storage

Secrets are encrypted at rest using AES-256-GCM with a random IV per secret. The encryption key is loaded from the apptor.secret.encryption-key environment variable. Secrets are cached for 5 seconds only and never written to logs.

Circuit Breaker

Each endpoint tracks consecutive_failures. At 5 failures the endpoint moves to CIRCUIT_BREAKER status and stops accepting events. An in-app notification is sent to the org. Reset is manual (admin action) after investigating the cause.

Retry

Transient processing failures are retried 7 times with exponential backoff (1m → 5m → 15m → 1hr → 6hr → 24hr → DLQ). Verification failures are not retried — they are deterministic.


Key Architectural Decisions

Actor-Based Execution

Each node type has its own named actor pool with a configurable number of threads. This means:

  • A slow SQL query never blocks the email actor
  • AI Task threads (1) can be kept low without affecting other throughput
  • Thread allocation can be tuned per deployment in flow-config.json

Asynchronous by Default

The engine returns immediately after queuing the first node. Clients poll for status via GET /process/instance/{id} or stream logs via SSE. This means workflows of any length do not block the API thread.

State in PostgreSQL

All execution state — variables, node status, event subscriptions — is persisted in PostgreSQL. The engine can restart or be horizontally scaled without losing in-flight executions (pending messages are re-queued from the queue_item table).

JSON Workflow Format

Workflows are stored as JSON strings (processText) and parsed at execution time by apptor-flow-json-parser. This means the same workflow definition can be versioned, exported, imported, and diffed like any other text file.

Variable Resolution

Node property values containing {variableName} are resolved by TemplateVariableResolver just before the node executes. The resolver reads from the execution's variable context. See Variable Reference for full details.


Technology Stack

ConcernTechnology
LanguageJava 21
FrameworkMicronaut 4.4.2
BuildGradle (multi-module)
DatabasePostgreSQL 16
MigrationsLiquibase
ORMJPA/Hibernate (Micronaut Data)
CacheHazelcast
AILangChain4j
VoiceTwilio + OpenAI
AuthOIDC (Micronaut Security) + custom API Key filter
FrontendAngular 18+, TypeScript
DiagramGoJS
ScriptingGraalVM Polyglot (JavaScript, Python)

Further Reading