Sistema backend avanzado para gestión inteligente de inventario con soporte para múltiples proveedores de AI: Qwen, OpenAI y DeepSeek. Análisis inteligente, recomendaciones automáticas y optimización de costos.
git clone <repository-url>
cd comercialai-saas
npm install
# Copiar archivo de configuración
cp .env.example .env
# Editar .env con tus API keys
nano .env
En tu archivo .env, configura los proveedores que desees usar:
# ========================================
# SELECCIÓN DE PROVEEDOR (Escoge UNO)
# ========================================
AI_PROVIDER=QWEN # QWEN | OPENAI | DEEPSEEK
# ========================================
# QWEN AI (Alibaba Cloud) - Recomendado para Producción
# ========================================
DASHSCOPE_API_KEY=sk-your-qwen-key
MODEL_NAME=qwen-flash # qwen-flash | qwen-plus | qwen-max
# ========================================
# OPENAI - Máxima Calidad
# ========================================
OPENAI_API_KEY=sk-your-openai-key
OPENAI_MODEL=gpt-4o-mini # gpt-4o-mini | gpt-4 | gpt-4-turbo
# ========================================
# DEEPSEEK - Ultra Económico
# ========================================
DEEPSEEK_API_KEY=sk-your-deepseek-key
DEEPSEEK_MODEL=deepseek-chat # deepseek-chat | deepseek-coder
# ========================================
# ANTHROPIC CLAUDE - Asistente de Compras
# ========================================
# Requerido para /api/v2/ai/purchase-assistant/chat, sin importar AI_PROVIDER
ANTHROPIC_API_KEY=sk-ant-your-key
ANTHROPIC_MODEL=claude-sonnet-5 # Usar un modelo vigente; los retirados responden 404
# Probar todos los proveedores configurados
npm run test:ai
# Probar un proveedor específico
npm run test:ai:openai
npm run test:ai:qwen
npm run test:ai:deepseek
# Iniciar servidor
npm start
| Proveedor | Costo por Análisis | Velocidad | Calidad | Caso de Uso Ideal |
|---|---|---|---|---|
| 🔥 DeepSeek | $0.01-0.05 | Muy Rápida | Excelente | Desarrollo, Testing, Alto Volumen |
| 🧠 Qwen AI | $0.05-0.15 | Rápida | Alta Consistencia | Producción, Uso Regular |
| 🤖 OpenAI | $0.50-2.00 | Moderada | Máxima Precisión | Análisis Críticos, Decisiones Importantes |
npm start # Iniciar servidor
npm run dev # Modo desarrollo con recarga automática
npm run test:ai # Probar todos los proveedores AI
# Tests del Asistente de Compras (sin BD ni red: cliente de Claude simulado)
node --test test/purchase-assistant-chat.test.js
npm run test:ai:openai # Probar solo OpenAI
npm run test:ai:qwen # Probar solo Qwen
npm run test:ai:deepseek # Probar solo DeepSeek
# Usar el script de switching automático
./scripts/switch-ai-provider.sh OPENAI # Cambiar a OpenAI
./scripts/switch-ai-provider.sh QWEN # Cambiar a Qwen
./scripts/switch-ai-provider.sh DEEPSEEK # Cambiar a DeepSeek
npm run ai:validate # Validar proveedor actual
npm run ai:validate:all # Probar todos los proveedores
# Análisis paginado (recomendado para datasets grandes)
POST /api/inventory/analyze-paginated
GET /api/inventory/results/:sessionId
GET /api/inventory/status/:sessionId
DELETE /api/inventory/stop/:sessionId # 🛑 NUEVO: Detener análisis en progreso
# Exportación de resultados
POST /api/inventory/export
GET /api/inventory/exports
GET /api/inventory/export/:filename
GET /api/inventory/status # Estado del sistema
GET /api/inventory/ai/validate # Validar proveedor actual
GET /api/inventory/ai/validate?testAll=true # Probar todos
POST /api/v2/ai/purchase-assistant/chat # Chat con tool calling (roles: owner, admin, manager, analyst)
GET /api/v2/ai/purchase-assistant/history # Historial de consultas del usuario
POST /api/ai/purchase-assistant/analyze # ⚠️ Deprecado: usar /chat
// Análisis de inventario con archivo CSV
const formData = new FormData();
formData.append('inventory', csvFile);
const response = await fetch('/api/inventory/analyze-paginated', {
method: 'POST',
body: formData
});
const { sessionId } = await response.json();
// Polling para obtener resultados
const pollResults = async () => {
const results = await fetch(`/api/inventory/results/${sessionId}`);
const data = await results.json();
if (data.processing.completed) {
console.log('Análisis completado:', data.results);
} else {
setTimeout(pollResults, 2000); // Continuar polling
}
};
pollResults();
// 🛑 Detener análisis si es necesario
const stopAnalysis = async () => {
const response = await fetch(`/api/inventory/stop/${sessionId}`, {
method: 'DELETE'
});
const result = await response.json();
console.log('Análisis detenido:', result.data.final_stats);
if (result.data.results_available) {
// Obtener resultados parciales
const partialResults = await fetch(`/api/inventory/results/${sessionId}`);
console.log('Resultados parciales:', await partialResults.json());
}
};
El asistente responde preguntas del área de compras consultando los datos del tenant bajo demanda. En lugar de recibir datos precargados en el prompt, Claude decide qué herramientas llamar; el backend las ejecuta contra la BD del tenant y le devuelve los resultados hasta que el modelo tiene la respuesta (máximo 8 iteraciones por pregunta).
Web (historial del chat) → POST /api/v2/ai/purchase-assistant/chat
→ PurchaseAssistantService.chat()
↔ Claude (messages.create con tools)
↔ executeTool() → servicios de dominio / inventory_data (tenantDB)
→ { analysis, toolsUsed, metadata.usage } + registro en audit_log (control DB)
| Área | Herramientas |
|---|---|
| Inventario | buscar_producto, detalle_sku, stock_bajo, top_ventas |
| Órdenes de compra | buscar_ordenes_compra, ordenes_compra_por_sku, detalle_orden_compra, proveedores, estados_orden, resumen_ordenes_compra |
| Despachos | despachos_por_orden, despachos_por_sku |
| Ventas | ventas_sku_por_mes |
Métricas derivadas en inventario:
venta_promedio_mensual = promedio de ventas_mes_1..6dias_cobertura = inventario_en_sitio / (venta_promedio_mensual / 30)src/domains/ai/tools/ con un objeto { name, description, input_schema, handler(input, { tenantDB, user }) }.purchaseTools (src/domains/ai/tools/index.js).capList/clampLimit y devolver JSON compacto.TOOL_LABELS del componente PurchaseAssistantChat.tsx (frontend).El formato de las herramientas es compatible con MCP, por lo que el mismo registro puede exponerse más adelante como servidor MCP sin reescribir los handlers.
metadata.usage y en audit_log.# Construir imagen
docker build -t comercialai-saas .
# Ejecutar con docker-compose
docker-compose up -d
# Verificar estado
docker-compose logs -f
# En docker-compose.yml o al ejecutar
docker run -e AI_PROVIDER=QWEN \
-e DASHSCOPE_API_KEY=sk-your-key \
-e OPENAI_API_KEY=sk-your-openai-key \
-e DEEPSEEK_API_KEY=sk-your-deepseek-key \
-e ANTHROPIC_API_KEY=sk-ant-your-key \
-e ANTHROPIC_MODEL=claude-sonnet-5 \
-p 3000:3000 comercialai-saas
comercialai-saas/
├── src/
│ ├── algorithms/
│ │ ├── InventoryCalculationEngine.js # Motor V1 (Pipeline + Días Objetivo)
│ │ └── InventoryCalculationEngineV2.js # Motor V2 (Min-Max + Safety Stock) 🆕
│ ├── domains/
│ │ └── ai/
│ │ ├── services/ # PurchaseAssistantService (loop de tool calling) y controller
│ │ ├── tools/ # Herramientas del Asistente de Compras
│ │ └── providers/AIProviderFactory.js # Clientes de IA por proveedor
│ ├── controllers/
│ │ └── InventoryController.js # Controlador principal
│ ├── services/
│ │ ├── UnifiedInventoryAnalysisService.js # Servicio unificado (sin IA)
│ │ ├── ExcelProcessorService.js # Procesamiento Excel
│ │ └── ExportService.js # Exportación de datos
│ ├── routes/
│ │ └── inventory.js # Rutas API
│ ├── utils/
│ │ └── middleware.js # Middleware personalizado
│ └── index.js # Servidor principal
├── scripts/
│ ├── test-ai-providers.js # Testing de proveedores
│ └── switch-ai-provider.sh # Cambio de proveedor
├── test/
│ └── purchase-assistant-chat.test.js # Tests del Asistente de Compras (node:test)
├── .env.example # Plantilla de configuración
├── docker-compose.yml # Configuración Docker
├── Dockerfile # Imagen Docker
├── CLEANUP_SUMMARY.md # Resumen de limpieza de código
├── DEPLOYMENT.md # Guía de despliegue
├── INVENTORY_MODELS_COMPARISON.md # Comparación V1 vs V2 🆕
└── README.md # Esta documentación
El sistema soporta dos modelos de cálculo de inventario que coexisten sin conflictos:
| Modelo | Descripción | Estado | Uso Recomendado |
|---|---|---|---|
| V1 | Pipeline + Días Objetivo | ✅ Producción (Default) | Simple, probado, rápido |
| V2 | Min-Max + Safety Stock | 🆕 Nuevo (Estadístico) | Preciso, incluye compras en fabricación |
inventario_en_compras (fabricación)inventario_en_compras en pipelinePara cambiar entre modelos, edita tu archivo .env:
# Usar modelo V1 (Default - Pipeline + Días Objetivo)
USE_INVENTORY_MODEL_V2=false
# Usar modelo V2 (Nuevo - Min-Max + Safety Stock)
USE_INVENTORY_MODEL_V2=true
Lee INVENTORY_MODELS_COMPARISON.md para:
# En .env - Ajustes de rendimiento
MAX_AI_CONCURRENCY=2 # Llamadas concurrentes (reducir si hay timeouts)
OPTIMIZED_THRESHOLD=100 # Usar modo optimizado para datasets >100 items
AI_TIMEOUT_BASE_MS=180000 # Timeout base: 3 minutos
AI_TIMEOUT_PER_ITEM_MS=8000 # Timeout adicional por item: 8 segundos
CIRCUIT_BREAKER_MAX_FAILURES=3 # Max fallos antes de backoff
# Configuraciones de negocio
LEAD_TIME_DAYS=90 # Lead time de fabricantes
TARGET_COVERAGE_DAYS=40 # Cobertura objetivo de stock
MIN_STOCK_ALERT_DAYS=30 # Umbral de alerta de stock mínimo
🔥 Timeouts en API de AI
# Reducir concurrencia en .env
MAX_AI_CONCURRENCY=1
AI_TIMEOUT_BASE_MS=300000
🔑 Error de API Keys
# Verificar configuración
npm run test:ai
# Validar un proveedor específico
npm run test:ai:qwen
💾 Memoria insuficiente para datasets grandes
# Usar procesamiento paginado
POST /api/inventory/analyze-paginated
# En lugar de /api/inventory/analyze
# Logs en tiempo real
docker-compose logs -f
# Estado del sistema
curl http://localhost:3000/api/inventory/status
# Validar todos los proveedores
curl "http://localhost:3000/api/inventory/ai/validate?testAll=true"
Consulta .env.example para ver todas las variables disponibles con documentación detallada.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Para soporte técnico o consultas:
DEPLOYMENT.mdMIT License - Ver LICENSE para más detalles.
🎯 Sistema listo para producción con arquitectura multi-proveedor AI escalable y optimizada para costos.
Content type
Image
Digest
sha256:e20717029…
Size
74.6 MB
Last updated
7 days ago
docker pull ingleo44/comercialai-logistics