Este proyecto implementa un servicio REST API en Node.js + Express.js + TypeScript siguiendo los principios de Arquitectura Limpia (Clean Architecture). El servicio actúa como intermediario para consumir una API externa de reprocesos, manejando autenticación JWT y exponiendo endpoints para consultar órdenes de producción.
- ✅ Arquitectura Limpia: Separación clara de responsabilidades en capas (Domain, Application, Infrastructure, Presentation)
- ✅ Autenticación JWT: Login automático y gestión de tokens
- ✅ Filtros de consulta: Soporte completo para filtros en órdenes de producción
- ✅ Manejo robusto de errores: Tratamiento adecuado de errores en todas las capas
- ✅ Pruebas unitarias: Cobertura completa con Jest
- ✅ Escalabilidad: Diseño preparado para integración futura con PostgreSQL
- ✅ TypeScript: Tipado fuerte y moderno
El proyecto sigue la Arquitectura Limpia con las siguientes capas:
src/
├── domain/ # Reglas de negocio (entidades, repositorios, errores)
├── application/ # Casos de uso y DTOs
├── infrastructure/ # Adaptadores externos (HTTP, base de datos)
└── presentation/ # Controladores, rutas y middleware (Express.js)
- Entities:
OrderProduction,Token- Modelos de datos del negocio - Repositories: Interfaces para acceso a datos (
TokenRepository,OrderProductionRepository) - Errors: Jerarquía de errores del dominio (
DomainError,AuthenticationError, etc.)
- Use Cases: Lógica de aplicación (
LoginUseCase,GetOrderProductionsUseCase, etc.) - DTOs: Objetos de transferencia de datos para requests/responses
- HTTP: Cliente para consumir la API externa (
ReprocessingApiClient) - Repositories: Implementaciones concretas de repositorios
- Config: Configuración de la aplicación
- Controllers: Manejo de requests HTTP
- Routes: Definición de rutas Express.js
- Middleware: Middleware para manejo de errores
- Configuración Inicial: Las credenciales se configuran en variables de entorno (
USER_API_ODOO,PASS_API_ODOO) - Login Automático: El servicio realiza login automáticamente usando las credenciales configuradas
- Renovación Transparente: Los tokens se renuevan automáticamente antes de expirar (5 minutos de buffer)
- Acceso Directo: Los endpoints de datos están disponibles sin necesidad de login manual
- Autenticación Automática: Cada consulta verifica y renueva el token si es necesario
- Filtros: Soporte completo para filtrar órdenes por material, orden, cliente, límite y offset
- ✅ Sin intervención manual: No hay que gestionar tokens manualmente
- ✅ Siempre autenticado: El servicio mantiene la sesión activa automáticamente
- ✅ Transparente para el cliente: Los usuarios finales no ven la lógica de autenticación
- ✅ Renovación automática: Los tokens expirados se renuevan sin interrupciones
GET /health
Verifica el estado del servicio.
Respuesta de Éxito (200):
{
"status": "OK",
"timestamp": "2025-10-17T21:44:42.173Z"
}Nota: El endpoint /api/auth/login ha sido ocultado para los usuarios finales. La autenticación ahora ocurre de forma transparente usando las credenciales configuradas en las variables de entorno.
Proceso Interno:
- El servicio usa automáticamente
USER_API_ODOOyPASS_API_ODOOpara autenticarse - Los tokens se gestionan internamente sin exposición al usuario
- La renovación ocurre automáticamente antes de la expiración
- Los usuarios finales solo interactúan con los endpoints de datos
Obtiene una lista de órdenes de producción con filtros opcionales.
Parámetros de Consulta (Query Parameters):
material_code(opcional): Código del material (string, mínimo 3 caracteres)order(opcional): Nombre de la orden (string, mínimo 3 caracteres)customer_id(opcional): ID del cliente (integer > 0)limit(opcional): Número máximo de resultados (integer > 0, por defecto: 10)offset(opcional): Desplazamiento para paginación (integer >= 0, por defecto: 0)
Nota: No se requieren headers de autorización. La autenticación es manejada automáticamente por el servicio.
GET /api/orders/production?material_code=ABC&limit=5&offset=0
Respuesta de Éxito (200):
{
"success": true,
"data": [
{
"id": 1,
"name": "Orden de Producción 001",
"center": ["Centro A"],
"customer": ["Cliente X"],
"dateCreateOrder": "2025-01-15",
"logisticsDate": "2025-01-20",
"materialCode": "ABC123",
"materialId": 456,
"materialName": "Material Ejemplo",
"order": "ORD001",
"priority": ["Alta"],
"quantityOrdered": 100.0,
"quantityPending": "50.0",
"uom": "kg",
"state": "En Progreso",
"components": [
{
"id": 1,
"demandQty": 50.0,
"locationOriginName": "Almacén Principal",
"locationOriginId": 10,
"materialCode": "ABC123",
"materialName": "Material Ejemplo",
"quantityToConsume": 50.0,
"uom": "kg"
}
]
}
],
"message": "Órdenes de producción obtenidas exitosamente"
}Obtiene una orden de producción específica por su ID.
Parámetros de Ruta:
id(requerido): ID de la orden de producción (integer > 0)
Nota: No se requieren headers de autorización. La autenticación es manejada automáticamente por el servicio.
GET /api/order/production/123
Respuesta de Éxito (200):
{
"success": true,
"data": {
"id": 123,
"name": "Orden de Producción 123",
"center": ["Centro B"],
"customer": ["Cliente Y"],
"dateCreateOrder": "2025-02-10",
"logisticsDate": "2025-02-15",
"materialCode": "XYZ789",
"materialId": 789,
"materialName": "Otro Material",
"order": "ORD123",
"priority": ["Media"],
"quantityOrdered": 200.0,
"quantityPending": "100.0",
"uom": "unidades",
"state": "Pendiente",
"components": [
{
"id": 2,
"demandQty": 100.0,
"locationOriginName": "Almacén Secundario",
"locationOriginId": 20,
"materialCode": "XYZ789",
"materialName": "Otro Material",
"quantityToConsume": 100.0,
"uom": "unidades"
}
]
},
"message": "Orden de producción obtenida exitosamente"
}Respuesta de Error (404):
{
"success": false,
"error": {
"code": "NOT_FOUND_ERROR",
"message": "Orden de producción con ID 123 no encontrada"
}
}- 400 Bad Request: Datos de entrada inválidos
- 401 Unauthorized: Token faltante, inválido o expirado
- 404 Not Found: Recurso no encontrado
- 422 Unprocessable Entity: Validación fallida
- 500 Internal Server Error: Error interno del servidor
- 502 Bad Gateway: Error en la API externa
- Node.js >= 18.0.0
- npm >= 8.0.0
cd reprocessing-service
npm installCrear un archivo .env en la raíz del proyecto:
PORT=7002
EXTERNAL_API_BASE_URL=https://prizmaservices-odoo-iluma-guate-nutreo-22109401.dev.odoo.com/api/v1/reprocessing
USER_API_ODOO=reprocesos@premexcorp.com
PASS_API_ODOO=RPr45698-*Nota: El servicio ahora carga automáticamente las variables de entorno desde el archivo .env usando dotenv. Las credenciales USER_API_ODOO y PASS_API_ODOO se usan para autenticación automática transparente.
npm run devnpm run build
npm startSe incluye un archivo reprocessing-service.http con ejemplos completos de todas las solicitudes HTTP para probar el servicio usando la extensión REST Client de VS Code.
Para usar el archivo de pruebas:
- Instala la extensión "REST Client" en VS Code
- Abre el archivo
reprocessing-service.http - Ejecuta las solicitudes en orden (comienza con el login)
- Reemplaza
{{token}}con el token obtenido del login
Archivo incluye:
- ✅ Health check
- ✅ Login con credenciales
- ✅ Consultas con diferentes filtros
- ✅ Consultas por ID
- ✅ Pruebas de errores (401, 404, etc.)
- ✅ Instrucciones detalladas de uso
# Ejecutar todas las pruebas
npm test
# Ejecutar pruebas con cobertura
npm run test:coverage
# Ejecutar pruebas en modo watch
npm run test:watchEl proyecto incluye pruebas unitarias para:
- Repositorios (
InMemoryTokenRepository) - Casos de uso (
LoginUseCase) - Controladores (
AuthController)
Las pruebas están ubicadas en __tests__/unit/ y usan Jest como framework de testing.
La configuración se encuentra en src/infrastructure/config/Config.ts:
export const config: AppConfig = {
port: parseInt(process.env.PORT || '3000', 10),
externalApi: {
baseUrl: process.env.EXTERNAL_API_BASE_URL || 'http://localhost:8000/api/v1/reprocessing',
loginEndpoint: '/authenticate/login',
ordersEndpoint: '/orders/production',
orderByIdEndpoint: '/order/production',
},
};El diseño actual usa repositorios in-memory, pero está preparado para PostgreSQL:
- Crear nueva implementación
PostgreSQLTokenRepository - Instalar dependencias:
npm install pg typeorm - Configurar conexión a base de datos
- Reemplazar
InMemoryTokenRepositoryporPostgreSQLTokenRepositoryen la inyección de dependencias
- Cache: Implementar Redis para cache de tokens y respuestas
- Rate Limiting: Proteger contra abuso de la API
- Logging: Sistema de logs estructurado (Winston, Pino)
- Health Checks: Endpoints avanzados de monitoreo
- Docker: Containerización completa
- API Gateway: Integración con Kong o similar
- Fork el proyecto
- Crear rama para feature (
git checkout -b feature/nueva-funcionalidad) - Commit cambios (
git commit -am 'Agregar nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Crear Pull Request
Este proyecto está bajo la Licencia ISC.
Para soporte técnico o preguntas, por favor crear un issue en el repositorio.