Skip to content

Nexivo Admin Portal

The Nexivo Admin Portal is the super-admin web application for managing the entire Nexivo omnichannel contact centre platform. It is used by platform administrators and tenant managers to configure AI agents, channels, workflows, knowledge bases, campaigns, reporting, and user roles.

Source

VSCodeProjects/Nexivo/nexivo-admin — React 18 / TypeScript / Vite SPA


Tech Stack

Layer Technology
Framework React 18.3 + TypeScript 5.6
Build Vite 6
Routing React Router DOM 7
State Redux Toolkit 2.5 + Redux Persist
Auth Keycloak JS 26 (PKCE flow)
UI components Fluent UI React 8 + Fluent UI v9 + Ant Design 5
Styling Tailwind CSS 3.4
Forms React Hook Form 7 + Zod 4 validation
Charts ApexCharts · Google Charts · Recharts
Workflow editor @xyflow/react 12 (React Flow)
Rich text React Quill (Quill.js)
HTTP Axios 1.7
Real-time react-use-websocket + RxJS 7
Media HLS.js 1.6 + custom cc-audio-player
Maps Leaflet 1.9 + React Leaflet 4
Animations Framer Motion 12
DI Inversify React 1.2

Authentication

Authentication is handled entirely by Keycloak using the PKCE flow.

Initialisation

On app load AuthContext (src/context/authContex.tsx) initialises Keycloak and silently logs the user in. Once authenticated:

  • Axios apiConnector and adminConnector have the Authorization: Bearer <token> header injected automatically.
  • Token refresh runs every 30 seconds; a refresh is forced when less than 70 seconds of validity remain.
  • On expiry, the user is redirected to the Keycloak logout endpoint.

Tenant & licence extraction

The JWT contains an organization object. Two hooks abstract this:

const { hasLicense, hasResourceAccess } = useAuthContext()
const getTenantId = useAuthTenant()  // memoised extraction from token

hasLicense(license) checks token.organization.licenses[]; hasResourceAccess(resource) checks Keycloak client roles. Both are used by LicenseGuard to gate routes and UI elements.

Environment variables

Variable Purpose
VITE_KEYCLOAK_BASE_URL Keycloak server URL
VITE_KEYCLOAK_REALM Realm name
VITE_KEYCLOAK_CLIENT_ID OAuth client ID
VITE_API_BASE_URL Backend API base URL
VITE_KNOWLEDGE_TENANT_ID Fallback tenant ID

Architecture

graph TD
    Browser -->|PKCE login| Keycloak
    Browser -->|REST / Axios| API[Platform API]
    Browser -->|WebSocket| WS[Live Updates]
    Browser -->|HLS| Media[Media Server]

    subgraph SPA[Nexivo Admin SPA]
        Router[React Router v7] --> ProtectedLayout
        ProtectedLayout --> Pages
        Pages --> Services[45 Service Files]
        Pages --> Redux[Redux Store]
        Pages --> Contexts[Context Providers]
    end

All routes are wrapped in ProtectedLayout, which enforces authentication. LicenseGuard then provides per-route licence enforcement on top.


Pages & Features

Dashboards

Route Page Key features
/dashboards/overview Overview Dashboard Drag-drop widget grid; KPI cards; call trends; team/agent/queue widgets; layout persisted to Redux + localStorage
/dashboards/ai AI Analytics Model usage; token consumption; AI conversation quality metrics
/dashboards/service-level Service Level SLA compliance; wait-time analysis; SLO visualisation
/dashboards/live-queue Live Queue Real-time queue depth; agent availability; WebSocket-based live updates

Dashboard layouts are stored in overviewLayoutSlice / aiOverviewLayoutSlice Redux slices and persisted across sessions via redux-persist.


AI Agents

Route group: /ai-agents — licence-gated to AI_AGENT.

  • Lists all agents with status badges: Active · Inactive · Provisioning · Failed
  • Quick actions: edit, view, duplicate, delete
  • Avatar display with fallback initials

Create / Edit agent (multi-step wizard)

Step 1 — Basic info      name · greeting · language · direction (inbound/outbound)
Step 2 — Personality     system prompt (rich text) · model provider selection
Step 3 — Execution       concurrency · timeout · runtime settings
Step 4 — Knowledge base  KB category assignment (modal picker)
Step 5 — Tasks           workflow task list · execution order

Agent creation requires the AI_AGENT_CREATOR licence. The final POST /tenants/{id}/agents payload is assembled from all wizard steps.

Key model:

interface AIAgentItem {
  agent_id: string
  agent_name: string
  agent_prompt: string
  base_greeting: string
  status: 'active' | 'inactive' | 'provisioning' | 'failed'
  agent_type: 'inbound' | 'outbound'
  agent_category: 'ai_ivr' | 'ai_agent' | 'human_agent'
  language: string | string[]
  metadata: {
    avatar_url?: string
    tools?: string[]
    teams?: string[]
    outbound_variables?: Record<string, string>
  }
  config_version: number
}

Background Agents

Separate agent type for non-voice, autonomous background task execution. Managed under /background-agents with its own create/edit flow and background-agent.service.ts.


Knowledge Base

Route group: /knowledge-base

Route Purpose
/knowledge-base Gallery — filter by status, template, agent
/knowledge-base/create Create KB (blank or from template)
/knowledge-base/:id Browse categories & articles
/knowledge-base/articles Article list with rich-text preview
/knowledge-base/article/create Create article (Quill editor)
/knowledge-base/templates Pre-built KB structure templates
/knowledge-base/search Semantic search (licence: KB_SEARCH)

Data shape:

interface KnowledgeBase {
  knowledge_base_id: string
  agent_id?: string          // optional agent association
  template_id?: string
  name: string
  description: string
  status: 'active' | 'inactive' | 'archived'
  category_count: number
  article_count: number
}

Articles are written in the Quill rich-text editor and stored as HTML. Templates provide a hierarchical category+article scaffold that can be imported into a new KB.


Workflows

Route group: /workflow

The workflow editor is built on @xyflow/react (React Flow), providing a drag-drop visual IVR/routing flow builder.

Node types

Node Purpose
AI Agent Route caller to a configured AI agent
Transfer Transfer to human agent / team
Menu DTMF menu selection
Condition Branch on call metadata or variable
Wait Introduce delay
API Call Trigger external webhook

Edges carry routing conditions; the full flow is serialised as workflow_json and sent to POST /workflows.

Demo workflows (read-only templates)

  • Trading Agent · Trader Agent · Insurance Agent · Appointment Booking · Multi-Agent Orchestration

Execution profiles (ExecutionProfile) define runtime constraints (concurrency limits, timeouts) and are assigned to workflows at save time.


Channels

Phone Numbers (/phone-numbers)

  • Provision new numbers from the marketplace (POST /numbers/buy)
  • Configure existing numbers: inbound routing, capacity/concurrency limits

WhatsApp (/whatsapp)

  • WhatsApp Business API integration configuration
  • Managed via whatsapp.service.ts

Email (/email)

  • Email channel setup and routing configuration

Chat Widgets (/widgets)

  • Create embeddable chat/call widgets for web properties
  • Configurable branding, routing, and queue assignment

App Connectors (/app-connectors)

  • Create connections to external systems (CRM, EHR, REST APIs)
  • Tool creation: define input schemas and outbound HTTP call mapping
  • Integrates with the App Connect service

Contacts & Lists

Contacts (/contacts)

  • Full directory: search, filter by type/tag/team
  • Create/edit with custom properties, tags, CRM link (cxConnectionId)
  • Supports CSV import (tracked via CsvImportJobContext)

Contact model:

interface Contact {
  id: string
  firstName: string
  lastName: string
  email?: string
  phoneNumber?: string
  whatsappNumber?: string
  address?: { country; city; postalCode; coordinates }
  tags: Tag[]
  properties: Record<string, any>
  teams?: string[]
  cxConnectionId?: string    // CRM integration link
  languages?: string[]
}

Contact Lists (/contact-lists)

  • Named segments used as campaign targets
  • Bulk import from CSV
  • Displays member count and last-updated metadata

Campaigns

Route group: /campaigns · /scheduled-calls

Campaigns

  • Multi-channel: Voice, WhatsApp, Email
  • Target a contact list with optional filter criteria
  • Configure: calling hours · retry attempts · concurrency · script/template
  • Route to: role · AI agent · team

Scheduled Calls

  • Automated outbound call scheduling
  • Frequency options: one-time · daily · weekly · custom
  • Do-not-call compliance rules
  • Outbound trunk assignment

Calls & Transcripts

Call list (/calls)

  • Sortable/filterable: direction, duration, status, outcome, disposition
  • Quick-access: notes · AI summary · transcript · structured JSON view

AI Summary (/calls/:callId/ai-summary)

interface AISummaryDto {
  mainReason: string
  summary: string
  resolutionStatus: 'RESOLVED' | 'NOT_RESOLVED' | 'CALLBACK'
  takeaways: string[]
  topics: string[]
  followUpActions: string[]
  sentimentAnalysis: {
    callScore: number
    customerSentiment: string
    emotionAnalysis: string
  }
  emailStatus: 'sent' | 'failed' | 'sending'
}

Transcript (/calls/:callId/transcript)

  • Participant-identified segments with timing offsets
  • Per-statement sentiment scores (negative · neutral · positive · compound)

Call notes (/calls/:callId/notes)

  • Rich-text note editor (Quill)
  • AI-generated note suggestions when enabled

Call quality (/call-quality)

  • Quality scoring and analytics for AI agent performance

Message & Clinical Templates

Section Route Purpose
Message Templates /message-templates Reusable multi-channel message templates with variable substitution
Clinical Templates /clinical-templates Healthcare-specific message templates

Teams & Roles

Section Purpose
/teams Create teams; assign members, skills, availability schedules
/roles Assign Keycloak roles to human agents; manage user-role bindings
/skill-templates Define skill sets that can be attached to agents

Settings

Route Purpose
/settings Organisation-level preferences and branding
/settings/disposition Call outcome code configuration and AI auto-tagging thresholds
/direct-routes Direct number-to-destination routing rules
/outbound-trunks SIP trunk management for outbound calls

Analytics & Reporting

Route Purpose
/dashboards/service-level SLA compliance dashboard
/ai-insights AI agent performance and conversation analytics
/opportunities Sales/conversion opportunity tracking

Full report generation (XLSX/CSV/PDF export, 29 report types) is handled by the Reporting Service; nexivo-admin triggers report requests through reports.service.ts.


State Management

Redux store (src/store/index.ts)

Slice What it holds
overviewLayoutSlice Overview dashboard widget grid positions (persisted)
aiOverviewLayoutSlice AI dashboard widget grid positions (persisted)
filterDataSlice Shared date range, search, and status filter state
confirmModal Generic confirm/cancel modal visibility and callbacks

Redux Persist serialises overviewLayoutSlice and aiOverviewLayoutSlice to localStorage so dashboard customisations survive page reload.

Context providers

Context Purpose
AuthContext Keycloak instance; hasLicense; hasResourceAccess; org metadata
ThemeContext Light / dark theme
AgentStatusContext Real-time human agent availability (SSE / WebSocket)
LiveQueueWaitingContext Real-time queue depth and wait-time metrics
CsvImportJobContext CSV import progress tracking for contacts / contact lists
AIDashboardContext AI dashboard date/filter state
OverviewDashboardContext Overview dashboard state

Services

All 45 service files in src/services/ use an Axios-based apiConnector (or adminConnector for Keycloak Admin API calls). The base URL is VITE_API_BASE_URL.

Error handling is centralised in createAPIError, which transforms Axios errors into APIError objects with an intent field (info | warning | error | success) consumed by the global toast notification system.

Key services and their primary endpoints:

Service file Primary endpoint Purpose
ai-agent.service.ts /tenants/{id}/agents AI agent CRUD + avatar URL resolution
calls.service.ts /calls Call history, disposition, notes, transcription, summaries
workflow.service.ts /workflows Workflow CRUD + execution profile management
knowledge-base.service.ts /knowledge-bases KB + article + category management
campaign.service.ts /campaigns Campaign CRUD, targeting, scheduling
contact.service.ts /contacts Contact CRUD, custom properties, CRM sync
phone-number.service.ts /phone-numbers Provisioning and routing configuration
live-queue.service.ts /live-queue Real-time queue metrics
reports.service.ts /reports Report generation and export
keycloak.service.ts Keycloak Admin API User + role management
app-connect.service.ts /app-connections External API tool/webhook integrations

Licence Gating

Feature licences are embedded in the Keycloak JWT under token.organization.licenses[]. LicenseGuard wraps any route or component that requires a specific licence:

<LicenseGuard license={LICENSE.AI_AGENT}>
  <AIAgentPage />
</LicenseGuard>

Known licence constants (from src/config/licenses.ts):

Constant Feature
AI_AGENT Access AI Agents gallery and features
AI_AGENT_CREATOR Create / edit AI agents
KB_SEARCH Semantic knowledge base search

Key Components

React Flow Workflow Builder (src/components/ReactFlowBuilder/)

Visual IVR/routing editor — drag-drop nodes, conditional edges, execution profile assignment, undo/redo, JSON import/export.

Data Table (src/components/DataTable/)

Reusable sortable/filterable data grid with column-visibility toggling, inline row actions, pagination, status badges, and avatar support.

Rich Text Editor (src/components/Form/RichText/)

React Quill wrapper used for AI agent prompts, KB articles, and call notes.

HLS Audio Player

Embeds hls.js for call recording playback directly in the call detail view.

Dashboard Widget System (src/components/dashboards/gadget/)

React Grid Layout-based drag-drop widgets. New widget types can be added by implementing the widget interface and registering in the widget catalogue.