Skip to main content

Step 1 — Set up the CRM project

This tutorial builds a small customer relationship management app on Liberty Next, in six steps: screens, lists of values, a dashboard, roles, the AI assistant and a scheduled job. Everything is done from Settings.

This first step prepares the database and creates the crm connector.


At a glance​

customersid PKnameindustrycountrystatusprimary_emailcreated_by …dealsid PKcustomer_idnamestageamountclose_dateowneractivitiesid PKdeal_idkindnoteshappened_atrecorded_bydeal_stagescode PKlabelordconnector crmSQL · pool defaultCustomers3 sample rowsActivitiesone deal, many activitiesDeal stageslist of valuesThe crm connectorbecomes the app in step 2

What we're building​

StepWe addWhat it teaches
1 — Setup (this page)Tables, sample data, the crm connector.Pools and connectors.
2 — CustomersThe Customers screen and the app's menu.Queries generated from a table, screens, menus.
3 — DealsDeals linked to customers, with their activities in a tab.Dictionary, lists of values, nested tabs.
4 — DashboardA pipeline dashboard.KPIs, charts, the period.
5 — RolesRoles, users, a data scope, company sign-in.Who sees what.
6 — AI and jobsThe AI assistant and a daily job.Assistant, Nomaflow, notifications.

Prerequisites​

NeedWhy
Liberty Next installedSee Installation.
A superuser accountSettings is reserved to superusers.
A SQL clientTo create the tables — psql, DBeaver, or any client connected to the database of the default pool.

The default pool points at the bundled PostgreSQL database on a Docker install, or at a local SQLite file on a Python install without PostgreSQL. The SQL below is written for PostgreSQL; on SQLite, replace SERIAL with INTEGER.


Create the tables​

CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
industry VARCHAR(64),
country VARCHAR(2),
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
primary_email VARCHAR(255),
created_by VARCHAR(64),
created_at TIMESTAMP,
updated_by VARCHAR(64),
updated_at TIMESTAMP
);

CREATE TABLE deal_stages (
code VARCHAR(16) PRIMARY KEY,
label VARCHAR(64) NOT NULL,
ord INTEGER NOT NULL
);

CREATE TABLE deals (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id),
name VARCHAR(255) NOT NULL,
stage VARCHAR(16) NOT NULL DEFAULT 'QUALIFIED' REFERENCES deal_stages(code),
amount DECIMAL(12,2) NOT NULL DEFAULT 0,
close_date DATE,
owner VARCHAR(64),
updated_at TIMESTAMP
);

CREATE TABLE activities (
id SERIAL PRIMARY KEY,
deal_id INTEGER NOT NULL REFERENCES deals(id),
kind VARCHAR(16) NOT NULL,
notes VARCHAR(2000),
happened_at TIMESTAMP NOT NULL,
recorded_by VARCHAR(64)
);

INSERT INTO deal_stages (code, label, ord) VALUES
('QUALIFIED', 'Qualified', 10), ('PROPOSAL', 'Proposal', 20),
('NEGOTIATION', 'Negotiation', 30), ('WON', 'Won', 40), ('LOST', 'Lost', 50);

INSERT INTO customers (name, industry, country, primary_email) VALUES
('ACME Industries', 'Manufacturing', 'FR', 'contact@acme.example'),
('Beta SARL', 'Logistics', 'FR', 'sales@beta.example'),
('Gamma SA', 'Services', 'BE', 'hello@gamma.example');

INSERT INTO deals (customer_id, name, stage, amount, close_date) VALUES
(1, 'Annual contract renewal', 'PROPOSAL', 45000, '2026-11-15'),
(1, 'Training package', 'QUALIFIED', 8500, '2026-12-10'),
(2, 'Logistics platform', 'NEGOTIATION', 120000, '2026-11-30'),
(3, 'Support contract', 'WON', 18000, '2026-10-05');

Create the crm connector​

A connector groups the queries of one database under a name. Once it has a menu, it becomes the crm app.

  1. Open Liberty Next → Build → Connectors, click + Connector.
  2. Name crm, type SQL, pool default. Save.

The connector appears under Data sources in the left list: it has no menu yet. It moves to Apps in Step 2.

To work on another database than the framework's, first add a pool in Liberty Next → Administer → Pools with its URL, then pick it here — see Connectors.


Check​

CheckHow
Tables createdSELECT count(*) FROM customers; returns 3.
Connector createdLiberty Next → Build → Connectors lists crm under Data sources.

→ Step 2 — Customers: the queries, the first screen and the menu.