Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/juadariasmar/inventory_project/llms.txt

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

The product catalog is the foundation of Inventory System. Every product belongs to a category, carries an auto-generated SKU code derived from that category’s prefix, and tracks its own minimum stock threshold. Changes to a product’s price are stored in a separate history table so you always have a full audit trail of who changed what and when.

Product data model

Each Producto record stores the following fields:
FieldTypeDescription
idIntAuto-incremented primary key
nombreStringDisplay name of the product
descripcionString?Optional free-text description
codigoStringUnique SKU within the company (auto-generated or custom)
precioFloatCurrent unit selling price
cantidadIntCurrent stock quantity (updated automatically by movements)
stockMinimoIntMinimum quantity threshold; triggers a low-stock notification when cantidad falls at or below this value plus the alert margin
categoriaIdIntForeign key to the owning Categoria
empresaIdStringTenant isolation key — every query is scoped to this value
creadoEnDateTimeUTC timestamp of record creation
Every product must belong to a category. If you migrate existing products without a category, the system reassigns them to a “Sin clasificar” fallback category automatically.

Category system

Categories group products and provide the prefix used to generate product codes. The Categoria model fields are:
FieldTypeDescription
idIntAuto-incremented primary key
nombreStringUnique category name within the company
prefijoStringUppercase alphanumeric characters derived from the category name (e.g. BEB, ALI). Must be unique within the company.
empresaIdStringTenant key
Both nombre and prefijo have a compound unique constraint per empresaId, so two categories in the same tenant cannot share either value.

Prefix suggestion

When you create a category without supplying a prefix, the system calls generarPrefijoSugerido from src/lib/codigos.ts. The algorithm:
  1. Strips accents and non-alphanumeric characters from the category name and converts it to uppercase.
  2. Takes the first 3 characters as the candidate (e.g. "Bebidas""BEB").
  3. If that prefix is already in use, it extends by one more character ("BEBI") until a free slot is found.
  4. If the name runs out of letters, it appends a numeric suffix ("BEB1", "BEB2", …).
  5. Falls back to "CAT" if the name has no usable letters.

Auto-generated product codes

Product codes follow the format {PREFIJO}-NNNNN (five zero-padded digits). The function siguienteCodigoConsecutivoPorCategoria in src/lib/codigos.ts queries the highest existing sequence number for the given category and returns the next one:
BEB-00001
BEB-00002
ALI-00001
If you supply a custom codigo when creating a product it is used as-is, provided it is unique within the tenant.

Stock management

The stockMinimo field defines the reorder point for a product. The system uses a constant alert margin (MARGEN_ALERTA_STOCK = 2, defined in src/lib/inventario.ts) on top of the minimum:
  • Stock bajocantidad <= stockMinimo + 2
  • Sin stockcantidad <= 0
  • Normal — above the alert margin
Set stockMinimo to the quantity you need on hand at all times. The alert fires while there are still units left, giving you time to reorder before you run out.
When a product enters the stock bajo or sin stock zone after a movement or a sale, the notification service (NotificacionesService.generarAlertasStock) creates a STOCK_BAJO or STOCK_CRITICO notification for the company. See Notifications for details.

Price history

Every time a product’s price is updated, the previous and new values are recorded in HistorialPrecio:
FieldTypeDescription
idIntAuto-incremented primary key
productoIdIntFK to the product
precioAnteriorFloatPrice before the change
precioNuevoFloatPrice after the change
cambiadoPorIdString?FK to the Usuario who made the change (nullable if changed by the system)
creadoEnDateTimeTimestamp of the price change
empresaIdStringTenant key
You can fetch the full price history for a product from GET /api/productos/[id]/historial-precios.

Bulk import

To load products in bulk, use the CSV/Excel import endpoint. First download the official template so your file has the correct column headers:
GET /api/productos/plantilla
The response is an Excel file (.xlsx). Fill it in and then upload it:
POST /api/productos/importar
Content-Type: multipart/form-data

file=<your-filled-template.xlsx>
The importer validates each row, auto-generates codes for rows without a codigo value, and returns a summary of created and failed records.

Bulk delete

To delete multiple products in a single request, send their IDs as an array:
POST /api/productos/bulk-delete
Content-Type: application/json
{
  "ids": [12, 15, 23]
}
Bulk delete is permanent and irreversible. Products with associated movements, sale items, or purchase order items cannot be deleted; the API returns a 409 error for those IDs.

Code example — product object

The following is a representative JSON object returned by GET /api/productos or POST /api/productos:
{
  "id": 42,
  "nombre": "Agua Mineral 500ml",
  "descripcion": "Agua mineral sin gas, presentación 500 ml",
  "codigo": "BEB-00003",
  "precio": 1500,
  "cantidad": 240,
  "stockMinimo": 20,
  "categoriaId": 3,
  "empresaId": "clx9t2k0f0000abcde12fgh34",
  "creadoEn": "2024-11-15T14:30:00.000Z",
  "categoria": {
    "id": 3,
    "nombre": "Bebidas",
    "prefijo": "BEB",
    "empresaId": "clx9t2k0f0000abcde12fgh34"
  }
}

Build docs developers (and LLMs) love