Architecture

Apostol CRM combines two frameworks into a single backend: a high-performance C++20 HTTP server and a PostgreSQL-based business logic engine. Together they deliver 418 REST API endpoints, OAuth 2.0 authentication, a workflow engine, WebSocket pub/sub, background processing, and file storage -- all in a single binary.

Overview

FrameworkRoleWhat it provides
libapostolC++20 serverHTTP/WebSocket server, async PostgreSQL, single epoll event loop -- 507K RPS
db-platformPostgreSQL layer26 PL/pgSQL modules, 100+ tables, 800+ functions -- REST API, auth, workflow, entities

No PHP, Python, or Node.js. HTTP requests flow directly from C++ to PostgreSQL -- zero intermediate layers, sub-millisecond latency.

Request Flow

Apostol CRM Architecture

The C++ layer handles HTTP parsing, TLS, connection pooling, WebSocket, JWT verification, and async I/O. The database layer handles business logic, REST routing, access control, workflow transitions, and data storage. They communicate through libpq -- one event loop, no threads.

Module System

The C++ server is assembled from independent modules. Each module is a separate GitHub repository that can be included or excluded.

Workers -- handle HTTP/WebSocket requests

ModuleDescription
AppServerAuth-aware REST API dispatch to PostgreSQL
AuthServerOAuth 2.0 (6 grant types), JWT, cookie auth, PKCE
WebSocketAPIJSON-RPC + pub/sub over WebSocket
FileServerFile serving with JWT authentication
PGHTTPRaw HTTP-to-PL/pgSQL function dispatch
WebServerStatic files, SPA support, Swagger UI

Worker registration order matters (first match wins):

static inline void create_workers(Application& app)
{
    // Auth endpoints: /oauth2/*
    if (app.module_enabled("AuthServer") && app.has_db_pool())
        app.module_manager().add_module(std::make_unique<AuthServer>(app));

    // REST API: /api/* (with auth)
    if (app.module_enabled("AppServer") && app.has_db_pool())
        app.module_manager().add_module(std::make_unique<AppServer>(app));

    // Static files: /* (last -- catches everything else)
    app.module_manager().add_module(std::make_unique<WebServer>(app));
}

Helpers -- background modules in the helper process

ModuleDescription
PGFetchLISTEN/NOTIFY triggers outbound HTTP requests
PGFileLISTEN/NOTIFY triggers file sync (PostgreSQL to filesystem)

Processes -- independent background daemons

ProcessDescription
MessageServerEmail/SMS/push dispatch via SMTP, FCM, HTTP API
TaskSchedulerCron-like job execution from db.job queue
ReportServerLISTEN-driven report generation

Database Architecture

The PostgreSQL layer uses a two-layer design with four schemas:

SchemaRoleExample
restREST dispatcher -- routes URL paths to API functionsrest.sensor('/sensor/list', '{}')
apiPublic API -- views and CRUD wrappers with access checksapi.list_sensor(...)
kernelBusiness logic -- core functions and viewsCreateSensor(...), EditSensor(...)
dbData layer -- tables, indexes, triggersdb.sensor

A typical request flows through all four layers:

POST /api/v1/sensor/list
  -> rest.sensor('/sensor/list', payload)
    -> api.list_sensor(search, filter, limit, offset, orderby)
      -> SELECT * FROM kernel.ObjectSensor (view)
        -> JOIN db.sensor, db.document, db.object, ...

Platform modules (26)

The db-platform provides 26 reusable PL/pgSQL modules:

  • Core: entity, class, type, object, document, reference
  • Auth: session, user, oauth2, token
  • Workflow: state, method, transition, action, event
  • Access control: ACU (class-level), AOU (object-level), AMU (method-level)
  • Infrastructure: job, message, file, log, notification

Three database roles

RoleUsed byPurpose
daemonWorkersHTTP request handling
apibotHelper and processesBackground tasks
kernelAdministrative operationsSchema migrations, setup

Entity System

Apostol CRM ships with 30 business entities (clients, invoices, payments, subscriptions, devices, and more). Each entity follows a standard 8-file convention:

entity/object/document/myentity/
├── table.sql       # CREATE TABLE, indexes, triggers
├── view.sql        # 3 kernel views (data, access, full object)
├── routine.sql     # Create*/Edit*/Get* functions
├── api.sql         # API schema views + 6 CRUD wrappers
├── rest.sql        # REST dispatcher (6 standard routes)
├── event.sql       # 9 event handler functions
├── init.sql        # Workflow: class, type, states, methods, transitions
└── create.psql     # Master install script

Every entity inherits from either document (business objects with lifecycle and area-based access) or reference (lookup/catalog data). Creating a new entity means creating these 8 files and wiring them into the parent.

Workflow Engine

Every entity has a built-in state machine. The default lifecycle:

       ┌────── restore ───────┐
       v                      |
  [Created] --enable--> [Enabled] --disable--> [Disabled]
       |                    |                       |
       |--disable-->  [Disabled]                    |--enable--> [Enabled]
       |                    |                       |
       |--delete-->   [Deleted]  <--delete--   [Deleted] <--delete--

Four state types: created, enabled, disabled, deleted.

You can customize the workflow per entity by adding custom states, methods, transitions, and events. For example, a charging station might have available, unavailable, and faulted as sub-states within the enabled state type. See the Workflow Customization guide.

Module Composition

libapostol is designed as a module constructor. You pick the modules you need:

  • Minimal (no database): WebServer only -- static file serving + healthcheck
  • HTTP gateway: PGHTTP + WebServer + PGFetch -- routes HTTP requests to PostgreSQL
  • Full backend: All workers + helpers + processes -- complete platform with auth, files, WebSocket, background tasks
  • Custom: Pick any combination. Each module is standalone

Production Projects

Projects built on the same architecture:

ProjectIndustry
ChargeMeCarEV charging station management (OCPP)
Apostol ARBCrypto futures arbitrage aggregator
PlugMeOCPP Central System
Ship Safety ERPMaritime safety ERP
CopyFrogAI content generation
Campus CORSGNSS correction data system