Skip to main content

Categorías API

The Categorías (Categories) API provides read-only access to product and material categories used throughout the POS system. Categories are master data used to classify products, raw materials, and other inventory items.

Endpoints Overview

MethodEndpointAuthenticationDescription
GET/api/pos/categoriaRequiredGet all categories
The Categorías API is read-only. Category management is typically handled through database administration tools or dedicated admin interfaces.

GET /api/pos/categoria

Retrieve a complete list of all categories in the system, ordered alphabetically by description.

Authentication

Authorization
string
required
Bearer token received from the login endpointExample: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response

Returns an array of category objects, each containing:
cat_codigo
string
Unique category code identifier
cat_descripcion
string
Category description/name
cat_estado
string
Category status (ACT for Active, INA for Inactive)

Example Request

curl -X GET http://localhost:3000/api/pos/categoria \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

[
  {
    "cat_codigo": "CAT001",
    "cat_descripcion": "Bebidas",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT002",
    "cat_descripcion": "Lácteos",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT003",
    "cat_descripcion": "Panadería",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT004",
    "cat_descripcion": "Carnes",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT005",
    "cat_descripcion": "Frutas y Verduras",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT006",
    "cat_descripcion": "Granos y Cereales",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT007",
    "cat_descripcion": "Condimentos y Especias",
    "cat_estado": "ACT"
  },
  {
    "cat_codigo": "CAT008",
    "cat_descripcion": "Dulces y Confitería",
    "cat_estado": "ACT"
  }
]
Results are ordered alphabetically by cat_descripcion for easy reference in dropdown menus and selection interfaces.
{
  "message": "No se encontraron categorías"
}
This response indicates that no categories exist in the database. This should not occur in a properly initialized system.
{
  "message": "Token inválido o expirado"
}
This error occurs when:
  • No Authorization header is provided
  • The token is invalid or malformed
  • The token has expired

Usage Examples

JavaScript - Populate Dropdown

async function loadCategories() {
  try {
    const response = await fetch('http://localhost:3000/api/pos/categoria', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    
    const categories = await response.json();
    
    const select = document.getElementById('categorySelect');
    categories.forEach(cat => {
      const option = document.createElement('option');
      option.value = cat.cat_codigo;
      option.textContent = cat.cat_descripcion;
      select.appendChild(option);
    });
  } catch (error) {
    console.error('Error loading categories:', error);
  }
}

Python - Filter Active Categories

import requests

def get_active_categories(token):
    url = "http://localhost:3000/api/pos/categoria"
    headers = {"Authorization": f"Bearer {token}"}
    
    response = requests.get(url, headers=headers)
    categories = response.json()
    
    # Filter only active categories
    active_categories = [
        cat for cat in categories 
        if cat['cat_estado'] == 'ACT'
    ]
    
    return active_categories

# Usage
active_cats = get_active_categories(token)
for cat in active_cats:
    print(f"{cat['cat_codigo']}: {cat['cat_descripcion']}")

React - Categories Hook

import { useState, useEffect } from 'react';

function useCategories(token) {
  const [categories, setCategories] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchCategories() {
      try {
        const response = await fetch('http://localhost:3000/api/pos/categoria', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });
        
        if (!response.ok) {
          throw new Error('Failed to fetch categories');
        }
        
        const data = await response.json();
        setCategories(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }

    fetchCategories();
  }, [token]);

  return { categories, loading, error };
}

// Usage in component
function CategorySelector() {
  const token = localStorage.getItem('token');
  const { categories, loading, error } = useCategories(token);

  if (loading) return <div>Cargando categorías...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <select>
      <option value="">Seleccione una categoría</option>
      {categories.map(cat => (
        <option key={cat.cat_codigo} value={cat.cat_codigo}>
          {cat.cat_descripcion}
        </option>
      ))}
    </select>
  );
}

Error Codes

Status CodeDescription
200Request successful
401Unauthorized - invalid or missing token
404No categories found in database
500Internal server error

Data Model

Category Object Structure

interface Categoria {
  cat_codigo: string;      // Primary key, unique identifier
  cat_descripcion: string; // Category name/description
  cat_estado: 'ACT' | 'INA'; // Active or Inactive status
}

Database Schema

The categories are stored in the categoria table with the following structure:
ColumnTypeDescription
cat_codigoVARCHAR(10)Primary key, category code
cat_descripcionVARCHAR(100)Category name
cat_estadoVARCHAR(3)Status: ACT (Active) or INA (Inactive)

Common Use Cases

Product Classification

Categories are primarily used to classify products and raw materials:
  • Products: Link products to categories using cat_codigo in the product table
  • Raw Materials: Link materials to categories for inventory organization
  • Reporting: Generate reports grouped by category
  • Filtering: Allow users to filter product lists by category
  • Dropdown Menus: Populate category selection dropdowns in product forms
  • Autocomplete: Use for category search and selection
  • Filtering: Enable category-based filtering in product catalogs
  • Navigation: Create category-based navigation in e-commerce interfaces

Integration Points

The Categorías API integrates with several other POS modules:
Related Modules:
  • Productos: Products are assigned categories through cat_codigo
  • Materia Prima: Raw materials can be categorized
  • Reporting: Category-based sales and inventory reports
  • E-commerce: Product catalog browsing by category

Best Practices

Performance Optimization:
  • Cache category data on the client side since it changes infrequently
  • Use categories for client-side filtering to reduce server requests
  • Preload categories on application startup for faster form rendering
State Handling:
  • Always filter by cat_estado = 'ACT' when displaying categories to users
  • Inactive categories should only be visible in admin interfaces
  • Consider caching strategies with reasonable TTL (e.g., 1 hour) since categories change rarely

Implementation Notes

Controller Implementation

The category controller is implemented in pos.categoria.controller.js:
const getAll = async (req, res) => {
  const pool = connectFromJWT(req);

  try {
    const result = await getAllQuery(pool);

    if (!result.length) {
      return res.status(404).json({ message: 'No se encontraron categorías' });
    }

    res.status(200).json(result);
  } catch (error) {
    res.status(500).json({ message: error.message });
  } finally {
    await pool.end();
  }
};

Model Implementation

The category model in categoria.model.js executes a simple query:
const getAllQuery = async (pool) => {
  const query = 'SELECT * FROM categoria ORDER BY cat_descripcion';
  const result = await pool.query(query);
  return result.rows;
};

Connection Management

Like all POS endpoints, categories use JWT-based connection pooling:
  1. JWT token is verified by verifyToken middleware
  2. Database credentials are extracted from the token payload
  3. A dedicated connection pool is created with user credentials
  4. Query is executed with proper permission scope
  5. Connection pool is closed in the finally block
This ensures proper row-level security and audit trailing at the database level.

Build docs developers (and LLMs) love