203 lines
6.1 KiB
Markdown
203 lines
6.1 KiB
Markdown
# Resumen de Archivos - Clean Architecture
|
|
|
|
## Archivos Modificados/Creados
|
|
|
|
### 1. **config/env.ts** ✓
|
|
- Lee y valida variables de entorno
|
|
- Centraliza PORT, DATABASE_URL, JWT_SEED, BCRYPT_ROUNDS
|
|
- Se importa en toda la app para acceder a configuración
|
|
|
|
### 2. **config/jwt.ts** ✓
|
|
- JwtAdapter para generar y validar tokens
|
|
- Métodos estáticos: `generate()` y `validate()`
|
|
- Define JwtPayload interface con id y email
|
|
- Exporta los tokens y valida automáticamente expiración
|
|
|
|
### 3. **config/bcrypt.ts** ✓
|
|
- BcryptAdapter para hashear y comparar contraseñas
|
|
- Métodos estáticos: `hash()` y `compare()`
|
|
- Usa BCRYPT_ROUNDS de env para consistencia
|
|
|
|
### 4. **domain/errors/custom.error.ts** ✓
|
|
- CustomError clase base para errores personalizados
|
|
- Métodos estáticos: badRequest(), unauthorized(), notFound(), conflict(), internalServer()
|
|
- Cada error tiene statusCode para responder correctamente
|
|
|
|
### 5. **domain/dtos/auth/register-user.dto.ts** ✓
|
|
- RegisterUserDto interfaz
|
|
- RegisterUserDtoValidator con método validate()
|
|
- Valida name (no vacío), email (formato), password (mínimo 6 caracteres)
|
|
- Normaliza email a minúsculas
|
|
|
|
### 6. **domain/dtos/auth/login-user.dto.ts** ✓
|
|
- LoginUserDto interfaz
|
|
- LoginUserDtoValidator con método validate()
|
|
- Valida email (formato) y password (no vacío)
|
|
- Normaliza email a minúsculas
|
|
|
|
### 7. **domain/dtos/index.ts** ✓
|
|
- Exporta todos los DTOs en un solo lugar
|
|
- Facilita importar: `import * from '../../dtos'`
|
|
|
|
### 8. **domain/repositories/auth.repository.ts** ✓
|
|
- AuthRepository interfaz (contrato)
|
|
- Define métodos: findByEmail(), create(), findById()
|
|
- El UseCase no sabe cómo se implementa, solo el contrato
|
|
|
|
### 9. **domain/use-cases/auth/register-user.use-case.ts** ✓
|
|
- RegisterUserUseCase ejecuta el registro
|
|
- Valida DTO → Verifica email → Hashea → Crea usuario → Genera JWT
|
|
- Retorna { user, token }
|
|
- Lanza CustomError si email existe
|
|
|
|
### 10. **domain/use-cases/auth/login-user.use-case.ts** ✓
|
|
- LoginUserUseCase ejecuta el login
|
|
- Valida DTO → Busca usuario → Compara password → Genera JWT
|
|
- Retorna { user, token }
|
|
- Lanza CustomError si credenciales son inválidas
|
|
|
|
### 11. **domain/use-cases/auth/get-me.use-case.ts** ✓
|
|
- GetMeUseCase obtiene el usuario autenticado
|
|
- Recibe userId del JWT
|
|
- Busca en repositorio y retorna datos del usuario
|
|
- Lanza CustomError si no existe
|
|
|
|
### 12. **data/postgres/index.ts** ✓
|
|
- Cliente único de Prisma
|
|
- Se inicializa una vez y se reutiliza
|
|
- Se exporta para usarlo en repositorios
|
|
|
|
### 13. **data/repositories/auth.repository.impl.ts** ✓
|
|
- AuthRepositoryImpl implementa AuthRepository
|
|
- Habla directamente con Prisma (BD)
|
|
- Métodos: findByEmail(), create(), findById()
|
|
- Select solo los campos necesarios (no contraseña en getMe)
|
|
|
|
### 14. **presentation/middlewares/auth.middleware.ts** ✓
|
|
- AuthMiddleware valida JWT en rutas protegidas
|
|
- Extrae token del header: "Authorization: Bearer TOKEN"
|
|
- Valida token → Busca usuario en BD → Agrega a req.user
|
|
- Define AuthRequest extends Request con user opcional
|
|
- Retorna 401 si token inválido o usuario no existe
|
|
|
|
### 15. **presentation/auth/controller.ts** ✓
|
|
- AuthController maneja peticiones HTTP
|
|
- Métodos: register(), login(), getMe()
|
|
- Cada método recibe, llama al UseCase, responde
|
|
- handleError() maneja CustomError y error normal
|
|
|
|
### 16. **presentation/auth/routes.ts** ✓
|
|
- Define rutas de autenticación
|
|
- POST /api/auth/register → controller.register
|
|
- POST /api/auth/login → controller.login
|
|
- GET /api/auth/me → AuthMiddleware.validate → controller.getMe
|
|
|
|
### 17. **presentation/routes.ts** ✓
|
|
- Rutas principales de la app
|
|
- Integra AuthRoutes en /api/auth
|
|
|
|
### 18. **presentation/server.ts** (Sin cambios)
|
|
- Instancia Express
|
|
- Middlewares globales (json, urlencoded)
|
|
|
|
### 19. **app.ts** ✓
|
|
- Punto de entrada
|
|
- Conecta a Prisma
|
|
- Crea Server con env.PORT
|
|
- Maneja errores globales
|
|
|
|
### 20. **.env.example** ✓
|
|
- Ejemplo de variables de entorno
|
|
- El usuario debe copiar a .env y configurar valores
|
|
|
|
### 21. **ARCHITECTURE.md** ✓
|
|
- Documentación completa de la arquitectura
|
|
- Estructura de carpetas
|
|
- Flujo de datos
|
|
- Endpoints
|
|
- Variables de entorno
|
|
|
|
---
|
|
|
|
## Resumen de Cambios
|
|
|
|
### Lógica de Negocio (Domain)
|
|
- DTOs con validaciones robustas
|
|
- UseCase implementan la lógica de registrar, login, obtener usuario
|
|
- Repository interface define el contrato
|
|
- CustomError para manejo de errores consistente
|
|
|
|
### Implementación (Data)
|
|
- AuthRepositoryImpl usa Prisma para hablar con BD
|
|
- Select solo campos necesarios (seguridad)
|
|
- Reutiliza cliente de Prisma
|
|
|
|
### HTTP (Presentation)
|
|
- AuthController coordina peticiones HTTP
|
|
- AuthMiddleware valida JWT en rutas protegidas
|
|
- AuthRoutes define endpoints
|
|
|
|
### Configuración (Config)
|
|
- JwtAdapter y BcryptAdapter centralizados
|
|
- env.ts maneja todas las variables
|
|
|
|
---
|
|
|
|
## Cómo Usar
|
|
|
|
### 1. Copiar .env.example a .env
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
### 2. Configurar variables de entorno
|
|
```bash
|
|
# .env
|
|
DATABASE_URL=postgresql://user:password@localhost:5432/optihack
|
|
JWT_SEED=mi_secreto_super_seguro
|
|
```
|
|
|
|
### 3. Instalar dependencias
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
### 4. Ejecutar migraciones de Prisma
|
|
```bash
|
|
npx prisma migrate dev
|
|
```
|
|
|
|
### 5. Iniciar el servidor
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
### 6. Probar endpoints
|
|
```bash
|
|
# Register
|
|
curl -X POST http://localhost:3000/api/auth/register \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"John","email":"john@example.com","password":"password123"}'
|
|
|
|
# Login
|
|
curl -X POST http://localhost:3000/api/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"john@example.com","password":"password123"}'
|
|
|
|
# GetMe (usa el token obtenido en login)
|
|
curl -X GET http://localhost:3000/api/auth/me \
|
|
-H "Authorization: Bearer <token>"
|
|
```
|
|
|
|
---
|
|
|
|
## Principios Aplicados
|
|
|
|
✓ **Separation of Concerns**: Cada capa tiene una responsabilidad
|
|
✓ **Dependency Inversion**: UseCase depende de interfaz, no implementación
|
|
✓ **Single Responsibility**: Cada archivo hace una cosa bien
|
|
✓ **Open/Closed**: Fácil agregar nuevos casos de uso
|
|
✓ **Liskov Substitution**: AuthRepositoryImpl puede reemplazar AuthRepository
|
|
✓ **Interface Segregation**: Interfaces pequeñas y específicas
|
|
✓ **DRY**: No repitas código, centraliza lógica
|