Back to blog
July 1, 2022

Creating a CRM from scratch using SaasRock’s Entity Builder

  • Name
Creating a CRM from scratch using SaasRock’s Entity Builder

I’ll write about the steps I take as I’m creating my own CRM for SaasRock’s core.

I’m going to use its Entity Builder, and add everything I need on the fly.

The only thing I know about CRM is its goal: managing relationships.

Let’s start by exploring popular CRM solutions to find out the core structure for an actual CRM.

1. Research — Existing CRM tools

According to Zapier, Pipedrive is one of the best CRM apps. So I went ahead and created an account.


And now let’s see how Freshsales lists deals:


2. Core Models — Contacts & Deals

Right from the start, I’m able to conclude that we need 2 models:

  • Contact: Email, Name, Phone, Company, Title, and Status (Lead, Prospect, Customer, Partner…).
  • Deal: Contact, Name, Value, and Status (Open, Won, Lost).

Deal statuses should be customizable since companies must have their own sales processes, so I’ll use the SaasRock’s Entity Builder to define their properties.

A Status would determine WHAT’s the next action and WHO is responsible for it, and WHEN it should be done.

What, Who and When sound like a Workflow more than a simple status field, so let’s keep that in mind.

3. List Views — Table or Kanban & Filters

We can use a table for Contacts:

Contacts Table

This view looks too plain, it needs a way to filter specific things, such as “Lead” status, so I went ahead and created a Filter mechanism:

Table Filters

And Deals should not have a Table view:

Deals Table

But a Kanban view:

Deals Kanban Board

I documented this process with a few tweets:

4. Workflow — Deal Stages

I could keep the Deal.Status field as a simple text field, but making the status as a workflow status could give us a couple of benefits:

  • Add custom workflow states
  • Assign to people on status change
  • Send emails on status change
  • Create and assign predefined tasks

Since I’m building the CRM on top of my Remix SaaS boilerplate, SaasRock, I’ll use the Entity Builder to create Contacts and Deals. As of right now, Workflows have not been implemented:

Entity Workflow — In construction

So let’s build a Workflows engine from scratch as well, we need the following database models:

  • WorkflowState: Title and Internal Status (Draft, Pending, Completed or Cancelled).
  • WorkflowStep: From state, To state, and an Action title.
  • WorkflowStepAssignee: Who to assign when reaching a certain Step (Current Tenant?, Roles?, Groups?, Users?).

Starting from the UI, it would look something like this:

Deal Workflow States

And Steps:

Deal Workflow Steps

5. Row Details View

Since I want to build CRM entities on top of the Entity Builder, I’ll need to make some changes there first. Currently, there are 3 elements on the Edit Row View:

  • Details: Property fields
  • Actions: Share, Update and Delete
  • Activity: Row events

Employees Row View

I need to add:

  • Tags: New property type for colorful tags
  • Tasks: Ability to assign tasks to other members
  • Comments: A simple comment mechanism for every row
  • Workflow Steps: Actions to send the row to a new state


First things first: Let’s add Tags, Comments, and Tasks.

I grouped Events/Logs and Comments into an Activity section:

Entity Row Comments

I made a demo about this functionality:

Custom Entity Row Comments Preview - SaasRock

I created a Postmark template “comment-notification” so the Row creator can receive emails for every comment. We’ll leave email notification preferences for another time.

Comment Email Notification

5.2. Tags

Now we want to Create and Update Entity Tags and set them to Rows. Here’s what an empty state would look like:

Row Tags Empty State

And here’s the Row Tags route/modal.

Employee Tags Modal

5.3. Tasks

Now, I’ll build the RowTask model with user assignment in mind, but right now a simple implementation is fine:

Employee Tasks

5.4. Workflow State and Transitions

Let’s use the WorkflowState and WorkflowStep models, I’ll leave WorkflowStepAssignee for another post.

When a Row is created, it should be set to the first Workflow State that we created, Draft is the default. When Rows are Drafts, we should have only one action (Submit):

Employee Workflow Steps

So every row (that has Workflows enabled), will have this "Submit" action:

Submit Workflow Step

And when the Submit action is performed, the new state should be Pending, which has 3 possible actions:

Recall, Accept and Reject Workflow Transitions

  • Recall → Sends row to back to Draft
  • Accept → Completes the workflow
  • Reject → Cancels the workflow

And whenever a Row reaches its end, it should not have any more actions, but it should show the final State:

Row Workflow End — Completed State

With every workflow action/step performed, there should be an audit trail:

Row Activity

5.5. Row Details View — Final result

I posted a 10-min video about these features:

6. Contacts and Deals using the Entity Builder

SaasRocks’s main goal is to build SaaS applications faster than ever using its Entity Builder, so it would make sense that the CRM is built on top of it.

Watch the end result here:

SaasRock - No-code, Low-code and Custom-code


I know that this is the world’s simplest CRM, but it’s a good start and the Entity Builder got stronger.

Let me know what should I add for the next iteration of the CRM!

If you'd like to see more of what I do, follow me :) or visit my personal blog.