Multi-tenant CRM, built in the open
Customers, deals, quotations, delivery, finance and approvals — for companies selling business services in Indonesia. Go backend, PostgreSQL row-level security, React frontend.
Early but real: the backend runs in production and tenant isolation is verified. Finance and commissions are not built yet — see Status before you commit to it.
Where it actually stands
The same table as the README, kept honest. Nothing here is marked finished unless it runs in production.
- Go backend foundation (tenancy, auth, permissions) Live
- Code complete and running in production.
- Multi-tenant isolation (PostgreSQL RLS) Live
- Verified against the live database: a tenant cannot reach another tenant’s rows, even with an explicit query.
- React frontend In progress
- All 25 modules present. The service layer is being ported module by module from the old PHP protocol to the Go API.
- Business modules (customers, deals, delivery, finance…) In progress
- Products, customers, deals, quotations and delivery are live. Finance and commissions are not written yet.
How it is put together
- Go 1.23 + Echo v4
- Middleware chain carries tenancy, auth and rate limiting.
- PostgreSQL 16 + row-level security
- Every request sets
app.tenant_id. The app connects as a non-owner role, so a handler that forgetsWHERE tenant_idis still blocked by the database. - sqlc + pgx/v5
- Hand-written SQL generating type-safe Go. No ORM, so the query a report runs is the query you read.
- JWT, 15m access + 7d revocable refresh
- Login is tenant code + username + password; usernames are unique within a tenant.
- React 18 + umi + Ant Design
- Three locales throughout: English, Bahasa Indonesia, 简体中文.
What happens next
In this order. Each step has to work before the following one means anything.
- Finish porting the frontend service layer, module by module, from the PHP action protocol to the Go REST API.
- Build file upload for delivery, so a task’s documents live in the system rather than in a chat thread.
- Write the finance and commission modules — the last two business areas still missing.
License
AGPL-3.0. AGPL differs from GPL in one way that matters for a CRM: run a MODIFIED copy and let people use it over a network, and you owe those users the source of your version. Running it unmodified, or only for yourself, triggers nothing.
If that does not suit you — building on ChuhaiCRM without publishing your changes, say — a commercial license can be arranged. Open an issue.