You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.7 KiB

CPQ Engine - Motor de Configuración de Producto

Sistema TypeScript type-safe para configuración de productos complejos (Configure-Price-Quote) con soporte i18n, reglas de validación declarativas y renderizado visual condicional.

🎯 Características principales

  • Type-safe: Sistema de tipos robusto con IDs con prefijos branded
  • i18n nativo: Soporte multiidioma en todos los elementos del modelo
  • Reglas declarativas: Motor de validación basado en JsonLogic
  • Visual rendering: Generación dinámica de imágenes basada en selecciones
  • Arquitectura modular: Separación clara entre modelo, motor y utilidades
  • Testing completo: >180 tests unitarios con Vitest

📦 Estructura del proyecto

src/
├── types/              # Definiciones de tipos TypeScript
│   ├── core/          # Tipos base (Value, ID, JsonLogic)
│   ├── model/         # Tipos del modelo (Attribute, Section, Rule)
│   └── i18n/          # Sistema de internacionalización
├── engine/            # Motores de evaluación
│   ├── json-logic/   # Evaluador JsonLogic
│   └── rule-engine.ts # Motor de reglas de validación
├── utils/             # Utilidades
│   ├── ids/          # Sistema de IDs con prefijos
│   └── i18n/         # Funciones de traducción
├── messages/          # Sistema de mensajes centralizados
│   ├── errors.ts     # Mensajes de error
│   ├── warnings.ts   # Mensajes de advertencia
│   └── logger.ts     # Logger estructurado
└── constants/         # Constantes globales
    └── defaults.ts    # Valores por defecto

🚀 Inicio rápido

Instalación

npm install

Ejecutar tests

# Todos los tests
npm test

# Con coverage
npm test -- --coverage

# Watch mode
npm test -- --watch

Ejemplo básico

import { CATALOGO_VIVIENDAS } from './fixtures/housing-catalog';
import { RuleEngine } from './engine/rule-engine';

// Obtener un objeto configurable
const apartamento = CATALOGO_VIVIENDAS.objects['ob:apartamento'];

// Crear estado de selección
const seleccion = {
  'at:calidad': 'op:calidad_premium',
  'at:suelo': 'op:suelo_parquet',
  'at:sanitario': 'op:sanit_negro'
};

// Validar con reglas
const engine = new RuleEngine();
const reglas = Object.values(CATALOGO_VIVIENDAS.rules);

const esValido = engine.isValid(reglas, seleccion);
const violaciones = engine.getViolations(reglas, seleccion);

console.log('¿Configuración válida?', esValido);
console.log('Violaciones:', violaciones);

📚 Documentación

🏗️ Arquitectura

Flujo de datos

┌─────────────────┐
│  Catalog JSON   │
│  (Definición)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐     ┌──────────────┐
│  Type System    │────▶│  Validation  │
│  (Compile-time) │     │  (Runtime)   │
└────────┬────────┘     └──────┬───────┘
         │                     │
         ▼                     ▼
┌─────────────────┐     ┌──────────────┐
│ User Selection  │────▶│ Rule Engine  │
│   (State)       │     │  (JsonLogic) │
└────────┬────────┘     └──────┬───────┘
         │                     │
         ▼                     ▼
┌─────────────────┐     ┌──────────────┐
│ Visual Render   │     │   Pricing    │
│  (Images)       │     │ (Calculate)  │
└─────────────────┘     └──────────────┘

Capas

  1. Types Layer - Definiciones de tipos, contratos
  2. Model Layer - Estructura del catálogo (Objects, Sections, Attributes)
  3. Engine Layer - Lógica de negocio (Rules, JsonLogic, Rendering)
  4. Utils Layer - Funciones auxiliares (IDs, i18n, logging)

🧪 Testing

El proyecto tiene >180 tests organizados en:

  • Unit tests - Utilidades individuales (IDs, i18n, JsonLogic)
  • Integration tests - Motor de reglas completo
  • Fixture tests - Catálogo de viviendas real
# Ver coverage
npm test -- --coverage

# Coverage actual: ~95%

🌍 i18n

Sistema de internacionalización con 9 idiomas soportados:

const mensaje: I18nString = {
  es: 'Hola mundo',
  en: 'Hello world',
  de: 'Hallo Welt',
  fr: 'Bonjour le monde',
  it: 'Ciao mondo',
  pt: 'Olá mundo',
  ca: 'Hola món',
  eu: 'Kaixo mundua',
  gl: 'Ola mundo'
};

// Uso
const texto = translate(mensaje, 'es'); // → "Hola mundo"

Strings simples también son válidos:

const simple: I18nString = 'OK'; // Válido en todos los idiomas

🎨 Ejemplo de modelo real

El proyecto incluye un catálogo completo de viviendas como fixture:

  • 2 modelos: Apartamento (4 secciones) y Dúplex (5 secciones)
  • 24 opciones de acabados (suelos, paredes, sanitarios, etc.)
  • 6 reglas de validación con prioridades
  • Generación de imágenes con templates
  • Pricing dinámico

Ver: housing-catalog.fixture.ts

🔧 Tecnologías

  • TypeScript 5.x - Lenguaje principal
  • Vitest - Framework de testing
  • JsonLogic - Motor de reglas declarativas
  • Branded Types - IDs type-safe

📝 Convenciones

IDs con prefijos

Todos los IDs usan prefijos branded:

Tipo Prefijo Ejemplo
Attribute at: at:calidad
Section sc: sc:salon
Option op: op:premium
Object ob: ob:apartamento
Rule rl: rl:negro_premium
View vw: vw:front
Hotspot hs: hs:punto1

Mensajes

Todos los mensajes de error/warning/info están centralizados en src/messages/:

import { ERRORS, logger } from '@/messages';

// ❌ NO hacer
throw new Error('Invalid ID format');

// ✅ Hacer
const errorMsg = ERRORS.INVALID_ID_FORMAT(id);
logger.error(MESSAGE_CATEGORIES.ID, errorMsg, { id });
throw new Error(JSON.stringify(errorMsg));

Naming

  • Types: PascalCase (AttributeDisplay, ValidationRule)
  • Interfaces: PascalCase con prefijo I opcional
  • Functions: camelCase (extractIdPart, isValid)
  • Constants: UPPER_SNAKE_CASE (DEFAULTS, MESSAGE_CATEGORIES)
  • Files: kebab-case (rule-engine.ts, id-parser.ts)

🤝 Contribuir

  1. Fork el proyecto
  2. Crea una rama (git checkout -b feature/amazing)
  3. Commit cambios (git commit -m 'Add amazing feature')
  4. Push a la rama (git push origin feature/amazing)
  5. Abre un Pull Request

Requisitos para PR

  • ✅ Todos los tests pasan
  • ✅ Coverage >90%
  • ✅ Sin errores de TypeScript
  • ✅ Mensajes centralizados (no inline)
  • ✅ Documentación actualizada

📄 Licencia

MIT License - ver LICENSE

🙏 Agradecimientos


Versión: 1.0.0
Última actualización: Febrero 2026

Powered by TurnKey Linux.