Skip to content

NATS

Describe NATS as the messaging backbone connecting the shared control plane to each tenant edge, and the subject hierarchy it uses.

NATS carries originate requests from the pacer to the edge call engines and streams real-time call, agent and queue events back for the supervisor and agent dashboards. It decouples the control plane from the edges so either side can restart without losing the contract.

Subjects follow t.<tenant>.<domain>.<event> (built by internal/events), with a t.global.<…> variant for platform-wide events.

Subject Direction
t.<tenant>.node.<NODE_ID>.call.originate pacer → a specific edge: place this call
t.<tenant>.call.amd_result worker → control: AMD classification
t.<tenant>.call.> realtime hub subscribe (call events for a tenant)
t.<tenant>.call.dtmf call engine → supervisor dashboard
t.<tenant>.agent.<id>.state agent state transitions
t.<tenant>.queue.<id>.<kind> queue caller events (joined / assigned / abandoned / overflowed)
t.<tenant>.config.ivr.changed, t.<tenant>.config.routing.changed config invalidation
Terminal window
# App node (shared infra):
NATS_URL=nats://nats-host:4222
# Edge node — tenant-scoped credentials (ADR-011):
NATS_URL=nats://edge_<TENANT_UUID>:<password>@nats-host:4222

Per-tenant NATS accounts are minted by the provisioning flow (POST /api/v1/platform/tenants/{id}/provision-edge) and permit publish/subscribe only on t.<tenant>.> (plus _INBOX.>). Cross-tenant subjects are denied.

sequenceDiagram
  participant Pacer
  participant NATS
  participant CallEngine
  Pacer->>NATS: publish t.<tenant>.node.<NODE_ID>.call.originate
  NATS->>CallEngine: deliver originate (this node only)
  CallEngine-->>NATS: t.<tenant>.call.answered / .hangup / .amd_result
  NATS-->>Pacer: deliver events (connect-rate, abandonment)
  • Each originate is targeted at one node subject, so two edges for a tenant never double-dial.
  • A mismatched NODE_ID between the pacer’s target and the edge’s subscription silently places zero calls — keep them aligned.
  • Credential rotation requires the edge .env to be redeployed to take effect.