📌 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**.  
