Sistema de Gestión de Productos | Documentación Técnica

Arquitectura de bases de datos para catálogo de productos con variantes, atributos y gestión de imágenes

📅 Versión: 1.0.0 | Última actualización: Febrero 2026 🎯 Audiencia: Usuarios finales y desarrolladores
EN

📋 Introducción

Este documento describe la arquitectura completa del sistema de gestión de productos, diseñado para soportar desde productos simples hasta aquellos con múltiples variantes (talla, color, sabor, etc.).

🎯 Objetivo: Proporcionar una guía clara tanto para usuarios finales (que capturan datos) como para desarrolladores (que implementan y mantienen el sistema).

📦 Productos Simples

Servicios, productos sin variantes, artículos únicos.

1 tabla Fácil

🔄 Productos con Variantes

Ropa (talla/color), alimentos (sabor), electrónica (modelo).

5+ tablas Complejo

🖼️ Gestión de Imágenes

Imágenes generales y específicas por variante.

2 tablas Dual

📊 Estructura de Tablas

Tabla Tipo Depende de Descripción
business_entitiesBase-Tenants / Negocios (asumida existente)
product_categoriesBasebusiness_entitiesCategorías de productos
prdcts_cat_attributesBase-Catálogo global de atributos (Color, Talla, etc.)
prdcts_cat_attribute_valuesBaseprdcts_cat_attributesValores posibles de atributos (Rojo, S, Fresa)
productsMaestrobusiness_entities, product_categoriesProductos maestros (plantilla)
product_imagesImagenproductsImágenes generales del producto
product_attributesConfigproducts, prdcts_cat_attributesAtributos asignados a un producto
product_variantsVarianteproducts, chzr_measure_unitsSKUs específicos con precio/stock propio
product_variant_imagesImagenproduct_variantsImágenes específicas por variante
service_productsParalelo-Catálogo simple de servicios
⚠️ Nota: Las tablas en negrita son las que requieren orden estricto de inserción. Las tablas base deben existir antes de insertar datos.

🔄 Mapa de Flujo de Datos

┌─────────────────┐
│ business_entities│
│    (Tenant)     │
└────────┬────────┘
         │
         ▼
┌─────────────────┐    ┌─────────────────────────┐
│product_categories│    │prdcts_cat_attributes   │
│                  │    │(Catálogo de Atributos) │
└────────┬────────┘    └───────────┬─────────────┘
         │                          │
         ▼                          ▼
┌─────────────────┐    ┌─────────────────────────┐
│    products     │◄───┤prdcts_cat_attribute_    │
│ (Producto Maestro)   │values (Valores de Atrib.)│
└────────┬────────┘    └─────────────────────────┘
         │                          ▲
         │                          │
         ▼              ┌───────────┴─────────────┐
┌─────────────────┐     │product_attributes       │
│ product_images  │     │(Asignación Prod-Atrib)  │
│ (Img Generales) │     └─────────────────────────┘
└────────┬────────┘
         │
         ▼
┌─────────────────┐    ┌─────────────────────────┐
│product_variants │◄───┤ (Combinaciones de       │
│   (SKUs)        │    │  valores de atributos)  │
└────────┬────────┘    └─────────────────────────┘
         │
         ▼
┌─────────────────┐    ┌─────────────────────────┐
│product_variant_ │    │ service_products        │
│images (Img Esp.)│    │ (Catálogo de Servicios) │
└─────────────────┘    └─────────────────────────┘

➜ FLUJO PRINCIPAL (productos físicos/variantes)
➜ FLUJO ALTERNO (servicios, simplificado)
                    

Diagrama de dependencias entre tablas. Las flechas indican "depende de".

📌 Orden de Captura de Datos

Para mantener la integridad referencial, sigue este orden estricto:

1

Tablas Base (Independientes)

prdcts_cat_attributes - Crear atributos globales (Color, Talla, Sabor)

prdcts_cat_attribute_values - Crear valores (Rojo, S, Fresa)

✓ No dependen de otras tablas

2

Producto Maestro

products - Insertar el producto plantilla

ⓘ Depende de: business_entities, product_categories (asumidas existentes)

3

Imágenes Generales (Opcional)

product_images - Insertar imágenes del producto maestro

ⓘ Depende de: products

4

Asignación de Atributos

product_attributes - Vincular atributos al producto

ⓘ Depende de: products, prdcts_cat_attributes

5

Creación de Variantes

product_variants - Crear SKUs específicos (combinaciones)

ⓘ Depende de: products, chzr_measure_units

6

Imágenes Específicas

product_variant_images - Insertar imágenes por variante

ⓘ Depende de: product_variants

7

Servicios (Paralelo)

service_products - En cualquier momento

✓ Totalmente independiente

🎯 Casos de Uso Principales

📱 Producto Simple

Ejemplo: Servicio de consultoría, libro, curso online

  • Solo usa products
  • Opcional: product_images
  • No necesita variantes ni atributos

👕 Producto con Variantes

Ejemplo: Playera (Color + Talla)

  • Usa TODO el flujo completo
  • Atributos: Color, Talla
  • Variantes: Rojo/S, Rojo/M, Azul/S...
  • Imágenes específicas por color

🍬 Producto Alimenticio

Ejemplo: Gomitas (Sabor)

  • Atributo: Sabor
  • Variantes: Fresa, Chocolate
  • Precio puede variar por sabor
  • Stock independiente por sabor

🖼️ Gestión de Imágenes Dual

Ejemplo: Catálogo de ropa

  • product_images: Modelo, empaque, tallas
  • product_variant_images: Color específico
  • Ambas se complementan

💾 Ejemplos SQL Completos

📌 Ejemplo 1: Producto Simple (Servicio)

-- 1. Crear el producto maestro INSERT INTO products (id_code, entity_id, category_id, brand_id, sku, name, description, material, status, tax_code, iva, unit_type, price, cost, ump, ums, is_active, points, xtra_points) VALUES ('SRV-CONS-001', 1, 1, 0, 'CONS-IT-HORA', 'Consultoría IT por hora', 'Soporte técnico especializado on-site', 'N/A', 1, '01010101', 16, 'Hora', 850.00, 300.00, 'H', 'H', 1, 0, 0); SET @product_id = LAST_INSERT_ID(); -- 2. Agregar imagen representativa INSERT INTO product_images (product_id, image_url, image_order, is_primary, alt_text) VALUES (@product_id, 'https://ejemplo.com/img/consultoria-it.jpg', 0, 1, 'Consultoría IT - Soporte técnico');

📌 Ejemplo 2: Producto con Variantes (Playera)

-- 1. Asegurar que existen atributos globales INSERT INTO prdcts_cat_attributes (attribute_name, attribute_type, is_variant, display_order) VALUES ('Color', 'color', 1, 1), ('Talla', 'lista', 1, 2); SET @attr_color_id = 1; -- Ajustar según IDs reales SET @attr_talla_id = 2; -- 2. Insertar valores de atributos INSERT INTO prdcts_cat_attribute_values (attribute_id, value_text, value_extra, display_order) VALUES (@attr_color_id, 'Rojo', '#FF0000', 1), (@attr_color_id, 'Azul', '#0000FF', 2), (@attr_talla_id, 'S', NULL, 1), (@attr_talla_id, 'M', NULL, 2), (@attr_talla_id, 'L', NULL, 3); -- 3. Crear producto maestro INSERT INTO products (id_code, entity_id, category_id, brand_id, sku, name, description, material, status, tax_code, iva, unit_type, price, cost, ump, ums, is_active, points, xtra_points) VALUES ('PRD-PLAY-001', 1, 1, 0, 'PLAY-BASIC', 'Playera Básica Premium', 'Playera de algodón 100%', 'Algodón', 1, '01010102', 16, 'Pieza', 199.99, 80.00, 'PZA', 'PZA', 1, 0, 0); SET @product_id = LAST_INSERT_ID(); -- 4. Imágenes generales INSERT INTO product_images (product_id, image_url, is_primary) VALUES (@product_id, 'https://ejemplo.com/playera-modelo.jpg', 1), (@product_id, 'https://ejemplo.com/playera-tallas.jpg', 0); -- 5. Asignar atributos al producto INSERT INTO product_attributes (product_id, attribute_id, is_required) VALUES (@product_id, @attr_color_id, 1), (@product_id, @attr_talla_id, 1); -- 6. Crear variantes (combinaciones) -- Variante: Rojo + S INSERT INTO product_variants (product_id, sku, variant_code, presentation, measure_unit_id, quantity, price, cost, stock, min_stock, max_stock, weight, barcode, is_active) VALUES (@product_id, 'PLAY-ROJO-S', 'ROJO-S', 'Playera Roja Talla S', 1, 1.000, 199.99, 80.00, 50, 5, 100, 200.00, '750123456001', 1); SET @variant1_id = LAST_INSERT_ID(); -- Variante: Azul + M INSERT INTO product_variants (product_id, sku, variant_code, presentation, measure_unit_id, quantity, price, cost, stock, min_stock, max_stock, weight, barcode, is_active) VALUES (@product_id, 'PLAY-AZUL-M', 'AZUL-M', 'Playera Azul Talla M', 1, 1.000, 199.99, 80.00, 30, 5, 100, 220.00, '750123456002', 1); SET @variant2_id = LAST_INSERT_ID(); -- 7. Imágenes específicas por variante INSERT INTO product_variant_images (variant_id, image_url, is_primary, alt_text) VALUES (@variant1_id, 'https://ejemplo.com/playera-roja-s.jpg', 1, 'Playera Roja Talla S - Frontal'), (@variant2_id, 'https://ejemplo.com/playera-azul-m.jpg', 1, 'Playera Azul Talla M - Frontal');

📌 Ejemplo 3: Producto Alimenticio (Gomitas)

-- 1. Asegurar atributo Sabor INSERT INTO prdcts_cat_attributes (attribute_name, attribute_type, is_variant, display_order) VALUES ('Sabor', 'lista', 1, 1); SET @attr_sabor_id = 3; -- Ajustar INSERT INTO prdcts_cat_attribute_values (attribute_id, value_text, display_order) VALUES (@attr_sabor_id, 'Fresa', 1), (@attr_sabor_id, 'Chocolate', 2), (@attr_sabor_id, 'Vainilla', 3); -- 2. Producto maestro INSERT INTO products (id_code, entity_id, sku, name, description, material, price, cost, ...) VALUES ('ALI-GOM-001', 1, 'GOMITAS-FRUT', 'Gomitas de Frutas', 'Bolsa 100g', 'Azúcar', 25.50, 12.00, ...); SET @product_id = LAST_INSERT_ID(); -- 3. Asignar atributo INSERT INTO product_attributes (product_id, attribute_id, is_required) VALUES (@product_id, @attr_sabor_id, 1); -- 4. Variantes por sabor INSERT INTO product_variants (product_id, sku, presentation, price, cost, stock, ...) VALUES (@product_id, 'GOM-FRESA', 'Gomitas Sabor Fresa 100g', 25.50, 12.00, 200, ...), (@product_id, 'GOM-CHOCO', 'Gomitas Sabor Chocolate 100g', 27.50, 14.00, 150, ...);

📌 Transacción Completa (Todo en Uno)

START TRANSACTION; -- 1. Producto maestro INSERT INTO products (id_code, entity_id, sku, name, price, ...) VALUES ('TEST-001', 1, 'TEST-SKU', 'Producto Test', 100.00, ...); SET @product_id = LAST_INSERT_ID(); -- 2. Imagen general INSERT INTO product_images (product_id, image_url, is_primary) VALUES (@product_id, 'img.jpg', 1); -- 3. Atributos del producto INSERT INTO product_attributes (product_id, attribute_id, is_required) VALUES (@product_id, 1, 1); -- 4. Variantes INSERT INTO product_variants (product_id, sku, price, stock) VALUES (@product_id, 'VAR-1', 100.00, 10); SET @var1_id = LAST_INSERT_ID(); INSERT INTO product_variants (product_id, sku, price, stock) VALUES (@product_id, 'VAR-2', 110.00, 5); SET @var2_id = LAST_INSERT_ID(); -- 5. Imágenes de variantes INSERT INTO product_variant_images (variant_id, image_url, is_primary) VALUES (@var1_id, 'var1.jpg', 1), (@var2_id, 'var2.jpg', 1); COMMIT;

⚠️ Consideraciones Importantes

🔴 Orden de Borrado (Inverso al de inserción):
1. DELETE FROM product_variant_images WHERE variant_id IN (SELECT id FROM product_variants WHERE product_id = X);
2. DELETE FROM product_variants WHERE product_id = X;
3. DELETE FROM product_attributes WHERE product_id = X;
4. DELETE FROM product_images WHERE product_id = X;
5. DELETE FROM products WHERE id = X;
6. (Opcional) Limpiar atributos no usados
🟢 ON DELETE CASCADE: Algunas tablas tienen CASCADE configurado. Por ejemplo, si borras un producto maestro, se borrarán automáticamente sus variantes e imágenes. ¡Ten cuidado!
📌 Recomendaciones:
  • Siempre usa transacciones para inserciones complejas
  • Captura los IDs con LAST_INSERT_ID() para usarlos en tablas hijas
  • Para productos sin variantes, ignora todo el sistema de variantes
  • Las imágenes generales (product_images) y específicas (product_variant_images) pueden coexistir
  • service_products es independiente, úsalo para catálogos rápidos de servicios

🔍 Preguntas Frecuentes

¿Puedo tener imágenes en product_images y product_variant_images para el mismo producto?

Sí, es totalmente válido y recomendado. Las generales muestran el producto en contexto, las específicas muestran la variante exacta.

¿Qué pasa si un producto no tiene variantes?

Simplemente no uses las tablas de atributos ni variantes. El producto vive en products y sus imágenes en product_images.

¿Cómo sé qué atributos son variantes?

El campo is_variant en prdcts_cat_attributes indica si el atributo genera variantes (1) o es solo descriptivo (0).

¿Puedo cambiar un producto simple a variantes después?

Sí, pero requerirá migración de datos. Es más fácil diseñarlo desde el inicio con la estructura completa.

↑