Skip to Content
Plan de pruebas3. Catálogo de productos

3. Catálogo de productos

Cubre categories, taxes, products (incluye inventories en su creación), modifier_groups y custom_fields.

Historial de ejecución

CicloFechaEjecutado porCasos ejecutadosResultado
1———Pendiente

Categorías

CP CAT-01: Crear categoría solo con nombre (único campo obligatorio)

  • Resultado esperado: se crea con el resto de campos (description, color, icon, parent_id) vacíos/nulos, sin error.
  • Resultado obtenido: Pendiente.

CP CAT-02: Crear subcategoría con parent_id de una categoría inexistente

  • Resultado esperado a verificar: ¿el backend valida que parent_id exista, o se guarda igual un ID huérfano? Si se guarda igual, es un hallazgo — el frontend podría mostrar un árbol de categorías roto.
  • Resultado obtenido: Pendiente.

CP CAT-03: Crear categoría sin nombre

  • Resultado esperado: error de validación claro en el formulario.
  • Resultado obtenido: Pendiente.

CP CAT-04: Jerarquía circular (A es padre de B, luego B es padre de A)

  • Resultado esperado a verificar: ¿el backend lo previene? Si no, el árbol de categorías quedaría en un ciclo infinito al renderizarse — anotar si el frontend se cuelga o simplemente no lo muestra.
  • Resultado obtenido: Pendiente.

Impuestos

CP TAX-01: Crear impuesto tipo percentage con tasa 19 (IVA Colombia)

  • Resultado esperado: se crea correctamente; queda disponible al elegir impuesto en productos.
  • Resultado obtenido: Pendiente.

CP TAX-02: Crear impuesto tipo fixed

  • Resultado esperado: se crea con un valor fijo en vez de porcentaje; confirmar que el cálculo en ventas lo trata distinto a uno de tipo percentage (no debería multiplicar por el subtotal).
  • Resultado obtenido: Pendiente.

CP TAX-03: Tasa negativa

  • Pasos: crear impuesto con rate: -5.
  • Resultado esperado: debe rechazarse (binding:"min=0").
  • Resultado obtenido: Pendiente.

CP TAX-04: Tipo inválido (ej. "porcentaje" en español en vez de "percentage")

  • Resultado esperado: error 400 claro (oneof=percentage fixed), no un 500 ni un impuesto mal guardado.
  • Resultado obtenido: Pendiente.

CP TAX-05: Marcar dos impuestos como is_default a la vez

  • Resultado esperado a verificar: ¿el backend desmarca automáticamente el anterior, o quedan dos impuestos “por defecto” compitiendo? Si el frontend asume que solo hay uno, puede mostrar comportamiento inconsistente al elegir impuesto por defecto en productos nuevos.
  • Resultado obtenido: Pendiente.

Productos — los 4 tipos

CP PROD-01: Crear producto tipo product (plato/mercancía física) completo

  • Pasos: nombre, SKU, precio, costo, impuesto, categoría, stock mínimo, imagen, precio/stock por tienda.
  • Resultado esperado: se crea con su registro de inventories por cada tienda donde se definió precio/stock.
  • Resultado obtenido: Pendiente.

CP PROD-02: Crear producto tipo service

  • Pasos: mismo formulario, tipo “Servicio”, con duration_minutes (ej. 30).
  • Resultado esperado a verificar: ¿un producto tipo service genera también un registro de inventario (no debería, un servicio no tiene stock)? Si el formulario sigue pidiendo “stock mínimo” para un servicio, es un problema de usabilidad — el campo no aplica.
  • Resultado obtenido: Pendiente.

CP PROD-03: Crear producto tipo combo con combo_items

  • Pasos: crear un combo que incluya 2 productos ya existentes vía combo_items: [{product_id, quantity}].
  • Resultado esperado: al vender el combo, ¿descuenta inventario de los productos incluidos, o solo del combo en sí? Verificar en el módulo de ventas (caso VTA) después de crear este producto.
  • Resultado obtenido: Pendiente.

CP PROD-04: Crear producto tipo combo referenciando un product_id inexistente dentro de combo_items

  • Resultado esperado a verificar: ¿se valida la existencia de cada ítem del combo, o se guarda un combo roto que fallará solo al intentar venderlo?
  • Resultado obtenido: Pendiente.

CP PROD-05: Crear producto tipo ingredient con recipe_items (receta)

  • Objetivo: un producto final (ej. “Hamburguesa”) consume ingredientes vía recipe_items: [{ingredient_id, quantity, unit}].
  • Resultado esperado: al vender el producto final, debe descontarse inventario del ingrediente, no solo del producto final.
  • Resultado obtenido: Pendiente.

CP PROD-06: Producto sin tipo (campo vacío)

  • Resultado esperado: error 400 (binding:"required,oneof=...").
  • Resultado obtenido: Pendiente.

CP PROD-07: Tipo inválido (ej. "producto" en español)

  • Resultado esperado: error 400 claro, no 500.
  • Resultado obtenido: Pendiente.

CP PROD-08: Precio negativo

  • Resultado esperado a verificar: el DTO no tiene binding:"min=0" en Price — probar si el backend lo acepta tal cual. Si lo acepta, es un hallazgo real: un producto con precio negativo podría generar ventas con totales negativos.
  • Resultado obtenido: Pendiente.

CP PROD-09: SKU duplicado entre dos productos de la misma empresa

  • Resultado esperado a verificar: ¿hay restricción de unicidad de SKU por empresa? Si no la hay, buscar por SKU (GET /products/sku/:id) sería ambiguo — confirmar qué devuelve en ese caso.
  • Resultado obtenido: Pendiente.

CP PROD-10: Categoría inexistente en category_ids

  • Resultado esperado a verificar: similar a CAT-02, confirmar si se valida la existencia de las categorías referenciadas.
  • Resultado obtenido: Pendiente.

CP PROD-11: Subir una imagen de producto con un archivo que no es imagen (ej. un .pdf renombrado a .png)

  • Resultado esperado: el backend/frontend debe rechazar por tipo de contenido real, no solo por extensión del nombre de archivo.
  • Resultado obtenido: Pendiente.

CP PROD-12: Subir una imagen de producto muy pesada (ej. 20MB)

  • Resultado esperado a verificar: ¿hay límite de tamaño? Si no, confirmar qué pasa (timeout, error de servidor, o se sube igual y degrada el rendimiento del listado de productos).
  • Resultado obtenido: Pendiente.

CP PROD-13: Desactivar un producto (is_active=false) que ya tiene ventas asociadas

  • Resultado esperado: debe desaparecer del POS para nuevas ventas, pero las ventas históricas que lo incluyen no deben romperse ni perder el nombre del producto (los sale_items guardan product_name propio, independiente del producto actual — confirmar que efectivamente funciona así).
  • Resultado obtenido: Pendiente.

CP PROD-14: Ocultar producto del menú pero mantenerlo en el POS (show_in_menu=false, show_in_pos=true)

  • Resultado esperado: no debe aparecer en la carta online pública, pero sí en el POS interno.
  • Resultado obtenido: Pendiente.

Grupos de modificadores

CP MOD-01: Grupo obligatorio con mínimo 1 y máximo 1 (ej. “Tamaño”: pequeño/mediano/grande)

  • Pasos: crear grupo con min_selections=1, max_selections=1, agregar 3 opciones.
  • Resultado esperado: en el POS, al agregar el producto, debe exigir elegir exactamente una opción antes de poder agregarlo al carrito.
  • Resultado obtenido: Pendiente.

CP MOD-02: Grupo opcional con múltiples selecciones (ej. “Extras”: 0 a 3)

  • Pasos: min_selections=0, max_selections=3.
  • Resultado esperado: el POS debe permitir no elegir ninguno, o hasta 3, y bloquear un cuarto.
  • Resultado obtenido: Pendiente.

CP MOD-03: min_selections mayor que max_selections (ej. min=3, max=1)

  • Resultado esperado a verificar: configuración contradictoria — ¿el backend la rechaza, o queda guardada y el POS simplemente no deja agregar nunca el producto (loop de validación imposible)?
  • Resultado obtenido: Pendiente.

CP MOD-04: Opción de modificador con price_adjustment negativo (ej. “sin queso”: -$1.000)

  • Resultado esperado: debe restar correctamente del total de la línea, sin dejarlo en negativo si el precio base es menor al ajuste.
  • Resultado obtenido: Pendiente.

Campos personalizados

CP CF-01: Crear campo personalizado obligatorio para el modelo “producto” (ej. “Proveedor sugerido”)

  • Pasos: model: "product", type (verificar tipos soportados: texto/número/selección), required: true.
  • Resultado esperado: al crear un producto nuevo, el formulario debe exigir ese campo; productos ya existentes creados antes de este campo personalizado no deberían bloquear el sistema (verificar que no rompan al editarlos).
  • Resultado obtenido: Pendiente.

CP CF-02: Campo personalizado con model que no corresponde a ningún módulo real (ej. "xyz")

  • Resultado esperado a verificar: ¿se valida contra una lista fija de modelos soportados, o acepta cualquier string sin que nunca se use en ningún formulario (campo “fantasma”)?
  • Resultado obtenido: Pendiente.

Notas de usabilidad y sugerencias

Se completa durante la ejecución.

© 2026 ClickStock