📌 CONTEXTO DEL PROYECTO: Estoy desarrollando una API en **Node.js** con **TypeScript**, **Express.js**, **Sequelize**, y **Arquitectura Hexagonal (Ports & Adapters)** bajo los principios de **DDD (Domain-Driven Design)** y **SOLID**. La API maneja **autenticación con PassportJS**, soporte para **JWT y LocalStrategy**, gestión segura de contraseñas con **bcrypt**, y transformación de respuestas con **DTOs (Data Transfer Objects)**. 📌 PRINCIPIOS Y PATRONES A APLICAR: ✅ **DDD (Domain-Driven Design):** - Los **agregados** encapsulan su estado y exponen solo lo necesario. - Cada **agregado** tiene su propio **mapper** para conversión entre persistencia y dominio. - **Repositorios** manejan **agregados** y deben desacoplarse de Sequelize. ✅ **SOLID (Principios de Diseño):** - **SRP:** Cada clase tiene una única responsabilidad. - **OCP:** El código debe ser fácil de extender sin modificarlo. - **LSP:** Los objetos derivados deben poder sustituir a sus clases base. - **ISP:** Usar interfaces específicas en lugar de dependencias directas. - **DIP:** Usar **interfaces** (`IAuthProvider`, `ITransactionManager`) en lugar de acoplarse a implementaciones concretas. 📌 GESTIÓN DE DEPENDENCIAS: ✅ **Factory Pattern (`createAuthService`)** - `AuthService` debe crearse con un **Factory** (`createAuthService()`), permitiendo cambiar su implementación sin afectar la API. - `AuthService` depende de `IAuthenticatedUserRepository`, `ITransactionManager` y `IAuthProvider`. 📌 AUTENTICACIÓN CON `PassportJS`: ✅ **Soporte para JWT y LocalStrategy** - `PassportAuthProvider` maneja **JWTStrategy** para autenticación con tokens y **LocalStrategy** para validación con email y contraseña. - Se debe usar `bcrypt` para cifrar contraseñas antes de almacenarlas. - `validateUser()` en `PassportAuthProvider` verifica credenciales con `LocalStrategy`. 📌 GESTIÓN SEGURA DE CONTRASEÑAS: ✅ **Uso de `bcrypt` para cifrado de contraseñas** - `PasswordHash.create()` valida la fuerza de la contraseña antes de cifrarla. - `bcrypt.compare()` se usa para validar la contraseña al hacer login. - Las contraseñas **nunca deben almacenarse en texto plano en la base de datos**. 📌 GESTIÓN DE ERRORES: ✅ **Uso de `ApiError` para respuestas de error estructuradas** - `ExpressController` debe devolver errores con `ApiError` (`status`, `title`, `detail`, `timestamp`). - `RegisterController` y `LoginController` deben usar `ApiError` en caso de errores (`409 Conflict`, `401 Unauthorized`, `500 Internal Server Error`). - Se deben capturar errores de **Sequelize** en `BaseRepository` (`UniqueConstraintError`, `ConnectionError`, `TimeoutError`). - **Errores de unicidad (`SequelizeUniqueConstraintError`) deben ser personalizados según el contexto usando `errorMapper` en los repositorios.** 📌 FLUJO DE LA API `/register`: 1️⃣ **Request llega a `RegisterController`**. 2️⃣ **Valida `email`, `username`, `password` como Value Objects**. 3️⃣ **Llama a `AuthService.registerUser()`**. 4️⃣ **`AuthService` usa `validateUser()` para evitar usuarios duplicados**. 5️⃣ **Si el usuario es nuevo, se cifra la contraseña con `bcrypt.hash()`**. 6️⃣ **Se almacena en la BD con `AuthenticatedUserRepository.create()`**. 7️⃣ **Se generan `accessToken` y `refreshToken` con `PassportAuthProvider`**. 8️⃣ **Se responde con los tokens y el `userId`**. 📌 FLUJO DE LA API `/login`: 1️⃣ **Request llega a `LoginController`**. 2️⃣ **Llama a `AuthService.loginUser()` con `email` y `password`**. 3️⃣ **`AuthService` busca el usuario en `AuthenticatedUserRepository.findUserByEmail()`**. 4️⃣ **Si el usuario existe, compara contraseñas con `bcrypt.compare()`**. 5️⃣ **Si la contraseña es correcta, genera `accessToken` y `refreshToken`**. 6️⃣ **Devuelve los tokens en la respuesta**. 📌 TRANSFORMACIÓN DE RESPUESTAS: ✅ **Los Controladores son responsables de la transformación de datos antes de enviarlos.** ✅ **Se usan `Presenters` (`AuthResponsePresenter`) para mapear datos del dominio a DTOs (`AuthResponseDTO`).** ✅ **Se inyectan `Presenters` en los controladores para desacoplar la lógica de transformación.** 📌 SEGURIDAD Y MEJORES PRÁCTICAS: ✅ **Usar `TransactionManager.complete()` para manejar transacciones.** ✅ **Evitar acoplamientos directos entre servicios y repositorios.** ✅ **Usar `bcrypt` con `SALT_ROUNDS=12` configurables en `.env`.** ✅ **Si ocurre un error en la BD, `rollback()` debe ejecutarse automáticamente.** ✅ **Devolver códigos HTTP adecuados (`401 Unauthorized`, `409 Conflict`, `500 Internal Server Error`).** 📌 SOLICITUDES QUE PUEDO HACERTE: - **Generar código** cumpliendo con estas reglas. - **Revisar código y detectar violaciones de SOLID o DDD**. - **Optimizar `AuthService` para mejorar la seguridad y escalabilidad**. - **Implementar `/refresh` para renovar `accessTokens`**. - **Escribir pruebas unitarias y de integración para `registerUser()` y `loginUser()`**. - **Optimizar `AuthResponsePresenter` para soportar más formatos (`XML`, `CSV`).** ⚠️ **IMPORTANTE:** - **NO generes código que acople dependencias directamente**. - **NO uses Sequelize directamente en los servicios**. - **SIEMPRE usa interfaces (`IAuthProvider`, `ITransactionManager`) en lugar de instancias concretas**.