Skip to main content

Overview

The Clientes API provides comprehensive customer management functionality for the POS system. All endpoints require JWT authentication via Bearer token.
All routes are protected with verifyToken middleware. Include your authentication token in the Authorization header.

Authentication

Authorization: Bearer <your_jwt_token>
The JWT token must contain usuario and password fields which are used for database connection credentials.

Create Cliente

POST
endpoint
/api/pos/clientes
Creates a new customer using the stored procedure sp_crear_cliente. The customer code is auto-generated by the database.

Request Body

ct_codigo
string
required
City code (foreign key). Maximum 10 characters.
cli_nombre
string
required
Customer name. Maximum 120 characters.
cli_ruc_ced
string
required
RUC or ID number. Must be numeric (13 digits).
cli_telefono
string
required
Phone number. Must be exactly 10 numeric digits.
cli_mail
string
required
Email address. Maximum 60 characters.
cli_direccion
string
Customer address.
cli_celular
string
Mobile phone number.

Example Request

curl -X POST https://api.example.com/api/pos/clientes \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ct_codigo": "UIO001",
    "cli_nombre": "Juan Pérez",
    "cli_ruc_ced": "1234567890001",
    "cli_telefono": "0987654321",
    "cli_mail": "[email protected]",
    "cli_direccion": "Av. Principal 123",
    "cli_celular": "0998765432"
  }'

Response

message
string
Success message
data
object
Created customer data
201 Success
{
  "message": "Cliente creado exitosamente",
  "data": {
    "cli_codigo": "GENERATED_BY_DB",
    "ct_codigo": "UIO001",
    "cli_nombre": "Juan Pérez",
    "cli_ruc_ced": "1234567890001",
    "cli_telefono": "0987654321",
    "cli_mail": "[email protected]",
    "cli_direccion": "Av. Principal 123",
    "cli_celular": "0998765432",
    "cli_estado": "ACT"
  }
}
400 Validation Error
{
  "errors": [
    "ct_codigo es requerido y máximo 10 caracteres",
    "cli_telefono es requerido y debe tener 10 dígitos numéricos"
  ]
}
500 Server Error
{
  "message": "Error interno al crear cliente",
  "detail": "Database connection error"
}

Get All Clientes

GET
endpoint
/api/pos/clientes
Retrieves a paginated list of all active customers (estado = ‘ACT’). Results are ordered by name and limited to 20 records per page.

Query Parameters

page
integer
default:"1"
Page number for pagination (1-based)

Example Request

curl -X GET "https://api.example.com/api/pos/clientes?page=1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response

message
string
Success message
count
integer
Number of records returned
data
array
Array of customer objects
200 Success
{
  "message": "Listado obtenido correctamente",
  "count": 20,
  "data": [
    {
      "cli_codigo": "CLI001",
      "cli_nombre": "Juan Pérez",
      "cli_ruc_ced": "1234567890001",
      "cli_telefono": "0987654321",
      "cli_mail": "[email protected]",
      "cli_direccion": "Av. Principal 123",
      "cli_celular": "0998765432",
      "cli_estado": "ACT",
      "ct_codigo": "UIO001"
    }
  ]
}
500 Server Error
{
  "message": "Error al obtener clientes"
}

Get Cliente by ID

GET
endpoint
/api/pos/clientes/:id
Retrieves detailed information for a specific customer by their unique code.

Path Parameters

id
string
required
Customer code (cli_codigo)

Example Request

curl -X GET https://api.example.com/api/pos/clientes/CLI001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response

200 Success
{
  "cli_codigo": "CLI001",
  "cli_nombre": "Juan Pérez",
  "cli_ruc_ced": "1234567890001",
  "cli_telefono": "0987654321",
  "cli_mail": "[email protected]",
  "cli_direccion": "Av. Principal 123",
  "cli_celular": "0998765432",
  "cli_estado": "ACT",
  "ct_codigo": "UIO001",
  "cli_fecha_alta": "2024-03-01T10:00:00Z"
}
404 Not Found
{
  "message": "Cliente no encontrado"
}
500 Server Error
{
  "message": "Error al buscar cliente"
}

Search Clientes by Name

GET
endpoint
/api/pos/clientes/search
Performs a case-insensitive partial match search on customer names. Returns up to 10 matching results using ILIKE pattern matching.
The search endpoint uses a different path than the ID lookup. Make sure to use /search before the query parameters.

Query Parameters

name
string
required
Name search term (partial match supported)

Example Request

curl -X GET "https://api.example.com/api/pos/clientes/search?name=juan" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response

200 Success
{
  "data": [
    {
      "cli_codigo": "CLI001",
      "cli_nombre": "Juan Pérez",
      "cli_ruc_ced": "1234567890001",
      "cli_telefono": "0987654321",
      "cli_mail": "[email protected]",
      "cli_direccion": "Av. Principal 123",
      "cli_celular": "0998765432",
      "cli_estado": "ACT",
      "ct_codigo": "UIO001"
    },
    {
      "cli_codigo": "CLI025",
      "cli_nombre": "Juan Carlos Rodríguez",
      "cli_ruc_ced": "1234567890025",
      "cli_telefono": "0987654322",
      "cli_mail": "[email protected]",
      "cli_direccion": "Calle Secundaria 456",
      "cli_celular": "0998765433",
      "cli_estado": "ACT",
      "ct_codigo": "UIO001"
    }
  ]
}
400 Bad Request
{
  "message": "El parámetro 'name' es requerido"
}
500 Server Error
{
  "message": "Error en la búsqueda"
}

Get Clientes for Select

GET
endpoint
/api/pos/clientes/type
Returns a simplified list of active customers containing only code and name. Optimized for dropdown/selector components in UI.

Example Request

curl -X GET https://api.example.com/api/pos/clientes/type \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response

200 Success
[
  {
    "cli_codigo": "CLI001",
    "cli_nombre": "Juan Pérez"
  },
  {
    "cli_codigo": "CLI002",
    "cli_nombre": "María González"
  },
  {
    "cli_codigo": "CLI003",
    "cli_nombre": "Carlos López"
  }
]
500 Server Error
{
  "message": "Error al obtener lista de tipos"
}

Update Cliente

PUT
endpoint
/api/pos/clientes/:id
Updates an existing customer. Only provided fields will be updated (partial update supported using COALESCE).

Path Parameters

id
string
required
Customer code (cli_codigo)

Request Body

All fields are optional. Only include fields you want to update.
cli_nombre
string
Customer name. Maximum 120 characters.
cli_ruc_ced
string
RUC or ID number. Must be numeric.
cli_telefono
string
Phone number. Must be exactly 10 numeric digits.
cli_mail
string
Email address. Maximum 60 characters.
cli_direccion
string
Customer address.
cli_celular
string
Mobile phone number.
ct_codigo
string
City code. Maximum 10 characters.

Example Request

curl -X PUT https://api.example.com/api/pos/clientes/CLI001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "cli_telefono": "0987654999",
    "cli_mail": "[email protected]"
  }'

Response

200 Success
{
  "message": "Cliente actualizado correctamente",
  "data": {
    "cli_codigo": "CLI001",
    "cli_nombre": "Juan Pérez",
    "cli_ruc_ced": "1234567890001",
    "cli_telefono": "0987654999",
    "cli_mail": "[email protected]",
    "cli_direccion": "Av. Principal 123",
    "cli_celular": "0998765432",
    "cli_estado": "ACT",
    "ct_codigo": "UIO001"
  }
}
400 Validation Error
{
  "errors": [
    "cli_telefono es requerido y debe tener 10 dígitos numéricos"
  ]
}
404 Not Found
{
  "message": "Cliente no encontrado para actualizar"
}
500 Server Error
{
  "message": "Error al actualizar cliente"
}

Delete Cliente

DELETE
endpoint
/api/pos/clientes/:id
Performs a logical deletion by setting customer status to ‘INA’ (inactive). The customer record is not physically removed from the database.
This is a soft delete operation. The customer status is changed to inactive and the cli_fecha_alta timestamp is updated.

Path Parameters

id
string
required
Customer code (cli_codigo)

Example Request

curl -X DELETE https://api.example.com/api/pos/clientes/CLI001 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response

200 Success
{
  "message": "Cliente eliminado correctamente"
}
500 Server Error
{
  "message": "Error al eliminar cliente"
}

Data Validation Rules

The following validation rules are enforced by the validateClienteDTO function:
All validation errors return a 400 status code with an errors array containing specific validation messages.
FieldRuleError Message
ct_codigoRequired (create), max 10 chars”ct_codigo es requerido y máximo 10 caracteres”
cli_nombreRequired (create), max 120 chars”cli_nombre es requerido y máximo 120 caracteres”
cli_ruc_cedRequired (create), numeric”cli_ruc_ced es requerido y debe ser numérico”
cli_telefonoRequired (create), exactly 10 digits”cli_telefono es requerido y debe tener 10 dígitos numéricos”
cli_mailRequired (create), max 60 chars”cli_mail es requerido y máximo 60 caracteres”

Customer Status Values

cli_estado
enum

Error Handling

All endpoints follow consistent error response patterns:

Common Error Responses

400 Bad Request
{
  "errors": ["Validation error message 1", "Validation error message 2"]
}
401 Unauthorized
{
  "message": "Token inválido o expirado"
}
404 Not Found
{
  "message": "Cliente no encontrado"
}
500 Internal Server Error
{
  "message": "Error interno al procesar solicitud",
  "detail": "Detailed error message"
}

Implementation Details

Source Code Reference

  • Routes: src/routes/pos.cliente.routes.js
  • Controller: src/controllers/pos.cliente.controller.js
  • Model: src/models/cliente.model.js
  • DTO: src/dtos/cliente.dto.js
  • Stored Procedure: sp_crear_cliente (database)

Database Connection

The API uses JWT-based database connection credentials:
const connectFromJWT = (req) => {
  const { usuario, password } = req.user;
  return getConnectionWithCredentials(usuario, password);
};
Each request establishes a new database connection using credentials extracted from the JWT token, ensuring proper authentication and authorization at the database level.

Pagination

List endpoints use page-based pagination:
  • Default page: 1
  • Records per page: 20
  • Offset calculation: (page - 1) * limit

Search Implementation

The name search uses PostgreSQL’s ILIKE operator for case-insensitive pattern matching:
SELECT * FROM public.cliente 
WHERE cli_nombre ILIKE '%search_term%' 
LIMIT 10

Build docs developers (and LLMs) love