I Didn’t Build Another Insurance CRM. I Built an Insurance Operating System.
Most insurance software solves one piece of the business.
A CRM manages leads.
A policy system manages policies.
A dialer manages calls.
A customer portal manages self-service.
An underwriting engine manages risk.
A billing platform manages invoices.
But the insurance business does not operate in isolated applications.
It operates as one connected ecosystem.
That is why I designed InsuranceERP differently.
The goal was not to build another dashboard with leads and policies.
The goal was to create a multi-tenant insurance operating system where a platform owner, DSA, agency, agent, underwriter, and customer can all work inside the same architecture—with different permissions, workflows, and visibility.
The current architecture connects multi-tenant administration, CRM, underwriting, quotes and policies, real-time communication, telephony, PBX infrastructure, and customer self-service into one platform.
The architecture starts with the business hierarchy
Insurance distribution is rarely flat.
A platform may have multiple DSAs.
A DSA may operate multiple agencies.
An agency manages multiple agents.
Agents interact with customers.
Underwriters may review risk separately.
So instead of designing the application around pages, I designed it around organizational boundaries.
Platform
│
├── DSA
│ │
│ ├── Agency
│ │ │
│ │ └── Agents
│ │
│ └── Managers
│
└── Direct Agencies
│
└── Agents
│
└── CustomersEach level needs a different operating environment.
The platform owner needs global control.
The DSA needs network visibility.
The agency needs operational control.
The agent needs a sales workspace.
The customer needs self-service.
The architecture therefore uses role-based portals and tenant-aware data boundaries rather than exposing the same application to everyone. The defined roles include Super Admin, DSA Admin, Manager, Agency Admin, Agent, Underwriter, and Customer.
One product. Multiple operating systems.
The frontend is divided into dedicated role portals:
/admin
/dsa
/agency
/agent
/customer
/underwriterBut these are not separate products.
They are different views into the same business platform.
For example:
Super Admin
The platform owner manages:
- Tenants
- Users
- Insurance categories
- Providers
- Products
- Aggregators
- Underwriting rules
- SIP trunks
- DID marketplace
- PBX monitoring
- Billing
- CMS
- Audit logs
- System settings
DSA
The DSA manages a distribution network:
- Agencies
- Agents
- Campaigns
- Leads
- Opportunities
- Quotes
- Policies
- Phone numbers
- Appointments
- Call activity
Agency
The agency runs the sales floor:
- Agents
- Campaigns
- IVR and call routes
- Leads
- Opportunities
- Quotes
- Policies
- Appointments
- Call logs
Agent
The agent gets a connected sales workspace:
Lead
↓
Call
↓
Opportunity
↓
Questionnaire
↓
Quote
↓
PolicyThe agent workspace combines CRM functionality with a browser softphone, campaign workflows, quotes, policies, questionnaires, appointments, chat, reports, and call history.
Customer
The customer does not need the complexity of the internal platform.
The customer gets a self-service experience:
- Complete questionnaires
- Receive recommendations
- Compare quotes
- Download quote PDFs
- View policies
- Download policy documents
- Book appointments
- Chat with the business
This role-based design reflects the actual insurance distribution workflow rather than forcing every user into the same CRM interface.
The architectural decision that makes the platform scalable
The core request flow is intentionally layered:
Browser
↓
Next.js Role Portal
↓
Next.js BFF / API Layer
↓
NestJS Backend
↓
PostgreSQL
↓
RedisWith real-time and telephony services operating alongside the main request path:
Browser ──────────────→ Socket.IO Chat
│
└── WebRTC / SIP ──→ Asterisk PBX
│
Asterisk AMI
│
NestJS ServicesThe frontend uses Next.js, while the backend is implemented with NestJS. PostgreSQL acts as the primary system of record, Redis is available for caching, and Asterisk provides PBX and telephony capabilities.
I deliberately separated the frontend from the domain backend through a BFF-style API layer.
The browser does not need to understand the entire backend topology.
The frontend calls its /api/* layer.
That layer forwards authenticated requests to NestJS.
NestJS applies authentication, role checks, and tenant-aware business logic before accessing the underlying systems.
This gives the architecture flexibility for:
- Future frontend changes
- Mobile applications
- Partner integrations
- Public APIs
- White-label portals
- Microservice extraction where justified
Without prematurely splitting everything into microservices.
Multi-tenancy is not just a login feature
One of the most important design decisions was treating tenancy as a core architectural concern.
A tenant can represent:
Platform
DSA
AgencyBusiness records are associated with tenant context, and backend services apply tenant-aware filtering.
This means the same platform can support multiple independent organizations while maintaining controlled data boundaries.
The architecture uses JWT authentication combined with role guards, while tenant scoping is applied through tenant_id and service-level filtering.
This matters because insurance distribution platforms often need to support:
- Multiple channel partners
- Multiple agencies
- Independent sales teams
- Different business configurations
- Controlled operational visibility
A DSA should not accidentally see another DSA's data.
An agency should not become a platform administrator.
An agent should not see every customer in the system.
The architecture is designed around scope.
Not simply around menus.
CRM is connected directly to telephony
This is where I believe many insurance platforms become fragmented.
A typical setup looks like this:
CRM
+
Third-party Dialer
+
PBX
+
Spreadsheet
+
Messaging Tool
+
Appointment ToolEach system has its own records.
Its own authentication.
Its own reporting.
Its own data synchronization problems.
Instead, the agent workflow is designed to connect CRM and telephony.
The platform includes:
- SIP trunks
- DIDs
- PBX monitoring
- Browser softphone
- WebRTC calling
- Call records
- CDR
- Call transfer
- Conferences
- Campaign calling
- IVR and routes
The softphone uses SIP/WebRTC from the browser toward Asterisk, while the backend can interact with Asterisk through AMI for call control and events.
The important point is not that there is a phone inside the browser.
The important point is that the call becomes part of the business workflow.
Lead
↓
Dial
↓
Call Result
↓
Disposition
↓
Opportunity
↓
Quote
↓
PolicyThe communication layer is part of the ERP.
Not a disconnected plugin.
Underwriting becomes configurable
Insurance products cannot rely entirely on static forms.
Different products may require different questions.
Different answers may affect:
- Eligibility
- Risk
- Product recommendations
- Provider recommendations
- Scoring
- Manual review
The platform therefore includes configurable underwriting questions, rules, questionnaires, evaluations, and scoring suggestions.
The architecture separates the catalog, underwriting, questionnaire, evaluation, quote, and policy domains so the business rules can evolve independently.
A simplified flow looks like this:
Customer / Agent
│
▼
Questionnaire
│
▼
Answers
│
▼
Underwriting Rules
│
▼
Evaluation / Suggestion
│
▼
Product Recommendation
│
▼
QuoteThis gives the platform a path toward more advanced capabilities later, including:
- AI-assisted recommendations
- Risk scoring
- Automated underwriting workflows
- Human underwriting overrides
- Product eligibility engines
The architecture is designed so intelligence can evolve without rebuilding the entire sales platform.
Aggregators are treated as adapters, not hard dependencies
Insurance platforms often integrate with multiple providers or aggregators.
The mistake is hardcoding each integration directly into the core quote and policy services.
Instead, the architecture uses an adapter approach.
Conceptually:
Quote Request
│
▼
Aggregator Adapter Factory
│
├── Provider A Adapter
├── Provider B Adapter
├── External API Adapter
└── Local Database AdapterThe current architecture includes an AggregatorAdapterFactory and a database-backed adapter that supports catalog, quote, and bind workflows. Unknown aggregator codes can fall back to the local adapter.
That means the core ERP does not need to be rewritten every time an integration changes.
The integration layer can evolve independently.
This is critical for a platform intended to support multiple insurers, aggregators, products, and future external APIs.
Real-time is used where real-time actually matters
Not every screen needs WebSockets.
But some workflows benefit significantly from real-time communication.
The platform uses Socket.IO for chat, with a REST fallback if the connection is unavailable. Other areas such as notifications, calendars, and PBX dashboards use HTTP polling.
This creates a practical hybrid model:
Realtime
├── Chat
└── Interactive messaging
Polling
├── Notifications
├── Calendar
└── Operational dashboards
WebRTC
└── Live voice communicationThe goal is not to make everything “real-time.”
The goal is to use the correct communication pattern for each workload.
The platform currently exposes a large role-aware API surface
One of the things I focused on during implementation was making sure the architecture was not just a collection of UI screens.
The backend capabilities are mapped directly to the role portals.
The API catalog contains roughly 250 unique endpoints generated from the current NestJS controllers and role definitions.
The backend spans domains including:
Authentication
Tenancy
Users
CRM
Campaigns
Leads
Opportunities
Insurance Catalog
Providers
Products
Aggregators
Underwriting
Questionnaires
Quotes
Policies
Billing
Appointments
Chat
Notifications
Telephony
PBX
DIDs
CDR
CMS
Audit Logs
IntegrationsThis matters because an ERP architecture should connect domains.
Not merely place them under the same navigation menu.
The backend functionality matrix explicitly maps these backend modules to the different role portals.
Why I chose a modular monolith
There is enormous pressure today to start every serious platform with:
- Microservices
- Kubernetes
- Event streaming
- Service mesh
- Dozens of independently deployed components
I did not believe that was the correct starting point for this product.
The current architecture is closer to a modular monolith with clearly separated domains.
That means:
One deployable backend
│
├── Auth
├── CRM
├── Quotes
├── Policies
├── Underwriting
├── Telephony
├── Billing
└── IntegrationsThe boundaries are already visible.
If a domain eventually requires independent scaling, deployment, or ownership, it can be extracted with a much clearer understanding of real workload boundaries.
For example, future candidates could include:
- Telephony event processing
- Quote aggregation
- Notification delivery
- AI processing
- Document generation
But architecture should follow operational demand.
Not fashion.
The most interesting part is what happens next
The current product is not the end state.
It is the foundation.
The architecture creates a path toward:
AI insurance assistants
Agents could receive contextual assistance during calls.
Customers could receive guided questionnaire support.
Underwriters could receive summarized risk analysis.
Voice AI
The telephony architecture can become a foundation for AI voice agents that qualify leads, collect information, schedule appointments, and transfer qualified customers to human agents.
Advanced analytics
Because CRM activity and calls are connected, the platform can eventually analyze:
Lead Source
↓
Campaign
↓
Call Attempts
↓
Conversations
↓
Opportunity
↓
Quote
↓
PolicyThat makes end-to-end conversion analytics possible.
Provider integrations
The adapter architecture can expand from database-backed flows into real insurer and aggregator APIs without changing the entire ERP.
White-label insurance platforms
The multi-tenant model creates a path toward independent branded environments for:
- DSAs
- Agencies
- Brokers
- Enterprise insurance distributors
My biggest architectural lesson
The hardest part of building an ERP is not creating the dashboards.
The hardest part is deciding:
Who owns the data?
Who can see the data?
How does work move between roles?
Which systems are the source of truth?
Where should integrations end and core business logic begin?
For InsuranceERP, I started with those questions.
The result is an architecture where:
Organization Hierarchy
+
Role-Based Access
+
Tenant Isolation
+
CRM
+
Underwriting
+
Quotes
+
Policies
+
Telephony
+
Customer Self-Service
=
Insurance Operating PlatformThat is the vision behind InsuranceERP.
Not another CRM.
Not another dialer.
Not another policy portal.
A connected architecture for the full insurance distribution lifecycle.
I’m building in public
I am particularly interested in connecting with:
- Insurance technology companies
- InsurTech founders
- DSAs and insurance distribution networks
- Insurance agencies
- Aggregator API providers
- Telecom and CPaaS companies
- AI voice companies
- CTOs and product leaders building insurance platforms
I would especially like feedback from people who have worked with the operational complexity of insurance distribution.
What would you change in this architecture?
And more importantly:
What is the one insurance workflow you believe existing ERP and CRM platforms still get wrong?
