Appearance
API Gateway
The API gateway is apps/app running on port 3000. There is no separate gateway process — all routing, auth, middleware, and business logic handlers live inside this single Express application.
Routing
Routes are defined using oRPC (OpenAPI-ready RPC framework), which provides type-safe handlers and auto-generates the OpenAPI spec served at /spec.json.
apps/app/src/v1/
├── campaign/ # Campaign CRUD + launch/pause/resume
├── leads/ # Lead groups + contact management
├── brand/ # Brand settings and information
├── conversations/ # Inbox + reply handling
├── payments/ # Chargebee subscription + credits
├── sender/ # Gmail sender account management
├── webhooks/ # Inbound webhook receivers
└── ...Middleware Stack
Applied to all requests in order:
| Middleware | Source | Purpose |
|---|---|---|
securityMiddleware() | @ce-sdr/shared | Helmet security headers |
gatewayCors() | @ce-sdr/shared | CORS with ALLOWED_ORIGINS env var |
rateLimiter() | @ce-sdr/shared | Per-IP rate limiting |
requestLogger("api-gateway") | @ce-sdr/shared | Structured HTTP request logging |
| Better-Auth handler | @ce-sdr/auth | Mounted at /auth/* |
Error handling:
notFoundHandler()— 404 for unknown routeserrorHandler()— Centralized error response formatting
Special Endpoints
| Path | Purpose |
|---|---|
GET /health | Health check (used by ECS) |
GET /spec.json | Auto-generated OpenAPI spec |
/bull | Bull Board queue monitoring UI (password protected) |
POST /internal/broadcast | Internal WebSocket broadcast (service-to-service only) |
/auth/* | Better-Auth handler (login, OAuth, sessions) |
WebSocket
Socket.io is mounted on the same Express server. The worker service calls POST /internal/broadcast when async jobs complete, which triggers real-time pushes to connected browser clients scoped by brandId.