Uecko_ERP/docs/prompt-auth.md

84 lines
5.4 KiB
Markdown
Raw Normal View History

2025-06-17 16:18:25 +00:00
📌 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**.