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 B2B Import ERP database is a multi-tenant PostgreSQL schema hosted on Supabase. Every design decision is driven by three principles: hard tenant isolation (all operational rows carry tenant_id), full auditability (every mutation is tracked by triggers writing to audit_log), and reversibility (rows are never physically deleted — deleted_at timestamps mark records as inactive). The schema is built up by 30+ ordered SQL migrations under supabase/migrations/.

Global Conventions

Every operational table (exceptions noted below) shares these columns:
ColumnTypeDefaultDescription
idUUIDgen_random_uuid()Immutable primary key.
tenant_idUUID NOT NULLForeign key → tenants(id). RLS is enforced on this column.
created_atTIMESTAMPTZNOW()Insert timestamp.
updated_atTIMESTAMPTZNOW()Auto-updated by a BEFORE UPDATE trigger.
deleted_atTIMESTAMPTZNULLSoft-delete marker. NULL = active record.
created_byUUIDFK → users(id). Set by the Server Action that created the row.
All queries issued by Server Actions filter .is("deleted_at", null) to exclude soft-deleted rows automatically.
The audit_log and user_access_logs tables are append-only. Records are never updated or deleted — even soft-deletes are blocked by a trigger that raises an exception on DELETE. This preserves an unbroken forensic record of all changes.

Core Tables

tenants

The root entity. One row per company that licenses the platform.
ColumnTypeNotes
idUUID PK
tenant_codeVARCHAR(50) UNIQUEHuman-readable slug used in URLs and Server Action calls (e.g. "apex").
nameVARCHAR(200)Short display name.
legal_nameVARCHAR(250)Full legal entity name.
tax_idVARCHAR(100) UNIQUENIT / RFC. Globally unique.
emailVARCHAR(200)
phoneVARCHAR(50)
statustenant_status_enum'Activo' | 'Inactivo' | 'Suspendido'
created_atTIMESTAMP
updated_atTIMESTAMP

users

Operational users. Linked to Supabase Auth via auth_user_id.
ColumnTypeNotes
idUUID PK
tenant_idUUIDNULL for SUPER_ADMIN platform users.
auth_user_idUUID UNIQUEMaps to auth.users.id in Supabase.
employee_codeVARCHAR(50)
first_nameVARCHAR(100)
last_nameVARCHAR(100)
emailVARCHAR(200)Unique per tenant.
phoneVARCHAR(50)
site_idUUIDFK → sites(id).
area_idUUIDFK → areas(id).
manager_idUUIDSelf-referencing FK for org hierarchy.
is_platform_userBOOLEANtrue for SUPER_ADMIN — bypasses all RLS.
statususer_status_enum'Activo' | 'Inactivo' | 'Bloqueado'

user_permissions

Row-level permission overrides — grants or revokes individual permissions outside of role assignments.
ColumnTypeNotes
idUUID PK
tenant_idUUID
user_idUUIDFK → users(id).
permission_idUUIDFK → permissions(id).
grantedBOOLEANtrue = explicit grant; false = explicit revoke.
assigned_atTIMESTAMP
assigned_byUUIDFK → users(id).

clients

B2B customer companies. Each client belongs to exactly one tenant.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
client_codeVARCHAR(50)Auto-generated CLI-000001 by trigger. Immutable after creation.
client_typeVARCHAR(50)'Empresa' | 'Persona'
legal_nameVARCHAR(250)Full legal name.
commercial_nameVARCHAR(250)Trade name.
tax_idVARCHAR(100)Unique per tenant (UNIQUE(tenant_id, tax_id)).
industryVARCHAR(150)Segment / industry vertical.
emailVARCHAR(200)
phoneVARCHAR(50)
countryVARCHAR(100)
cityVARCHAR(100)
assigned_user_idUUID NOT NULLAccount owner. FK → users(id).
statusVARCHAR(50)PROSPECTO | ACTIVO | INACTIVO | BLOQUEADO | ARCHIVADO
deleted_atTIMESTAMPSoft-delete.

client_contacts

Individual contacts within a client company.
ColumnTypeNotes
idUUID PK
client_idUUID NOT NULLFK → clients(id).
tenant_idUUID NOT NULL
first_nameVARCHAR(100)
last_nameVARCHAR(100)
positionVARCHAR(150)Job title.
emailVARCHAR(200)
phoneVARCHAR(50)
mobileVARCHAR(50)
is_primaryBOOLEANA trigger enforces at most one primary contact per client.
statusVARCHAR(50)'ACTIVO' | 'INACTIVO'
deleted_atTIMESTAMP

requirements

Customer service requests and technical requirements.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
requirement_codeVARCHAR(50)Auto-generated sequential code.
titleVARCHAR(250)Short description.
categoryVARCHAR(100)Service type (e.g. fabricacion).
priorityVARCHAR'LOW' | 'MEDIUM' | 'HIGH'
statusVARCHARBORRADOR | NUEVO | EN_REVISION | DIAGNOSTICO | COTIZACION | COMPLETADO | CANCELADO
client_idUUID NOT NULLFK → clients(id).
engineering_user_idUUIDAssigned engineer. FK → users(id).
sales_user_idUUIDAssigned sales rep. FK → users(id).
deleted_atTIMESTAMP

quotes

Commercial quotations linked to clients and optionally to a requirement.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
quote_codeVARCHAR(50)Auto-generated sequential code.
client_idUUID NOT NULLFK → clients(id).
requirement_idUUIDOptional FK → requirements(id).
assigned_user_idUUIDQuote owner. FK → users(id).
valid_untilDATEQuote expiry date.
subtotalNUMERICPre-tax total.
total_amountNUMERICFinal amount including tax.
statusVARCHARBORRADOR | EN_REVISION | ENVIADA | APROBADA | RECHAZADA | VENCIDA

quote_items

Line items belonging to a quote.
ColumnTypeNotes
idUUID PK
quote_idUUID NOT NULLFK → quotes(id).
tenant_idUUID NOT NULL
item_orderINTEGERDisplay sort order.
item_typeVARCHARProduct, service, etc.
descriptionTEXT
quantityNUMERIC
unitVARCHARUnit of measure (e.g. "UNIDAD").
unit_priceNUMERIC
discount_amountNUMERICAbsolute discount (not percentage).
tax_percentNUMERICTax rate applied to this line.

jobs

Field service work orders.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
job_codeVARCHAR(50)Auto-generated JOB-2026-XXX.
client_idUUIDFK → clients(id).
requirement_idUUIDFK → requirements(id).
site_id / area_idUUIDFK → sites(id) / areas(id).
titleVARCHAR(100)
descriptionTEXT
assigned_user_idUUIDAssigned technician/engineer.
planned_start_dateTIMESTAMPTZ
planned_end_dateTIMESTAMPTZ
priorityVARCHARLOW | MEDIUM | HIGH
statusVARCHARPENDIENTE | EN_EJECUCION | COMPLETADA | CANCELADA

inventory_items

Product/material master data.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
item_codeVARCHAR(50)Unique per tenant.
nameVARCHAR(250)
categoryVARCHAR(100)
unit_typeVARCHAR(50)Unit of measure.
purchase_priceNUMERICCost price.
reorder_pointNUMERICMinimum stock before reorder alert.

inventory_movements

Inventory transaction log (entrances, exits, transfers).
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
movement_codeVARCHAR(50)Auto-generated MOV-2026-XXXX.
item_idUUID NOT NULLFK → inventory_items(id).
movement_typeVARCHAREntrada | Salida | Transferencia
quantityNUMERIC
unit_costNUMERICCost at time of movement.
warehouse_idUUIDFK → warehouses(id). Used for Entrada/Salida.
source_warehouse_idUUIDFK for transfers.
destination_warehouse_idUUIDFK for transfers.
statusVARCHARAplicado | Pendiente | Cancelado

invoices

Billing documents issued to clients.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
invoice_codeVARCHAR(50)Auto-generated FAC-2026-XXXX.
client_idUUID NOT NULLFK → clients(id).
quote_idUUIDOptional FK → quotes(id).
invoice_dateDATE
due_dateDATE
subtotal_amountNUMERIC
tax_amountNUMERIC
total_amountNUMERIC
paid_amountNUMERICCumulative payments received.
balance_amountNUMERICtotal_amount − paid_amount.
statusVARCHARBORRADOR | EMITIDA | PARCIALMENTE_PAGADA | PAGADA | ANULADA
payment_statusVARCHARWompi gateway status mirror.
payment_linkTEXTCheckout URL.
deleted_atTIMESTAMP

payment_gateways

Payment provider credentials per tenant.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
gateway_typeVARCHAR'WOMPI' (extensible to Stripe, PayU, etc.).
public_keyTEXTPublishable key — safe to expose in checkout widget.
api_urlTEXTGateway API base URL.
environmentVARCHAR'sandbox' | 'production'
is_activeBOOLEANOnly one active gateway is used per tenant.

leads

CRM lead records created from the wizard form, contact forms, or manually by sales.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
client_idUUIDFK → clients(id).
contact_idUUIDFK → client_contacts(id).
lead_sourceVARCHARWEBSITE | MANUAL | REFERIDO etc.
scoreINTEGER0–100 priority score.
risk_levelVARCHARCALIENTE | TIBIO | FRIO | SPAM
statusVARCHARNUEVO | EN_SEGUIMIENTO | CONVERTIDO | PERDIDO
assigned_user_idUUIDFK → users(id).
notesTEXT

audit_log

Append-only table capturing every INSERT, UPDATE, and soft-DELETE across all operational tables via a generic PostgreSQL trigger.
ColumnTypeNotes
idUUID PK
tenant_idUUID
event_codeVARCHAR(50)Event type identifier set by the trigger, e.g. CLIENT_CREATED, CLIENT_STATUS_CHANGED.
entity_typeVARCHAR(100)Table name (e.g. "clients").
entity_idUUIDPrimary key of the affected record.
actionVARCHAR(50)CREATE | UPDATE | DELETE
old_valuesJSONBRow state before the change. NULL for INSERT.
new_valuesJSONBRow state after the change. NULL for DELETE.
user_idUUIDFK → users(id). Resolved from auth.uid().
ip_addressVARCHAR(100)
user_agentTEXT
created_atTIMESTAMP
audit_log is append-only. A trigger blocks physical DELETE statements with RAISE EXCEPTION. Records are never updated or logically deleted. This guarantees a complete and tamper-evident forensic trail.

tenant_settings

Key-value configuration store per tenant, organised by module.
ColumnTypeNotes
idUUID PK
tenant_idUUID NOT NULL
moduleVARCHARLogical group: EMPRESA | LOCALIZACION | IDENTIDAD | DOCUMENTOS etc.
config_keyVARCHARSetting name (e.g. color_primario).
config_valueJSONBSetting value — any JSON-serialisable type.
is_publicBOOLEANWhether the value can be read by unauthenticated requests.
is_encryptedBOOLEANEncrypted values are decrypted via the get_tenant_setting RPC.
updated_atTIMESTAMPTZ
Unique constraint: (tenant_id, module, config_key).

Relationships Diagram

tenants ─────────────────────────────────────────────────┐
   │                                                       │
   ├─ users (tenant_id)                                    │
   │    └─ user_roles → roles                              │
   │    └─ user_permissions → permissions                  │
   │                                                       │
   ├─ clients (tenant_id) ──────────────────┐              │
   │    └─ client_contacts (client_id)      │              │
   │                                        │              │
   ├─ requirements (tenant_id, client_id) ──┤              │
   │                                        │              │
   ├─ quotes (tenant_id, client_id) ────────┤              │
   │    └─ quote_items (quote_id)           │              │
   │                                        │              │
   ├─ jobs (tenant_id, client_id,           │              │
   │        requirement_id)                 │              │
   │                                        │              │
   ├─ invoices (tenant_id, client_id,       │              │
   │            quote_id)                   │              │
   │    └─ invoice_items (invoice_id)       │              │
   │    └─ payment_transactions             │              │
   │         └─ payments                   │              │
   │         └─ payment_reconciliations    │              │
   │                                        │              │
   ├─ leads (tenant_id, client_id) ─────────┘              │
   │    └─ diagnostic_reports (lead_id)                    │
   │                                                       │
   ├─ inventory_items (tenant_id)                          │
   │    └─ inventory_movements (item_id)                   │
   │                                                       │
   ├─ payment_gateways (tenant_id)                         │
   ├─ tenant_settings (tenant_id)                          │
   ├─ tenant_branding_version (tenant_id)                  │
   └─ audit_log (tenant_id) ──────────────────────────────┘

Build docs developers (and LLMs) love