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.

259 lines
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
```bash
npm install
```
### Ejecutar tests
```bash
# Todos los tests
npm test
# Con coverage
npm test -- --coverage
# Watch mode
npm test -- --watch
```
### Ejemplo básico
```typescript
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
- [**Modelo de datos**](./docs/MODEL.md) - Estructura completa del modelo
- [**Sistema de tipos**](./docs/TYPES.md) - Tipos TypeScript y branded IDs
- [**Reglas de validación**](./docs/RULES.md) - Cómo crear y usar reglas
- [**i18n**](./docs/I18N.md) - Sistema de internacionalización
- [**Motor de renderizado**](./docs/RENDERING.md) - Generación de imágenes
- [**Guía de creación**](./docs/CATALOG_GUIDE.md) - Cómo crear un catálogo completo
## 🏗️ 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
```bash
# Ver coverage
npm test -- --coverage
# Coverage actual: ~95%
```
## 🌍 i18n
Sistema de internacionalización con 9 idiomas soportados:
```typescript
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:
```typescript
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`](./tests/fixtures/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/`:
```typescript
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](LICENSE)
## 🙏 Agradecimientos
- [JsonLogic](http://jsonlogic.com/) - Motor de reglas declarativas
- [Vitest](https://vitest.dev/) - Framework de testing
---
**Versión**: 1.0.0
**Última actualización**: Febrero 2026

Powered by TurnKey Linux.