Files
hackathon-opti-1a67c9077937…/backend/CHANGES_SUMMARY.md
2026-05-22 19:26:38 -06:00

6.1 KiB

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

cp .env.example .env

2. Configurar variables de entorno

# .env
DATABASE_URL=postgresql://user:password@localhost:5432/optihack
JWT_SEED=mi_secreto_super_seguro

3. Instalar dependencias

npm install

4. Ejecutar migraciones de Prisma

npx prisma migrate dev

5. Iniciar el servidor

npm run dev

6. Probar endpoints

# 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