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​