Customization and Configuration
This guide explains how to customize and configure OmniCRM to match your brand identity, operational requirements, and integration needs.
Environment Variables (.env Files)
OmniCRM uses environment variables to configure both the backend API and
frontend UI. There are two separate .env files that control different
aspects of the system.
Backend API Configuration (.env)
Located at the root of the OmniCRM directory, this file configures database connections and CGRates integration.
Location: /OmniCRM/.env
Database Configuration:
# MySQL/MariaDB Database (CRM Data)
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_USER=omnitouch
MYSQL_PASSWORD=your_database_password
MYSQL_DATABASE=crm
DB_SERVER=db
# PostgreSQL Database (CGRates Data)
POSTGRES_USER=cgrates
POSTGRES_PASSWORD=cgrates_password
POSTGRES_DB=cgrates_db
CGRates Configuration:
# CGRates API Credentials
CGRATES_API_USER=admin
CGRATES_API_PASS=secret
CGRATES_DB_USER=cgrates
CGRATES_DB_PASS=cgrates_password
CGRATES_DB_NAME=cgrates_db
CGRATES_DB_PORT=5432
Security Considerations:
- Never commit .env files to version control - Use
.env.exampleas a template - Use strong passwords - Minimum 16 characters with mixed case, numbers, and symbols
- Rotate credentials regularly - Especially for production deployments
- Restrict database access - Use IP whitelisting and firewall rules
Frontend UI Configuration (.env)
Located in the OmniCRM-UI directory, this file controls branding,
appearance, integrations, and feature flags.
Location: /OmniCRM/OmniCRM-UI/.env
API Keys and Integration:
# Google Maps API (for address autocomplete and geocoding)
REACT_APP_GOOGLE_API_KEY=your_google_api_key
# Stripe Payment Gateway
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
# Disable browser auto-launch on npm start
BROWSER=none
Branding and Company Information:
# Company Branding
REACT_APP_COMPANY_NAME="ShellFone"
REACT_APP_PORTAL_NAME="ShellManager"
REACT_APP_SELF_CARE_NAME="ShellCare"
REACT_APP_COMPANY_TAGLINE="Phones with Shells"
These values appear throughout the UI:
COMPANY_NAME- Displayed in page titles, emails, and customer communicationsPORTAL_NAME- Name of the admin/staff portal (e.g., "ShellManager")SELF_CARE_NAME- Name of the customer self-service portal (e.g., "ShellCare")COMPANY_TAGLINE- Appears in login screens and marketing materials
Localization and Regional Settings:
# Language and Locale
# Supported languages: ar, ch, en, fr, gr, it, ru, sp
REACT_APP_DEFAULT_LANGUAGE=en
REACT_APP_LOCALE="en-GB"
# Default Location (for address autocomplete)
REACT_APP_DEFAULT_LOCATION="Sydney, Australia"
REACT_APP_DEFAULT_COUNTRY="Australia"
# Currency Settings
REACT_APP_CURRENCY_CODE="GBP"
REACT_APP_CURRENCY_SYMBOL="£"
Color Scheme Customization:
# Primary Color (main brand color)
REACT_APP_PRIMARY_COLOR=#405189
# Additional Color Options (commented examples)
# REACT_APP_SECONDARY_COLOR=#2bFFcf
# REACT_APP_TERTIARY_COLOR=#1a9fbf
# REACT_APP_SUCCESS_COLOR=#28a745
# REACT_APP_INFO_COLOR=#17a2b8
# REACT_APP_WARNING_COLOR=#ffc107
# REACT_APP_DANGER_COLOR=#dc3545
The primary color is applied to:
- Navigation headers
- Action buttons
- Links and highlights
- Active states
- Brand elements
Web App Integrations:
Configure up to 6 quick-access web applications that appear in the admin dashboard:
# Web App 1: GitHub
REACT_APP_WEB_APP_1_NAME="GitHub"
REACT_APP_WEB_APP_1_URL="https://github.com"
REACT_APP_WEB_APP_1_ICON_PATH="resources/webapp_icons/github.png"
# Web App 2: Xero
REACT_APP_WEB_APP_2_NAME="Xero"
REACT_APP_WEB_APP_2_URL="https://go.xero.com/"
REACT_APP_WEB_APP_2_ICON_PATH="resources/webapp_icons/xero.png"
# Web App 3-6: Additional integrations
# (Configure similarly with NAME, URL, and ICON_PATH)
Monitoring and Analytics:
# Grafana Dashboard Integration
REACT_APP_GRAFANA_URLS=url1,url2,url3
REACT_APP_GRAFANA_LABELS=label1,label2,label3
REACT_APP_GRAFANA_API_KEY=your-api-key
Feature Flags:
# Support and Documentation URLs
REACT_APP_FAQS_URL=https://docs.yourcompany.com/faqs
REACT_APP_SUPPORT_URL=https://support.yourcompany.com
# Social Login (Google, Facebook, etc.)
REACT_APP_ALLOW_SOCIAL_LOGINS=yes
Logo and Splash Image Customization
OmniCRM allows you to replace default branding images with your company's logo and splash screens without modifying code.
Logo Files
Logos are stored in /OmniCRM-UI/src/assets/images/omnitouch/ and use a
fallback system:
Default Logos (always present):
DefaultLogoDark.png- Dark theme logo (used on light backgrounds)DefaultLogoLight.png- Light theme logo (used on dark backgrounds)
Custom Logos (optional, take precedence when present):
logoSm.png- Small logo for collapsed sidebar (recommended: 100x100px)logoDark.png- Full-size dark logo for headers (recommended: 200x50px)logoLight.png- Full-size light logo for authentication screens (recommended: 200x50px)
How Logo Fallback Works:
The system attempts to load custom logos first. If a custom logo file doesn't exist, it falls back to the default:
// From Header.js
const tryImport = (filename) => {
try {
return require(`../assets/images/omnitouch/${filename}`);
} catch (err) {
return null; // Falls back to default
}
};
const userLogoSm = tryImport("logoSm.png");
const userLogoDark = tryImport("logoDark.png");
const userLogoLight = tryImport("logoLight.png");
Where Logos Appear:
- logoSm.png - Collapsed sidebar, mobile navigation, small header displays
- logoDark.png - Main header bar (light mode), admin dashboard header
- logoLight.png - Login/registration screens, dark backgrounds, authentication carousel
Replacing Logos:
-
Create Your Logo Files:
- Use PNG format for transparency support
- Match the recommended dimensions above
- Ensure logos are clear at both regular and retina resolutions
-
Add to OmniCRM:
# Copy your logo files to the omnitouch images directory
cp /path/to/your/logoSm.png OmniCRM-UI/src/assets/images/omnitouch/
cp /path/to/your/logoDark.png OmniCRM-UI/src/assets/images/omnitouch/
cp /path/to/your/logoLight.png OmniCRM-UI/src/assets/images/omnitouch/ -
Rebuild the UI:
cd OmniCRM-UI
npm run build -
Verify Changes:
- Check light mode header (should show
logoDark.png) - Check dark mode header (should show
logoLight.png) - Check collapsed sidebar (should show
logoSm.png) - Check login screen (should show
logoLight.png)
- Check light mode header (should show
Logo Design Best Practices:
- Contrast - Ensure logos are visible on both light and dark backgrounds
- Simplicity - Logos should be recognizable at small sizes
- Format - Use PNG with transparent backgrounds
- Retina - Provide 2x resolution for high-DPI displays
- Consistency - Use the same brand colors across all logo variants
Splash Screens and Authentication Backgrounds
The authentication screens (login, registration, password reset) use a carousel background with customizable images.
Location:
/OmniCRM-UI/src/pages/AuthenticationInner/authCarousel.js
Default Configuration:
import logoLight from "../../assets/images/logo-light.png";
// Logo displayed on authentication screens
<img src={logoLight} alt="" height="18" />
Customizing Authentication Screens:
- Replace
logo-light.pngin/OmniCRM-UI/src/assets/images/ - Add custom background CSS to
.auth-one-bgclass - Modify carousel quotes in
authCarousel.jsto match your brand voice
Example Customization:
/* Add to your custom CSS */
.auth-one-bg {
background-image: url('/assets/images/custom-auth-bg.jpg');
background-size: cover;
background-position: center;
}
CRM Configuration File (crm_config.yaml)
The crm_config.yaml file is the central configuration for the OmniCRM
API, controlling integrations, provisioning, email templates, and
external services.
Location: /OmniCRM/OmniCRM-API/crm_config.yaml
Database Configuration
database:
username: omnitouch
password: omnitouch2024
server: localhost
Note: This should match your .env database credentials. In
containerized deployments, the server is typically db (Docker service
name).
Service Types
Define valid service types for your deployment:
service_types:
- omnicharge
- mobile
- fixed
- fixed-voice
- hotspot
- dongle
These are used throughout the system for:
- Product categorization
- Addon filtering (addons match service types)
- Provisioning workflows
- Reporting and analytics
HSS Integration (Home Subscriber Server)
For mobile network operators with HSS integration:
hss:
hss_peers:
- 'http://10.179.2.140:8080'
apn_list: "1,2,3,4,5,6"
Configuration:
hss_peers- List of HSS endpoints for subscriber provisioningapn_list- Comma-separated list of APN IDs available for provisioning
Mailjet Email Template Configuration
OmniCRM uses Mailjet for transactional emails. Each email type has its own template configuration:
mailjet:
api_key: your_mailjet_api_key
api_secret: your_mailjet_api_secret
# Customer Welcome Email
api_crmCommunicationCustomerWelcome:
from_email: "support@yourcompany.com"
from_name: "Your Company Support"
template_id: 5977509
subject: "Welcome to YourCompany"
# Customer Invoice Email
api_crmCommunicationCustomerInvoice:
from_email: "billing@yourcompany.com"
from_name: "Your Company Billing"
template_id: 6759851
subject: "Your Invoice - "
# Invoice Reminder
api_crmCommunicationCustomerInvoiceReminder:
from_email: "billing@yourcompany.com"
from_name: "Your Company Billing"
template_id: 5977570
subject: "Invoice Payment Reminder"
# User Welcome Email (Staff/Admin)
api_crmCommunicationUserWelcome:
from_email: "admin@yourcompany.com"
from_name: "Your Company Admin"
template_id: 6118112
subject: "Welcome to the Team"
# Password Reset Request
api_crmCommunicationUserPasswordReset:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6735666
subject: "Password Reset Request"
# Password Reset Success Confirmation
api_crmCommunicationUserPasswordResetSuccess:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6118378
subject: "Password Reset Successful"
# Password Change Notification
api_crmCommunicationUserPasswordChange:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6118423
subject: "Password Changed"
# Email Verification
api_crmCommunicationEmailVerification:
from_email: "verify@yourcompany.com"
from_name: "Your Company Verification"
template_id: 6267350
subject: "Verify Your Email Address"
# Balance Expired Notification
api_crmCommunicationsBalanceExpired:
from_email: "alerts@yourcompany.com"
from_name: "Your Company Alerts"
template_id: 7238252
subject: "Service Balance Expired"
# Low Balance Warning
api_crmCommunicationsBalanceLow:
from_email: "alerts@yourcompany.com"
from_name: "Your Company Alerts"
template_id: 7238263
subject: "Low Balance Warning"
Creating Mailjet Templates:
- Log in to Mailjet dashboard (<https://app.mailjet.com>)
- Navigate to Transactional → Templates
- Create a new template or clone an existing one
- Note the Template ID (numeric value)
- Add template variables matching the OmniCRM data structure
- Update
crm_config.yamlwith the template ID
Available Template Variables:
Each email type receives specific variables. Common examples:
{{customer_name}}- Customer or user name{{service_name}}- Service or product name{{invoice_id}}- Invoice number{{invoice_amount}}- Total invoice amount{{due_date}}- Payment due date{{reset_link}}- Password reset URL{{verification_link}}- Email verification URL{{balance}}- Current account balance{{expiry_date}}- Balance or service expiry date
Provisioning Configuration
provisioning:
failure_list: ['admin@yourcompany.com', 'ops@yourcompany.com']
Purpose:
failure_list- Email addresses notified when Ansible provisioning fails- Notifications include playbook name, error details, and customer information
- Allows ops team to quickly respond to provisioning issues
Invoice Configuration
invoice:
template_filename: 'yourcompany_invoice_template.html'
Purpose:
Specifies which Jinja2 HTML template to use for PDF invoice generation.
Template Location: /OmniCRM-API/invoice_templates/
See Invoice PDF Generation section below for details on creating custom templates.
CRM Base URL
crm:
base_url: 'http://localhost:5000'
Purpose:
- Used by Ansible playbooks to make API callbacks
- Used in email templates for generating links to the CRM
- Should be the publicly accessible URL of your API (not internal container names)
Examples:
- Development:
http://localhost:5000 - Production:
https://api.yourcompany.com - Docker:
http://omnicrm-api:5000(internal container communication)
OCS and CGRates Configuration
ocs:
ocsApi: 'http://10.179.2.142:8080/api'
ocsTenant: 'mnc380.mcc313.3gppnetwork.org'
cgrates: 'localhost:2080'
Configuration:
ocsApi- OCS API endpoint for subscriber managementocsTenant- Tenant identifier for multi-tenant OCS deploymentscgrates- CGRates JSON-RPC API endpoint (host:port)
SMSC Configuration (SMS Gateway)
smsc:
source_msisdn: 'YourCompany'
smsc_url: 'http://10.179.2.216/SMSc/'
api_key: 'your_smsc_api_key'
Purpose:
- Send SMS notifications to customers (low balance, service alerts, 2FA codes)
source_msisdn- Sender ID displayed to recipients (alphanumeric or phone number)smsc_url- SMSC gateway API endpointapi_key- Authentication for SMSC API
JWT Secret Key
jwt_secret: '2b93110f723db60172c8e9a1eaa80027a9a9c3f05b44e50dc3fcf38dba68d87e'
Security:
- Used to sign and verify authentication tokens
- MUST be changed from default value in production
- Generate a secure random string (minimum 64 characters)
- Never share or commit to version control
Generating a New JWT Secret:
# Generate a cryptographically secure random key
python3 -c "import secrets; print(secrets.token_hex(32))"
Stripe Payment Configuration
stripe:
secret_key: 'sk_live_xxxxxxxxxx'
publishable_key: 'pk_live_xxxxxxxxxx'
currency: 'aud'
statement_descriptor_suffix: 'YOURCOMPANY'
Configuration:
secret_key- Stripe secret API key (server-side, keep confidential)publishable_key- Stripe publishable key (client-side, safe to expose)currency- ISO 4217 currency code (aud, usd, gbp, eur, etc.)statement_descriptor_suffix- Appears on customer credit card statements
Statement Descriptor Usage:
- Shown on customer bank statements as "YOURCOMPANY"
- Maximum 22 characters
- Helps customers identify charges
- Also used in invoice PDF filenames (e.g.,
YOURCOMPANY_12345.pdf)
API Keys and IP Whitelisting
Define API keys with role-based access and IP restrictions:
api_keys:
"YOUR_API_KEY_1":
roles: ["admin"]
ips: ["127.0.0.1", "::1"]
"YOUR_API_KEY_2":
roles: ["customer_service_agent_1"]
ips: ["127.0.0.1", "::1", "10.0.1.0/24"]
# IP Whitelist (standalone, without API key)
ip_whitelist:
"10.179.2.142":
roles: ["admin"]
Purpose:
- Allow external systems to authenticate via API key
- Restrict access by IP address
- Grant specific roles to API consumers
- Useful for integrations (billing systems, monitoring, automation)
Security Best Practices:
- Use long, random API keys (minimum 32 characters)
- Restrict IPs to known sources only
- Grant minimum necessary roles
- Rotate API keys regularly
- Monitor API key usage in logs
Invoice PDF Generation
OmniCRM generates professional PDF invoices using Jinja2 HTML templates and WeasyPrint PDF rendering.
How PDF Generation Works
- Template Selection:
- Template filename is specified in
crm_config.yamlunderinvoice.template_filename - Template is loaded from
/OmniCRM-API/invoice_templates/directory
- Template filename is specified in
- Data Preparation:
- Invoice data (ID, dates, amounts, status) is fetched from database
- Customer information (name, address) is retrieved
- Transaction list is compiled (all charges/credits on the invoice)
- Template Rendering:
- Jinja2 renders the HTML template with invoice data
- Variables like
{{ invoice_number }},{{ total_amount }}, etc. are replaced - Rendered HTML is saved to
invoice_templates/rendered/for debugging
- PDF Generation:
- WeasyPrint converts rendered HTML to PDF
- PDF supports CSS styling, images, page breaks, headers/footers
- PDF binary data is generated in memory
- Caching:
- PDF is Base64-encoded and stored in
Invoice_PDF_Cachetable - SHA256 hash is calculated for integrity verification
- Subsequent requests return cached PDF (instant delivery)
- PDF is Base64-encoded and stored in
- Cache Invalidation:
- Cache is invalidated when invoice is modified, voided, or refunded
- Template changes do not automatically invalidate existing caches
Invoice Template Structure
Invoice templates are Jinja2 HTML files with embedded variables and logic.
Template Location:
/OmniCRM-API/invoice_templates/yourcompany_invoice_template.html
Available Variables:
{
'invoice_number': 12345,
'date': '2025-01-04',
'client': {
'name': 'John Smith',
'address': {
'address_line_1': '123 Main St',
'city': 'Sydney',
'state': 'NSW',
'zip_code': '2000',
'country': 'Australia'
}
},
'transaction_list': [
[
{
'transaction_id': 1,
'title': 'Mobile Service - Monthly Fee',
'retail_cost': 30.00,
'wholesale_cost': 10.00,
'created': '2025-01-01'
},
{
'transaction_id': 2,
'title': 'Data Addon - 5GB',
'retail_cost': 15.00,
'wholesale_cost': 5.00,
'created': '2025-01-15'
}
]
],
'total_amount': 45.00,
'due_date': '2025-01-31',
'start_date': '2025-01-01',
'end_date': '2025-01-31',
'paid': False,
'void': False
}
Example Template Snippet:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Invoice {{ invoice_number }}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.invoice-details {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #405189;
color: white;
}
.total {
text-align: right;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="header">
<img src="file:///path/to/logo.png" alt="Company Logo" height="60">
<h1>INVOICE</h1>
</div>
<div class="invoice-details">
<p><strong>Invoice Number:</strong> {{ invoice_number }}</p>
<p><strong>Date:</strong> {{ date }}</p>
<p><strong>Due Date:</strong> {{ due_date }}</p>
<p><strong>Billing Period:</strong> {{ start_date }} to {{ end_date }}</p>
</div>
<div class="customer-details">
<h3>Bill To:</h3>
<p>{{ client.name }}</p>
<p>{{ client.address.address_line_1 }}</p>
<p>{{ client.address.city }}, {{ client.address.state }} {{ client.address.zip_code }}</p>
<p>{{ client.address.country }}</p>
</div>
<table>
<thead>
<tr>
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{% for transaction in transaction_list[0] %}
<tr>
<td>{{ transaction.title }}</td>
<td>{{ transaction.created }}</td>
<td>${{ "%.2f"|format(transaction.retail_cost) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="total">
<p>Total Amount Due: ${{ "%.2f"|format(total_amount) }}</p>
</div>
{% if paid %}
<div style="text-align: center; color: green; font-weight: bold;">
PAID
</div>
{% endif %}
{% if void %}
<div style="text-align: center; color: red; font-weight: bold;">
VOID
</div>
{% endif %}
</body>
</html>
Template Best Practices:
- Use absolute paths for images -
file:///absolute/path/to/image.png - Inline CSS - WeasyPrint doesn't load external stylesheets reliably
- Test with sample data - Use
invoice_templates/rendered/to inspect HTML - Page breaks - Use
<div style="page-break-after: always;"></div>for multi-page invoices - Headers and footers - Use
@pageCSS rules for repeating elements - Currency formatting - Use Jinja2 filters:
{{ "%.2f"|format(amount) }}
Creating a Custom Invoice Template
-
Copy Example Template:
cd /OmniCRM/OmniCRM-API/invoice_templates
cp norfone_invoice_template.html yourcompany_invoice_template.html -
Edit Template:
- Replace company name, logo, contact information
- Adjust styling (colors, fonts, layout) to match brand
- Add or remove sections as needed (tax breakdowns, payment instructions, etc.)
-
Update Configuration:
Edit
crm_config.yaml:invoice:
template_filename: 'yourcompany_invoice_template.html' -
Test Invoice Generation:
- Create a test invoice in the CRM
- Download the PDF and verify formatting
- Check
invoice_templates/rendered/{invoice_id}.htmlfor debugging
-
Invalidate Old Caches (if needed):
If you've changed the template and want to regenerate existing invoices:
-- Clear all cached PDFs (forces regeneration)
DELETE FROM Invoice_PDF_Cache;
PDF Caching System
To improve performance, OmniCRM caches generated PDFs:
Cache Behavior:
- First Request - PDF is generated, cached, and returned
- Subsequent Requests - Cached PDF is returned immediately (no regeneration)
- Cache Invalidation - Occurs when invoice is modified, voided, or refunded
- Cache Cleanup - Old caches are automatically purged after 30 days of inactivity
Cache Storage:
- Base64-encoded PDF stored in
Invoice_PDF_Cachetable - SHA256 content hash for integrity verification
- Includes filename, creation timestamp, last accessed timestamp
Manual Cache Management:
# In OmniCRM API or Python shell
from services.invoice_service import cleanup_old_pdf_cache, invalidate_invoice_cache
from utils.db_helpers import get_db_session
session = get_db_session()
# Clean up caches older than 30 days
result = cleanup_old_pdf_cache(session, days_old=30)
print(result) # {'status': 'success', 'deleted_count': 15}
# Invalidate specific invoice cache
invalidate_invoice_cache(session, invoice_id='12345')
API Endpoints:
Generate/download invoice PDF:
GET /invoice/pdf/{invoice_id}
Response: PDF file download with filename from Stripe statement descriptor
Cache Headers:
- First request: Slower response (generation time)
- Cached requests: Instant response
- Cache hit/miss is transparent to the user
Troubleshooting
PDF Generation Fails:
- Check that WeasyPrint is installed:
pip install weasyprint - Verify template filename matches
crm_config.yaml - Check
invoice_templates/rendered/for HTML rendering errors - Review API logs for Jinja2 template errors
Images Not Appearing in PDF:
- Use absolute file paths:
file:///full/path/to/image.png - Ensure image files exist and are readable
- Check image format (PNG and JPEG work best)
- Verify image paths don't contain special characters
Styling Issues:
- Inline all CSS (external stylesheets not supported)
- Avoid complex CSS features (flexbox, grid may not render correctly)
- Test with simple layouts first, add complexity gradually
- Use tables for layout instead of divs where possible
Cache Not Invalidating:
- Verify
invalidate_invoice_cache()is called when invoice is modified - Check that transaction updates trigger cache invalidation
- Manually delete from
Invoice_PDF_Cachetable if needed
Configuration Checklist
Use this checklist when deploying OmniCRM:
Backend Configuration
- [ ] Copy
.env.exampleto.env - [ ] Set strong database passwords
- [ ] Configure CGRates credentials
- [ ] Update
crm_config.yamlwith your settings:- [ ] Database connection
- [ ] Service types
- [ ] Mailjet API keys and template IDs
- [ ] Provisioning failure notification emails
- [ ] Invoice template filename
- [ ] CRM base URL (publicly accessible)
- [ ] OCS/CGRates endpoints
- [ ] SMSC configuration
- [ ] Generate new JWT secret key
- [ ] Stripe keys (live, not test)
- [ ] API keys and IP whitelisting
Frontend Configuration
- [ ] Copy
OmniCRM-UI/.env.exampletoOmniCRM-UI/.env - [ ] Set Google Maps API key
- [ ] Set Stripe publishable key
- [ ] Update company branding:
- [ ] Company name
- [ ] Portal name
- [ ] Self-care name
- [ ] Company tagline
- [ ] Configure localization:
- [ ] Default language
- [ ] Locale
- [ ] Default location and country
- [ ] Currency code and symbol
- [ ] Set primary brand color
- [ ] Configure web app integrations (optional)
- [ ] Add support and FAQ URLs (optional)
Branding Assets
- [ ] Create logo files (logoSm.png, logoDark.png, logoLight.png)
- [ ] Upload logos to
OmniCRM-UI/src/assets/images/omnitouch/ - [ ] Create custom invoice template HTML
- [ ] Upload invoice template to
OmniCRM-API/invoice_templates/ - [ ] Update
crm_config.yamlwith invoice template filename - [ ] Test invoice PDF generation
- [ ] Rebuild UI:
npm run build
Security
- [ ] Change all default passwords
- [ ] Generate unique JWT secret
- [ ] Use production Stripe keys (not test keys)
- [ ] Rotate Mailjet API keys
- [ ] Enable firewall rules
- [ ] Configure IP whitelisting for API access
- [ ] Set up SSL/TLS certificates
- [ ] Enable HTTPS for all endpoints
- [ ] Review CORS settings
- [ ] Implement rate limiting
- [ ] Configure backup and recovery procedures
Testing
- [ ] Test customer registration flow
- [ ] Test service provisioning end-to-end
- [ ] Verify email notifications are sent correctly
- [ ] Test invoice generation and PDF download
- [ ] Verify payment processing (Stripe)
- [ ] Check user authentication and 2FA
- [ ] Test impersonation and audit logging
- [ ] Verify usage data syncs from OCS
- [ ] Test ActionPlan creation and renewal
- [ ] Confirm inventory allocation works correctly
Deployment
- [ ] Build Docker images or deploy to servers
- [ ] Start database containers (MySQL, PostgreSQL)
- [ ] Start CGRates
- [ ] Start OmniCRM API
- [ ] Start OmniCRM UI
- [ ] Configure reverse proxy (nginx, traefik)
- [ ] Set up monitoring (Grafana, Prometheus)
- [ ] Configure log aggregation
- [ ] Set up automated backups
- [ ] Document deployment architecture
- [ ] Train staff on system usage