Skip to content

Architecture

Serve as the landing page for the architecture section — deeper, component-level design documentation that builds on the high-level Architecture Overview.

Get2Dial is a Go + Next.js monorepo. The runtime splits into a shared control plane and per-tenant edges:

  • Control plane (cmd/control) — a single Go binary serving the /api/v1 HTTP API on port 8080 (a stdlib net/http mux with Go 1.22 method-prefixed patterns). It wires ~40 repositories/services over PostgreSQL, Redis and NATS, and runs background workers: the dialer pacer, the queue overflow sweeper, a live-metrics publisher, a transactional outbox relay, a lead-reset worker, trial/demo sweepers, an agent-presence sweeper and a scheduled-report worker.
  • Edge — the call engine (cmd/callengine) and node agent (cmd/nodeagent) alongside OpenSIPS, rtpengine and FreeSWITCH. Per ADR-011 the edge is pool-less: it reads config via node-authenticated API calls (READ_SOURCE=api) rather than a shared database connection.

State lives in three tiers: PostgreSQL/TimescaleDB (durable config, CDRs, audit), Redis (call context, pacing counters, agent presence), and MinIO (audio assets, recordings, voicemail).

flowchart TB
  subgraph CP[Control plane]
    API[/api/v1 HTTP API/]
    W[Background workers]
  end
  API --- PG[(PostgreSQL + TimescaleDB)]
  API --- RD[(Redis)]
  API --- NA{{NATS}}
  API --- MIN[(MinIO)]
  W --- API
  NA <--> EDGE[Per-tenant edges]

Not applicable. See the per-subsystem pages for environment variables and deployment.

The state-machine code (lead state, agent state, queue selection, compliance) is written as pure functions with no I/O so it is unit-testable, with Postgres repos and Redis hot-path state layered on top. See Agents and Campaigns.

  • Architecture decisions are recorded as ADRs; this section describes the resulting design, while ADRs capture the why.
  • Tenant isolation is enforced in depth: JWT request scoping, Postgres RLS, per-tenant Redis ACLs and per-tenant NATS subject permissions.