Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ency07/B2B-import/llms.txt

Use this file to discover all available pages before exploring further.

The Clients module is the commercial foundation of B2B Import ERP. It centralises all information about the B2B companies your tenant serves — from the moment a company is registered as a prospect through its active commercial relationship, potential inactivation, and final archival. Every mutation is fully scoped to your tenant via Row Level Security and recorded in both the technical audit_log and the semantic business_events table.

Client Lifecycle

Clients move through a defined set of states enforced by database-level triggers. No status change can be performed directly against the database; all transitions must go through domain services that validate permissions, record audit entries, and emit business events.
PROSPECTO ──► ACTIVO ──► INACTIVO ──► ARCHIVADO


            BLOQUEADO ──► ACTIVO
TransitionCondition
PROSPECTO → ACTIVOCommercial qualification complete, client formally onboarded
ACTIVO → INACTIVOClient pauses operations or relationship placed on hold
ACTIVO → BLOQUEADOCompliance or payment issue requires immediate restriction
BLOQUEADO → ACTIVOBlock lifted; client reinstated
INACTIVO → ACTIVOClient relationship reactivated
INACTIVO → ARCHIVADOPermanently closed; soft-deleted from active views
The transitions PROSPECTO → ARCHIVADO and BLOQUEADO → ARCHIVADO are not permitted. A blocked client must be unblocked first; a prospect must be activated before it can be archived.

Key Fields

The following fields are defined on the clients table (migration 20260617000002_clients_core.sql):
FieldTypeRequiredUniqueDescription
iduuidPrimary key, auto-generated
tenant_iduuidOwning tenant; enforced by RLS
client_codevarchar(50)Per tenantAuto-generated as CLI-000001; immutable after creation
legal_namevarchar(250)Official registered company name
tax_idvarchar(100)Per tenantTax identification number; unique within the tenant
cityvarchar(100)City of the client’s primary address
emailvarchar(200)Primary commercial contact email
statusenumPROSPECTO · ACTIVO · INACTIVO · BLOQUEADO · ARCHIVADO
assigned_user_iduuidCommercial owner; every client must have a responsible user
created_attimestampRecord creation timestamp (auto-set by trigger)
deleted_attimestampPopulated on soft-delete; NULL means the record is active
client_code and tax_id are unique per tenant, so the same tax_id can exist across different tenants without conflict.

Client Contacts

Each client can have multiple contacts stored in the client_contacts table. One contact per client may be designated as the primary contact using the is_primary flag.
FieldTypeDescription
iduuidPrimary key
client_iduuidFK to clients.id
first_namevarchar(100)Contact’s first name (required)
last_namevarchar(100)Contact’s surname
positionvarchar(150)Job title or role
emailvarchar(200)Contact email
phone / mobilevarchar(50)Direct phone numbers
is_primarybooleanMarks the main point of contact
statusenumACTIVO · INACTIVO
Only one contact per client can hold is_primary = true. The trigger trg_handle_primary_contact automatically demotes the previous primary contact when a new one is promoted — no manual cleanup is required.

Server Action Reference

ClientRow Interface

interface ClientRow {
  id: string;
  tenant_id: string;
  client_code: string;
  client_type: "Empresa" | "Persona";
  legal_name: string;
  commercial_name: string | null;
  tax_id: string;
  industry: string | null;
  email: string | null;
  phone: string | null;
  country: string;
  city: string | null;
  status: "PROSPECTO" | "ACTIVO" | "INACTIVO" | "BLOQUEADO" | "ARCHIVADO";
  assigned_user_id: string;
  created_at: string;
  deleted_at: string | null;
}

Available Actions

getClients

getClients(tenantCode?)Returns all non-deleted clients for the resolved tenant, ordered by creation date descending.
const clients = await getClients("acme");

createClient

createClient(tenantCode, clientData)Creates a new client in PROSPECTO status. The client_code is auto-generated by the database trigger as CLI-XXXXXX. An audit log entry is written automatically via process_audit_log().
const client = await createClient("acme", {
  legal_name: "Industrias XYZ S.A.",
  tax_id: "900123456-7",
  country: "Colombia",
  assigned_user_id: userId,
});

Audit Events

The system records two independent audit layers for every client mutation.

Technical Audit (audit_log)

Driven by the audit_clients_trigger which fires process_audit_log() after every INSERT, UPDATE, or DELETE:
SQL Operationevent_code
INSERTCLIENTS_CREATE
UPDATECLIENTS_UPDATE
Physical DELETE operations are blocked at the RLS policy level for tenant users. A Super Admin purge would emit CLIENTS_DELETE.

Business Events (business_events)

Semantic events emitted by dispatch_client_events() after each meaningful state change:
Event CodeTrigger ConditionPayload Fields
CLIENT_CREATEDNew client registeredclient_code, legal_name, tax_id, status, assigned_user_id
CLIENT_UPDATEDGeneral data fields changedchanges object with old/new per field
CLIENT_STATUS_CHANGEDstatus column updatedold_status, new_status
CLIENT_ARCHIVEDStatus set to ARCHIVADOclient_code, legal_name, archived_at
CLIENT_BLOCKEDStatus set to BLOQUEADOblock_reason, blocked_at
CLIENT_UNBLOCKEDStatus changed away from BLOQUEADOunblock_reason, unblocked_at
CLIENT_ASSIGNEDassigned_user_id changedold_assigned_user_id, new_assigned_user_id
Contact-level events (CONTACT_CREATED, CONTACT_UPDATED, CONTACT_DELETED, CONTACT_PRIMARY_CHANGED) and site events (CLIENT_SITE_CREATED, CLIENT_SITE_UPDATED, CLIENT_SITE_DELETED) are emitted by their respective triggers.

RBAC — Role-Based Access

Access to the Clients module is governed by Supabase RLS policies and database-level permission triggers.
ActionRoles Permitted
View clientsAll authenticated tenant users (clients_select_tenant)
Create clientADMIN_EMPRESA, GERENTE_GENERAL, DIRECTOR_COMERCIAL, EJECUTIVO_COMERCIAL
Edit clientADMIN_EMPRESA, GERENTE_GENERAL, DIRECTOR_COMERCIAL, EJECUTIVO_COMERCIAL
Change statusADMIN_EMPRESA, GERENTE_GENERAL, DIRECTOR_COMERCIAL, EJECUTIVO_COMERCIAL
View soft-deleted recordsAUDITOR (and Platform Super Admin)
RLS policies enforce tenant_id isolation at the database row level. It is impossible for a user in tenant A to read or write records belonging to tenant B, regardless of the application layer.

Dashboard

Navigate to the Clients dashboard for your tenant:
/dashboard/clients?tenant=<code>
Replace <code> with your tenant’s slug (e.g. /dashboard/clients?tenant=acme).

Build docs developers (and LLMs) love