← Back to ServiFlow

Getting Started

Get ServiFlow running locally in under five minutes.

Prerequisites

Install & Run

# Install dependencies
npm install

# Create databases & seed data
npm run setup-db

# Start the server
npm start

Open http://localhost:3000 in your browser.

Default Credentials

RoleUsernamePassword
Master Adminadminadmin123
Tenant Adminadminpassword123
Expertexpertpassword123
Customercustomerpassword123

When logging in as a tenant user, use the tenant code apoyar.

Environment Variables

# .env file
MASTER_DB_HOST=localhost
MASTER_DB_PORT=3306
MASTER_DB_USER=root
MASTER_DB_PASSWORD=
MASTER_DB_NAME=a1_master
PORT=3000

# Email (Gmail SMTP)
SMTP_EMAIL=your-email@gmail.com
SMTP_PASSWORD=your-app-password

Architecture

Multi-Tenant Database

ServiFlow uses a database-per-tenant isolation model:

┌─────────────┐   ┌────────────────┐   ┌────────────────┐
│  a1_master  │   │ a1_tenant_     │   │ a1_tenant_     │
│             │   │ apoyar         │   │ bleckmann      │
│ master_users│   │ users          │   │ users          │
│ tenants     │   │ tickets        │   │ tickets        │
│ plans       │   │ cmdb_items     │   │ cmdb_items     │
└─────────────┘   └────────────────┘   └────────────────┘
        │                  │                    │
        └──────────────────┼────────────────────┘
                           │
                   ┌───────────────┐
                   │  Express API  │
                   │  + SPA Front  │
                   └───────────────┘

Key Files

FilePurpose
server.jsMain Express entry point
config/database.jsDatabase connection management
services/tenant-provisioning.jsNew tenant creation & schema
routes/auth.jsAuthentication endpoints
routes/master.jsMaster admin API
routes/admin.jsTenant admin settings & housekeeping
services/sla-notifier.jsSLA notification scheduler
services/email-processor.jsInbound email → ticket processing
services/ai-analysis-service.jsAI ticket analysis
services/housekeeping.jsData retention & pruning

Technology Stack

Security

Feature Overview

Core Capabilities

User Roles

RoleAccess
Master AdminPlatform-wide: tenants, plans, billing, system health
AdminTenant-level: tickets, users, CMDB, settings, rules, analytics
ExpertAssigned tickets, CMDB, knowledge base, AI insights
CustomerOwn tickets, raise requests, company CMDB, analytics

Email System

Ticket Management

Ticket Workflow

Tickets progress through the following statuses:

OpenIn ProgressPendingResolvedClosed

Status Descriptions

StatusDescription
OpenNew ticket awaiting assignment or triage
In ProgressBeing actively worked on by an expert
PendingWaiting for customer response or external input
ResolvedFix applied, awaiting customer confirmation
ClosedCompleted — no further action needed

SLA Tracking

Each ticket can have an SLA definition applied that tracks:

Activity Logging

Every ticket action is recorded in the ticket_activity table:

Activity TypeTrigger
createdTicket created
assignedExpert assigned
updatedStatus or field changed
commentInternal note added
resolvedTicket resolved with comment
closedTicket closed
classifiedAI classification applied
email_replyCustomer replied via email
auto_replySystem auto-response sent

Demo Scenarios

  1. Admin: View all tickets, assign to experts, manage SLA definitions
  2. Expert: Work assigned tickets, update status, use completion modal
  3. Customer: Raise requests, track status, view CMDB assets

Customer Management

CRUD Operations

ActionEndpointRole
List allGET /api/customersAdmin, Expert
Get oneGET /api/customers/:idAdmin, Expert
CreatePOST /api/customersAdmin
UpdatePUT /api/customers/:idAdmin
DeactivateDELETE /api/customers/:idAdmin
ReactivatePOST /api/customers/:id/reactivateAdmin

Company Domain Matching

The company_domain field is critical for the email-to-ticket system:

  1. Customer sends email from john@acme.com
  2. System extracts domain: acme.com
  3. Looks up domain in customers table
  4. Creates ticket for that customer (or creates a new customer user if none exists)

Database Schema

ColumnTypeDescription
idintPrimary key
user_idintFK to users table
company_namevarchar(100)Company display name
company_domainvarchar(255)Email domain for matching
contact_phonevarchar(20)Contact phone
addresstextCompany address
sla_levelenumbasic / premium / enterprise

Security

AI Insights

Automatic Analysis

Every incoming ticket is analysed for:

Trend Detection

Automatically detects:

Dashboard Actions

ActionDescription
RefreshReload latest insights
Detect TrendsManually trigger trend analysis for the last 24 hours
AcknowledgeMark insight as reviewed (tracked with user + timestamp)
DismissRemove false positive or resolved insight from view

API Endpoints

MethodEndpointDescription
GET/api/analytics/:tenantId/ai-insightsDashboard data
POST/api/analytics/:tenantId/detect-trendsManual trend analysis
POST/api/analytics/:tenantId/insights/:id/acknowledgeAcknowledge insight
POST/api/analytics/:tenantId/insights/:id/dismissDismiss insight

Database Tables

Ticket Processing Rules

Create automated rules that match tickets by search criteria and perform actions.

Rule Configuration

FieldDescription
Rule NameDescriptive label
Search Intitle, body, or both
Search TextText to match
Case SensitiveToggle case-sensitive matching
Action TypeWhat to do when a match is found
EnabledToggle rule on/off without deleting

Action Types

TypeDescriptionParameters
deleteDelete matching tickets(none)
assign_to_expertAssign to a specific expertexpert_id, expert_name
create_for_customerForward ticket to another customercustomer_id
set_prioritySet ticket prioritypriority (low/medium/high/critical)
set_statusSet ticket statusstatus
add_tagAdd a tag to the tickettag

Examples

Auto-assign infrastructure alerts

{
  "rule_name": "Auto-assign Infrastructure",
  "search_in": "title",
  "search_text": "Infrastructure Monitoring",
  "action_type": "assign_to_expert",
  "action_params": { "expert_id": 1, "expert_name": "Infrastructure Team" }
}

Escalate urgent tickets

{
  "rule_name": "Escalate Critical",
  "search_in": "title",
  "search_text": "URGENT",
  "case_sensitive": true,
  "action_type": "set_priority",
  "action_params": { "priority": "critical" }
}

API Endpoints

All prefixed with /api/ticket-rules/:tenantId.

MethodPathDescription
GET/List all rules
GET/:ruleIdGet single rule
POST/Create rule
PUT/:ruleIdUpdate rule
DELETE/:ruleIdDelete rule
POST/:ruleId/testPreview matching tickets
POST/:ruleId/execute/:ticketIdExecute on specific ticket
POST/execute-all/:ticketIdExecute all enabled rules on ticket
GET/:ruleId/historyExecution history
GET/statisticsRule statistics

API Reference

All endpoints require a Bearer token in the Authorization header unless noted.

Authentication

MethodEndpointDescription
POST/api/auth/master/loginMaster admin login
POST/api/auth/tenant/loginTenant user login
POST/api/auth/master/change-passwordChange master password
POST/api/auth/tenant/change-passwordChange tenant password
GET/api/auth/verifyVerify token validity
GET/api/auth/profileGet user profile
PUT/api/auth/profileUpdate user profile
GET/api/auth/tenantsList available tenants (public)

Tickets

MethodEndpointDescription
GET/api/tickets/:tenantIdGet all tickets
GET/api/tickets/:tenantId/:ticketIdGet specific ticket + activity
POST/api/tickets/:tenantIdCreate new ticket
PUT/api/tickets/:tenantId/:ticketIdUpdate ticket (resolve, assign, etc.)

Master Admin

MethodEndpointDescription
GET/api/master/tenantsGet all tenants
GET/api/master/overviewPlatform overview
GET/api/master/subscriptionsGet subscriptions
GET/api/master/billingGet billing information
GET/api/master/plansGet subscription plans
GET/api/master/email-settingsGet email settings
POST/api/master/email-settings/testTest email processing
GET/api/master/audit-logsGet audit logs

Customers

MethodEndpointDescription
GET/api/customersList all customers
GET/api/customers/:idGet single customer
POST/api/customersCreate customer
PUT/api/customers/:idUpdate customer
DELETE/api/customers/:idDeactivate customer
POST/api/customers/:id/reactivateReactivate customer

Analytics & AI

MethodEndpointDescription
GET/api/analytics/:tenantId/ai-insightsAI dashboard data
POST/api/analytics/:tenantId/detect-trendsManual trend detection
POST/api/analytics/:tenantId/insights/:id/acknowledgeAcknowledge insight
POST/api/analytics/:tenantId/insights/:id/dismissDismiss insight

Admin Settings

MethodEndpointDescription
GET/api/admin/:tenantId/housekeepingGet housekeeping config
PUT/api/admin/:tenantId/housekeepingUpdate housekeeping config
POST/api/admin/:tenantId/housekeeping/runRun housekeeping now

Health & Status

MethodEndpointAuthDescription
GET/healthNoServer health check
GET/api/db/statusNoDatabase connection status

Troubleshooting

Server Hangs on Login

Usually caused by MySQL connection pool exhaustion.

# Kill stale node processes
pkill -f "node.*server"
lsof -ti:3000 | xargs kill -9

# Clean stale MySQL connections
mysql -u root -e "SELECT CONCAT('KILL ', id, ';') \
  FROM information_schema.processlist \
  WHERE user='root' AND command='Sleep' AND time > 60;" -N | mysql -u root

# Restart
npm start

MySQL Connection Issues

# Check MySQL service
sudo systemctl start mysql
sudo systemctl enable mysql

# Ensure root has privileges
mysql -u root -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost';
FLUSH PRIVILEGES;

Port Conflicts

# Use a different port
PORT=3001 npm start

Railway Deployment Not Updating

Changes must be committed to git before railway up. Railway deploys from git, not local files.

git add .
git commit -m "Your message"
railway up --detach

Customer Domain Issues

ErrorSolution
"Domain not found in customers"Add the sender's email domain to a customer record
"Username or email already exists"Choose a different username or update the existing customer
"Cannot delete customer with X active tickets"Close all tickets first, then deactivate
Customer can't loginCheck: active status, correct password, tenant code = "apoyar"

Ticket Rules Not Matching

  1. Verify search text is correct
  2. Try with case-sensitive disabled
  3. Check if searching in the correct field (title / body / both)
  4. Use the Test button to preview matches before enabling

AI Insights Not Loading

  1. Check browser console for API errors
  2. Verify authentication token is valid (re-login if expired)
  3. Ensure the ai_email_analysis table exists in the tenant database
  4. Try clicking Refresh or Detect Trends to regenerate data

Adding Columns to Existing Tenant DBs

When adding new columns, update all tenant databases:

# Get Railway MySQL password
railway variables | grep MYSQLPASSWORD

# Run migration on each tenant DB
mysql -h tramway.proxy.rlwy.net -P 19355 -u root -p{PASSWORD} -e "
ALTER TABLE a1_tenant_{code}.tickets ADD COLUMN new_col TYPE;"