Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProyectoFerretek/FerreMarket/llms.txt

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

The Customers module (/clientes) maintains the client base for FerreMarket. It supports two distinct client types — natural persons and legal entities — each with its own set of required fields and tax identification. The module surfaces purchase history (count, total CLP spent, and last purchase date) derived live from the ventas table, and provides grid and table views with rich search and filter capabilities.
In Chile, RUN (Rol Único Nacional) is the national identity number assigned to natural persons (individuals), while RUT (Rol Único Tributario) is the tax identification number used by legal entities and businesses. FerreMarket stores these as separate fields (run for individuals, rut for companies) to ensure invoicing and legal compliance. Both numbers follow the same format (XX.XXX.XXX-X) but are issued and administered separately.

Customer Types

FerreMarket supports two tipoCliente values, each with a distinct form and data shape:

Individual (tipoCliente: 'individual')

FieldDescription
nombreFirst name
apellidosLast name(s)
emailContact email address
telefonoContact phone number
direccionPhysical address
runRUN — Chilean national identity number for natural persons
Individual names are stored as nombre + ' ' + apellidos when loaded from Supabase and displayed as a single full name throughout the UI.

Business (tipoCliente: 'empresa')

FieldDescription
razonSocialLegal company name (stored as razonsocial in Supabase)
nombreComercialTrading name (stored as nombre in Supabase)
rutRUT — Chilean tax ID for legal entities
giroBusiness activity category (industry/sector code)
emailCorporate contact email
telefonoCorporate contact phone number
direccionRegistered business address
Business clients are distinguished in the UI by a Building2 icon in place of the initial letter avatar, and by a purple Empresa badge.

Cliente Interface

The full Cliente TypeScript interface from src/types/index.ts:
FieldTypeDescription
idstring (optional)Numeric Supabase primary key
tipoClientestring'individual' or 'empresa'
estado'activo' | 'inactivo'Account status
nombrestring (optional)Full name (individual) or trading name (company)
apellidosstring (optional)Surname — individual clients only
emailstring (optional)Email address
telefonostring (optional)Phone number
direccionstring (optional)Physical address
runstring (optional)Individual tax ID
rutstring (optional)Business tax ID
girostring (optional)Business activity — companies only
razonSocialstring (optional)Legal company name — companies only
nombreComercialstring (optional)Trading name — companies only
notasstring (optional)Free-text internal notes
comprasnumber (optional)Total number of sales transactions for this client
totalComprasnumber (optional)Cumulative CLP value of all purchases
ultimaComprastring (optional)ISO 8601 timestamp of the most recent purchase
fechaCreacionstring (optional)ISO 8601 timestamp of when the record was created
ultimaModificacionstring (optional)ISO 8601 timestamp of the last edit

Adding Customers

1

Open the modal

Click the orange Nuevo Cliente button in the top-right header. ClienteModal opens with the type selector defaulting to Individual.
2

Select client type

Toggle between Individual and Empresa. The form fields update immediately to match the selected type — individual fields (nombre, apellidos, RUN) swap for company fields (razonSocial, nombreComercial, RUT, giro).
3

Fill in required fields

Complete all visible fields. Email and phone are required for both types.
4

Save

On save, agregarCliente(tipoCliente, dataCliente) maps the form values to the Supabase clientes column schema (e.g. razonSocialrazonsocial, ultimaCompraultimacompra) and inserts the row. The client list reloads automatically.

Customer Status

Each client has an estado field with two possible values:
EstadoBadgeBehaviour
activoGreen pillClient appears in the VentaModal client selector and is available for new sales
inactivoRed pillClient is excluded from the new-sale client dropdown and cannot be assigned to new transactions
Status is set to 'activo' automatically when a client is created via agregarCliente.

Purchase History

Purchase statistics are calculated live from the ventas table during obtenerClientes() and are not stored as columns on the clientes table. Each time the Customers page loads, two async calls are made per client:
StatFunctionSupabase query
comprasobtenerCantidadComprasClientePorId(id)COUNT(*) from ventas WHERE cliente = id
totalComprasobtenerTotalComprasClientePorId(id)SUM(total) from ventas WHERE cliente = id
ultimaCompra is a column on the clientes table that is updated to the current Santiago timestamp every time a new sale is created for that client via agregarVenta. The Customers page also surfaces a quick VIP indicator in the stats row: clients with 10 or more purchases are counted separately as “VIP (10+ compras)”, and clients with a ultimaCompra within the last 30 days are counted as “Activos (30 días)”.

Editing and Deleting

Editing: Click the Editar button on a customer card or the pencil icon in the table actions row. ClienteModal opens pre-populated with the client’s current values. On save, actualizarCliente() is called. Deleting:
1

Click the delete icon

Click the red Trash icon on a card or in the table row. The client is stored in clienteSeleccionado and ConfirmDialog opens.
2

Confirm deletion

The dialog reads: “¿Estás seguro de que deseas eliminar al cliente ‘[nombre]’? Esta acción no se puede deshacer.”
3

Record removed

eliminarCliente(id) executes DELETE FROM clientes WHERE id = ?. The list refreshes automatically.
The search bar matches against nombre, email, telefono, and identificacion simultaneously. The identificacion check is present in the client filter expression in Clientes.tsx, though it is not a named field on the Cliente TypeScript interface — it will evaluate to undefined for all client objects and therefore never matches.

Build docs developers (and LLMs) love