Skip to main content

routing-engine — Local Development Setup

Status: populated | Last updated: 2026-04-18

Prerequisites

ToolVersionInstall
Node.js≥ 20 LTSnvm install 20
pnpm≥ 9npm i -g pnpm
Docker + Docker Compose≥ 24docker.com
grpcurllatestbrew install grpcurl
protoc≥ 25brew install protobuf

1. Clone and Install

git clone https://github.com/ghasitech/sms-gateway.git
cd sms-gateway/services/routing-engine
pnpm install

2. Start Dependencies (Docker Compose)

A docker-compose.dev.yml is provided at the repository root that starts all dependencies for local development.

# From repo root
docker compose -f docker-compose.dev.yml up -d postgres redis nats

Services started:

ServicePortCredentials
PostgreSQL5432postgres:devpassword
Redis6379No auth
NATS JetStream4222No auth

3. Seed the Database

# Apply schema migrations
pnpm db:migrate

# Seed test routing rules and operators
pnpm db:seed

Seed data includes:

  • 3 operators (Roshan-AF, MTN-AF, AWCC-AF)
  • Destination prefixes: +93, +9375, +9377, +9379
  • Routing rules: PRIORITY for +93 (global), COST for +9375 (account-scoped)

4. Environment Variables

Copy the example env file:

cp .env.example .env

.env.example:

# PostgreSQL (read-only user for routing queries)
DATABASE_URL=postgresql://routing_engine_ro:devpassword@localhost:5432/sms_gateway?schema=ops_routing

# Redis
REDIS_URL=redis://localhost:6379

# NATS
NATS_URL=nats://localhost:4222

# Service ports
GRPC_PORT=50051
MGMT_PORT=3001

# Logging
LOG_LEVEL=debug

# TLS (disabled in local dev)
GRPC_TLS_ENABLED=false

5. Run the Service

# Development mode with hot reload
pnpm dev

# Production build
pnpm build
pnpm start

6. Test a gRPC Call Locally

# Reflection-based call (no TLS in dev)
grpcurl -plaintext \
-d '{"to": "+93791234567", "account_id": "00000000-0000-0000-0000-000000000001", "message_type": 1}' \
localhost:50051 \
ghasi.sms.routing.v1.RoutingService/SelectOperator

Expected response:

{
"operatorId": "550e8400-e29b-41d4-a716-446655440001",
"host": "smpp1.roshan.af",
"port": 2775,
"systemId": "smsgtw01",
"tpsLimit": 100,
"strategy": "ROUTING_STRATEGY_PRIORITY"
}

7. Publish a Test NATS Health Event

# Install NATS CLI
brew install nats-io/nats-tools/nats

# Publish an UNBOUND event for operator 550e8400-...
nats pub operator.health '{
"version": "1.0",
"eventId": "test-event-001",
"occurredAt": "2026-04-18T10:00:00.000Z",
"operatorId": "550e8400-e29b-41d4-a716-446655440001",
"operatorName": "Roshan-AF",
"status": "UNBOUND",
"previousStatus": "BOUND",
"reason": "manual test"
}'

8. Run Tests

# Unit tests
pnpm test:unit

# Integration tests (requires Docker)
pnpm test:integration

# All tests with coverage
pnpm test:cov