Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Oct 15, 2025. It is now read-only.

abr4xas/wayni-test

Repository files navigation

🏦 Wayni Móvil - API de Deudores BCRA

API desarrollada con NestJS para procesar y consultar datos de deudores del Banco Central de la República Argentina (BCRA) con procesamiento asíncrono con SQS y subida a S3 usando LocalStack.

🚀 Características

  • Procesamiento asíncrono con SQS para archivos grandes
  • Subida optimizada a S3 con multipart upload para archivos pesados
  • Procesamiento por lotes de 3000 registros para eficiencia optimizada
  • API REST para consulta de deudores y entidades
  • Base de datos MySQL con migraciones automáticas
  • LocalStack para simular servicios AWS (S3, SQS)
  • Docker Compose para orquestación completa de servicios
  • Procesamiento eficiente de archivos grandes (>100MB usa multipart)
  • Arquitectura modular con microservicios
  • Seguimiento de progreso en tiempo real
  • Notificaciones por email al inicio y finalización del procesamiento

📋 Requisitos

  • Docker & Docker Compose
  • pnpm (gestor de paquetes)
  • Git

🛠️ Instalación

Opción 1: Ejecución completa con Docker (Recomendado)

  1. Clonar el repositorio

    git clone <repository-url>
    cd waynijs
  2. Iniciar todos los servicios

    # Iniciar MySQL, LocalStack y la aplicación
    docker-compose up -d
  3. Inicializar LocalStack

    # Inicializar recursos S3 y SQS
    ./scripts/init-localstack.sh
  4. Verificar que todo funciona

    # Ver estado de los contenedores
    docker-compose ps
    
    # Ver logs de la aplicación
    docker-compose logs -f app
    
    # Probar la API
    curl http://localhost:3001/api

Opción 2: Desarrollo local

  1. Clonar el repositorio

    git clone <repository-url>
    cd waynijs
  2. Instalar dependencias

    pnpm install
  3. Configurar variables de entorno

    # El archivo .env ya está configurado para desarrollo local
    # Solo necesitas tener MySQL ejecutándose localmente
  4. Iniciar servicios de soporte

    # Iniciar solo MySQL y LocalStack
    docker-compose up mysql localstack -d
    
    # Inicializar LocalStack
    ./scripts/init-localstack.sh
  5. Ejecutar la aplicación

    pnpm run start:dev

🐳 Servicios Docker

El proyecto incluye los siguientes servicios en Docker Compose:

  • MySQL 8.0: Base de datos principal

    • Puerto: 3306
    • Usuario: root
    • Contraseña: root123
    • Base de datos: wayni
    • Migraciones automáticas habilitadas
  • LocalStack: Simulación de servicios AWS

    • Puerto: 4566
    • Servicios: S3, SQS
    • Bucket S3: wayni-files
    • Cola SQS: wayni-notifications
    • Estrategia de endpoint: standard
  • MailHog: Servidor SMTP para desarrollo

    • Puerto: 8025 (UI web)
    • Puerto: 1025 (SMTP)
    • Captura todos los emails enviados
  • Aplicación NestJS: API principal

    • Puerto: 3001
    • Hot reload en desarrollo
    • Procesamiento asíncrono con SQS

📊 Estructura de Base de Datos

Tabla deudores

  • id: ID único autoincremental
  • nro_identificacion: CUIT/CUIL (único)
  • situacion_maxima: Máximo valor entre registros coincidentes
  • suma_total_prestamos: Suma total de préstamos
  • created_at, updated_at: Timestamps

Tabla entidades

  • id: ID único autoincremental
  • codigo_entidad: Código de entidad financiera (único)
  • suma_total_prestamos: Suma total agrupada por entidad
  • created_at, updated_at: Timestamps

🔌 Endpoints de la API

Información General

  • GET / - Mensaje de bienvenida
  • GET /api - Información completa de la API (incluye listado de endpoints)

Importación (Asíncrona con SQS + S3) ⭐

  • POST /import/upload - Procesar archivo de deudores (asíncrono con SQS)
  • GET /import/jobs/{jobId} - Obtener estado de un trabajo específico

Deudores

  • GET /deudores/{cuit} - Buscar deudor por CUIT/CUIL
  • GET /deudores/top/{n} - Top N deudores con mayor suma de préstamos
  • GET /deudores?situacion={n} - Filtrar deudores por situación
  • GET /deudores/stats/overview - Estadísticas generales de deudores

Entidades

  • GET /entidades/{codigo} - Buscar entidad por código
  • GET /entidades - Listar todas las entidades
  • GET /entidades/stats/overview - Estadísticas generales de entidades

🗄️ Conexión a Base de Datos

Con Sequel Ace (macOS)

  • Host: localhost
  • Puerto: 3306
  • Usuario: root
  • Contraseña: root123
  • Base de datos: wayni

Con MySQL CLI

mysql -h localhost -P 3306 -u root -p
# Contraseña: root123

Con Docker

docker exec -it wayni-mysql mysql -u root -p
# Contraseña: root123

📁 Estructura del Proyecto

src/
├── config/
│   └── database.config.ts      # Configuración de base de datos
├── modules/
│   ├── aws/                    # Módulo de servicios AWS
│   │   ├── aws.module.ts
│   │   ├── s3.service.ts       # Servicio S3
│   │   └── sqs.service.ts      # Servicio SQS
│   ├── deudores/               # Módulo de deudores
│   │   ├── entities/
│   │   │   └── deudor.entity.ts
│   │   ├── deudores.controller.ts
│   │   ├── deudores.service.ts
│   │   └── deudores.module.ts
│   ├── entidades/              # Módulo de entidades
│   │   ├── entities/
│   │   │   └── entidad.entity.ts
│   │   ├── entidades.controller.ts
│   │   ├── entidades.service.ts
│   │   └── entidades.module.ts
│   ├── import/                 # Módulo de importación
│   │   ├── import.controller.ts
│   │   ├── import.service.ts
│   │   └── import.module.ts
│   ├── email/                  # Módulo de email
│   │   ├── email.service.ts    # Servicio de envío de emails
│   │   └── email.module.ts
│   ├── notification/           # Módulo de notificaciones
│   │   ├── notification.service.ts
│   │   └── notification.module.ts
│   └── queue/                  # Módulo de colas
│       ├── queue.service.ts    # Servicio de colas
│       ├── queue-worker.service.ts # Worker de procesamiento
│       └── queue.module.ts
├── shared/
│   ├── interfaces/             # Interfaces TypeScript
│   │   └── bcra-record.interface.ts
│   └── services/               # Servicios compartidos
│       └── file-parser.service.ts
└── main.ts                     # Punto de entrada

🔧 Uso

1. Procesar archivo (Asíncrono con SQS + S3) ⭐

# Iniciar procesamiento asíncrono indicando la ruta del archivo
curl -X POST http://localhost:3001/import/upload \
  -H "Content-Type: application/json" \
  -d '{"filePath":"./deudores/deudores.txt"}'

# Ver estado de un trabajo específico
curl http://localhost:3001/import/jobs/{jobId}

2. Procesar archivo específico

# Procesar archivo específico
curl -X POST http://localhost:3001/import/upload \
  -H "Content-Type: application/json" \
  -d '{"filePath": "/ruta/al/archivo.txt"}'

3. Consultar deudor por CUIT

curl http://localhost:3001/deudores/20123456789

4. Obtener top 10 deudores

curl http://localhost:3001/deudores/top/10

5. Filtrar por situación

curl http://localhost:3001/deudores?situacion=5

6. Consultar entidad

curl http://localhost:3001/entidades/001

7. Ver estadísticas

curl http://localhost:3001/deudores/stats/overview
curl http://localhost:3001/entidades/stats/overview

8. Probar integración SQS + S3

# Ejecutar pruebas e2e de integración (requiere Docker corriendo)
pnpm run test:e2e -- --testNamePattern="SQS.*S3.*Integration"

10. Validar SQS + S3 y progreso del Job (rápido)

# 1) Ver que LocalStack tenga el bucket y la cola
docker compose exec localstack awslocal s3 ls | grep wayni-files
docker compose exec localstack awslocal sqs list-queues | grep wayni-notifications

# 2) Disparar el procesamiento (usa ./deudores/deudores.txt por defecto)
JOB_ID=$(curl -s -X POST http://localhost:3001/import/upload | jq -r .jobId)
echo "Job: $JOB_ID"

# 3) Monitorear el estado y progreso
watch -n 5 "curl -s http://localhost:3001/import/jobs/$JOB_ID | jq"

# 4) Ver logs del worker y eventos SQS/S3
docker compose logs -f app | grep -E "submitJob|SQS|QueueWorker|S3|s3Url"

9. Verificar emails enviados

# Acceder a la interfaz web de MailHog
open http://localhost:8025

# O verificar via API
curl http://localhost:8025/api/v1/messages

🚀 Comandos Docker Útiles

Gestión de contenedores

# Ver estado de todos los servicios
docker-compose ps

# Iniciar todos los servicios
docker-compose up -d

# Detener todos los servicios
docker-compose down

# Reiniciar un servicio específico
docker-compose restart app

# Ver logs de un servicio
docker-compose logs -f app
docker-compose logs -f mysql
docker-compose logs -f localstack
docker-compose logs -f mailhog

Gestión de datos

# Conectar a MySQL
docker exec -it wayni-mysql mysql -u root -p

# Hacer backup de la base de datos
docker exec wayni-mysql mysqldump -u root -proot123 wayni > backup.sql

# Restaurar backup
docker exec -i wayni-mysql mysql -u root -proot123 wayni < backup.sql

# Limpiar volúmenes (¡CUIDADO! Borra todos los datos)
docker-compose down -v

Desarrollo

# Reconstruir la aplicación
docker-compose up --build -d

# Ejecutar comandos en el contenedor de la app
docker exec -it waynijs-app-1 sh

# Ver logs en tiempo real
docker-compose logs -f --tail=100 app

📈 Reglas de Negocio

Procesamiento de Deudores

  1. Agrupación por CUIT/CUIL: Los registros se agrupan por número de identificación
  2. Situación Máxima: Se toma el valor máximo del campo 6 entre registros coincidentes
  3. Suma Total: Se suman todos los préstamos (campo 7) del mismo deudor

Procesamiento de Entidades

  1. Agrupación por Código: Se agrupa por código de entidad (campo 1)
  2. Suma Total: Se suman todos los préstamos agrupados por entidad

🔄 Flujo de Procesamiento

Procesamiento Asíncrono con SQS + S3 ⭐

El sistema utiliza un flujo asíncrono completo que incluye:

  1. Envío a SQS: El archivo se envía a la cola SQS para procesamiento asíncrono
  2. Email de inicio: Se envía notificación por email al iniciar el procesamiento
  3. Subida a S3: El archivo se sube a S3 con multipart upload para archivos grandes
  4. Procesamiento por lotes: QueueWorker procesa el archivo en lotes de 3000 registros via SQS
  5. Monitoreo: Seguimiento del progreso en tiempo real
  6. Email de finalización: Se envía notificación por email al completar el procesamiento

Variables de entorno clave:

AWS_ENDPOINT_URL=http://localstack:4566
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
S3_BUCKET_NAME=wayni-files
SQS_QUEUE_URL=http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/wayni-notifications
SMTP_HOST=mailhog
SMTP_PORT=1025

Procesamiento Síncrono

  1. Carga del archivo: Se lee el archivo TXT del BCRA desde /data/
  2. Parsing: Se procesa línea por línea usando streams para eficiencia
  3. Transformación: Se agrupan y transforman los datos según las reglas de negocio
  4. Almacenamiento: Se guardan en MySQL con TypeORM
  5. Backup S3: Se almacena el archivo original en LocalStack S3
  6. Notificación: Se envía notificación de finalización a SQS

🏗️ Arquitectura

graph TD
  A[Archivo TXT] --> B[NestJS API]
  B --> C[MySQL DB]
  B --> D[S3 - LocalStack]
  B --> E[SQS - LocalStack]

  E --> F[Queue Worker]
  F --> C
  F --> D

  B --> G[MailHog UI]
  F --> H[SMTP MailHog]

  classDef svc fill:#eef,stroke:#88a,stroke-width:1px;
  class B,C,D,E,F,G,H svc;
Loading

⚡ Características de Rendimiento

Procesamiento por Lotes

  • Archivo: Procesa en lotes de 3000 registros (optimizado)
  • Base de datos: Guarda en lotes de 3000 registros
  • Memoria: Uso eficiente con streams
  • Concurrencia: Permite procesamiento de múltiples archivos

Procesamiento Asíncrono

  • SQS: Cola de mensajes para trabajos
  • Worker: Procesamiento en background
  • Progreso: Seguimiento en tiempo real
  • Escalabilidad: Fácil escalado horizontal

🧪 Testing

# Ejecutar tests unitarios
pnpm run test

# Ejecutar tests con cobertura
pnpm run test:cov

# Ejecutar tests e2e
pnpm run test:e2e

📝 Logs

La aplicación genera logs estructurados que incluyen:

  • Progreso del procesamiento de archivos (cada 10,000 líneas)
  • Estadísticas de importación por lotes
  • Notificaciones de finalización vía SQS
  • Errores y advertencias detallados
  • Estado de trabajos asíncronos

🚨 Consideraciones

  • Archivos grandes: El sistema está optimizado para procesar archivos >200MB
  • Memoria: Usa streams y procesamiento por lotes para eficiencia
  • Concurrencia: Maneja múltiples solicitudes simultáneas
  • Validación: Valida formato de CUIT/CUIL y códigos de entidad
  • Docker: Requiere al menos 4GB de RAM disponible para todos los servicios
  • Puertos: Asegúrate de que los puertos 3001, 3306, 4566, 8025 y 1025 estén disponibles
  • SQS: Requiere inicialización de LocalStack para funcionar correctamente
  • Email: Los emails se capturan en MailHog para desarrollo (puerto 8025)
  • Rendimiento: Lotes de 3000 registros optimizados para procesamiento rápido

🔧 Desarrollo

Comandos de desarrollo

# Modo desarrollo con hot reload
pnpm run start:dev

# Compilar para producción
pnpm run build

# Ejecutar en producción
pnpm run start:prod

# Linting
pnpm run lint

Comandos Docker para desarrollo

# Iniciar solo servicios de soporte
docker-compose up mysql localstack -d

# Ejecutar la app localmente
pnpm run start:dev

# Reconstruir y reiniciar todo
docker-compose down && docker-compose up --build -d

🆘 Solución de Problemas

Puerto en uso

# Ver qué proceso usa el puerto 3001
lsof -ti:3001

# Matar el proceso
kill -9 $(lsof -ti:3001)

Problemas de conexión a MySQL

# Verificar que MySQL esté ejecutándose
docker-compose ps mysql

# Ver logs de MySQL
docker-compose logs mysql

# Reiniciar MySQL
docker-compose restart mysql

Problemas con LocalStack

# Verificar estado de LocalStack
curl http://localhost:4566/_localstack/health

# Reiniciar LocalStack
docker-compose restart localstack

# Inicializar recursos nuevamente
./scripts/init-localstack-curl-sqs.sh

Problemas con SQS

# Verificar que la cola existe
curl -X POST "http://localhost:4566/" \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AWSSimpleQueueService.ListQueues" \
  -d '{}'

# Crear la cola manualmente si es necesario
curl -X POST "http://localhost:4566/" \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AWSSimpleQueueService.CreateQueue" \
  -d '{"QueueName": "wayni-notifications"}'

Limpiar todo y empezar de nuevo

# Detener y eliminar contenedores y volúmenes
docker-compose down -v

# Eliminar imágenes
docker-compose down --rmi all

# Iniciar desde cero
docker-compose up --build -d

📊 Monitoreo

Estado de Trabajos

# Ver todos los trabajos
curl http://localhost:3001/import/jobs

# Ver estado de un trabajo específico
curl http://localhost:3001/import/jobs/{jobId}

Logs en Tiempo Real

# Ver logs de la aplicación
docker-compose logs -f app

# Ver logs de un servicio específico
docker-compose logs -f mysql
docker-compose logs -f localstack
docker-compose logs -f mailhog

Verificar Emails

# Acceder a la interfaz web de MailHog
open http://localhost:8025

# Ver todos los emails enviados
curl -s http://localhost:8025/api/v1/messages | jq '.[0].Content.Headers.Subject[0]'

# Contar emails enviados
curl -s http://localhost:8025/api/v1/messages | jq 'length'

📄 Licencia

Este proyecto es parte de una prueba técnica para Wayni Móvil.


Desarrollado con ❤️ usando NestJS, TypeORM, MySQL, SQS y LocalStack

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published