Skip to main content

backend — Core API

The backend repo (package name nodvel) is the platform's core API server. It is the largest service and the integration hub: clients call it, and it orchestrates the microservices and external CRMs.

  • Stack: Express 4 + Mongoose/MongoDB, Socket.IO (+ Redis adapter), built on the Nodevel framework.
  • Runtime: Node 22 (container), FFmpeg installed, 6 GB heap.
  • Deploy: Docker → ECR → EKS, 4 API replicas + 1 scheduler pod.

Responsibilities

  • Auth & RBAC — registration, sessions, JWT, passport OAuth (Google/Facebook/ Apple), teams, branches. Authorization is user_type + the per-user permissions[] array — the legacy roles/permissions layer (PermissionService, RoleController, PermissionController, populate('roles') in the bearer strategy) was removed 2026-07-20.
  • Tenancy & billing — companies, agencies, subscriptions, packages, add-ons, invoices (Stripe + Xero).
  • Visitor identity — the identity graph: Person/PersonProfile resolution, IP signals, enrichment.
  • CRM sync — bidirectional sync to GoHighLevel, HubSpot, Slack.
  • Realtime — the main Socket.IO server for dashboards, call/chat signalling, agent presence.
  • Scheduler — ~38 cron jobs (subscriptions, reporting, CRM sync, Knox metrics).
  • Orchestration — hands work to ms-ai, ms-sessions, ms-communication.

Boot flow

index.jsotel.js (Sentry/OTel) → Application.run() (Nodevel sequence) → app/hooks.js:

  • boot() — middleware (file upload, trust proxy, CORS, rate limiting), then loads services (Redis, Auth, Mongo, Scheduler, Logger, Mail, EmailQueue, CrmSync) and the identity subsystem chain (IdentityGraphRenderer → IdentityGraphConfig → SubscriptionGate → IdentityGraph → Verifier → PersonResolver → PersonWatch), plus Knox auto-engagement and CRM enrichment.
  • server() — starts Socket.IO, mounts Bull Board (/admin/queues), Sentry error handler.

Directory map

PathContents
app/configs/app/service/database/redis/AWS/Azure/CRM config
app/controllers/80+ controllers (Admin*, Agency*, AI*, Call*, Chat*, Company*, Payment*, Reporting*, …)
app/models/~70 Mongoose models (see Data Stores)
app/routes/80+ route files; api.js is the root
app/services/~45 service classes (GoHighLevelService, HubspotService, StripeService, IdentityGraphService, PersonResolverService, SocketService, SchedulerService, …)
app/jobs/~38 cron jobs
app/lib/cross-service clients (msAiHandoff.js, msAiKnoxClient.js, msSessionsRecordingClient.js), ghlResilience.js, ipSignals.js
core/the Nodevel framework
eks/prod/K8s manifests (backend + scheduler deployments, service)
public/served visitor scripts (widget.js, knock-socket.js, Twilio/ElevenLabs clients)

Key route groups

AreaRoutes
AuthauthRoutes.js — login, signup, OAuth, refresh
AgencyagencyRoutes.js — multi-client mgmt, staff, packages
CompanyCompanyRoutes.js — settings, website, FAQ, integrations
ChatchatRoutes.js — messages, chatbot training
CallscallRoutes.js, internalAiCallRoutes.js, aiInboundAgentRoutes.js, aiOutboundCallRoutes.js
SessionsuserSessionRoutes.js — visitor analytics
IdentityidentityGraphRoutes.js, adminIdentityRoutes.js
CRMgoHighLevelRoutes.js, hubspotRoutes.js — webhooks + sync
PaymentssubscriptionRoutes.js, stripeRoutes.js
WalletinternalTelephonyRoutes.js (ms-ai → backend: /internal/telephony/wallet|debit|notify), GET /subscription/wallet-transactions
PlaygroundplaygroundRoutes.js — public no-login sandbox + agency/admin management
ReportingreportRoutes.js, statsRoutes.js, statsV2Routes.js
StorageadminStorageRoutes.js — super-admin storage stats + recording cleanup proxy

Scheduler & cron

Cron runs on a dedicated scheduler pod (SERVICE_CRON=true) so jobs fire exactly once. SchedulerService registers node-cron jobs wrapped by CronMonitor (Redis-backed history at /admin/cron). Representative jobs:

CadenceJobs (examples)
1 minActiveSessionJob, UserOnlineStatusJob, OutboundCallGhlSyncJob, PostCallWebhookFallbackJob, BalanceAutoRechargeJob (wallet top-up)
5 minFactExtractionTriggerJob, AiCallGhlTranscriptSyncJob, MsAiHandoffSweeperJob
10 minDailyBriefEmailJob, SubscriptionExpireJob, SubscriptionSuspensionJob, FunnelSweepJob
15 minRecordingBackfillSweeperJob (backfills failed ms-sessions handoffs)
HourlyAgentKUsageEmitJob (provider usage → ms-ai cost-tracking), FunnelDailyStatsJob
DailyKnoxBaselineMetricsJob (02:00), KnoxGhlSyncJob (03:00), FunnelDormancyJob (04:00), NoxFunnelReconcileJob (04:30), FunnelBackfillJob (05:00)

Cron runs in the schedular deployment, not the API pods — it has its own configmap (Apps/PROD/schedular/configmap.yaml); provider API keys must exist in both configmaps or cron feeders silently break.

Retired this window: ReportingEmailJob is unscheduled (replaced by the Nox daily brief) and GhlTipsEmailJob is stopped (both commented out in SchedulerService).

External integrations

GoHighLevel (GoHighLevelService.js, ~61 KB — the biggest integration), HubSpot, Slack, Twilio, ElevenLabs, Firebase (FCM), AWS (S3/CloudFront/ACM), Azure CDN, Stripe, Xero, Simpro, Tapi (IMAP work-order emails), Clearbit/Apollo/HappierLeads (enrichment), Calendly, Dualhook (WhatsApp), Rb2b. Each lives in app/services/<Name>Service.js with config under app/configs/. See CRM Integration for the sync mechanics.

Realtime

SocketService creates the Socket.IO server with a Redis adapter (in-memory fallback for single-pod dev). Session→socket mappings live in Redis (session_sockets:, 24h TTL); heartbeat writes are throttled via heartbeat_status: (5m TTL). Events drive live dashboards, call status, typing indicators, and agent availability.

Config & deployment

  • Key env: MS_AI_URL / MS_SESSION_URL / MS_COMMUNICATION_URL, MS_AI_SECRET_TOKEN, CRON_ENABLED/SERVICE_CRON, FILE_STORAGE, DB_*, plus per-integration credentials. Observability via BUGSINK_DSN (Sentry) and Winston.
  • EKS: backend-deployment.yaml (4 replicas, 8–12 Gi mem), separate schedular-deployment.yaml (1 replica, cron leader), backend-service.yaml (ClusterIP). Config via backend-cm ConfigMap. Namespace kk-ns-prod.
  • CI: buildspec.yml builds the image, pushes to ECR, and kubectl rollout restarts the deployments. See CI/CD.