Arquitectura Backend — CETB
Stack Tecnológico
| Componente | Tecnología |
|---|---|
| Lenguaje | TypeScript |
| Framework | NestJS v11 |
| Runtime | AWS Lambda (Node.js) |
| Base de datos | MongoDB (Mongoose) |
| Cola de mensajes | Amazon SQS |
| API Gateway | AWS API Gateway (REST) |
| Autenticación | Amazon Cognito (User Pool como Authorizer) |
| Adaptador serverless | @vendia/serverless-express |
Flujo de una petición
Cliente (App/Web)
│
▼
┌──────────────────────┐
│ AWS API Gateway │
│ (REST API) │
│ │
│ Authorizer: │
│ Cognito User Pool │
│ (valida JWT token) │
└──────────┬───────────┘
│ evento proxy
▼
┌──────────────────────┐
│ AWS Lambda │
│ (handler) │
│ │
│ - Extrae claims de │
│ Cognito │
│ - Bootstrap NestJS │
│ (cached) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ NestJS App │
│ (Express adapter) │
│ │
│ ValidationPipe │
│ (whitelist, │
│ transform) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Controller │
│ (Infraestructura) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Use Case │
│ (Aplicación) │
└──────────┬───────────┘
│
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ MongoDB │ │ SQS │
│(Mongoose│ │ (email/ │
│ repos) │ │ sms) │
└─────────┘ └─────────┘
Arquitectura DDD (Domain-Driven Design)
El proyecto sigue una estructura de capas por módulo:
src/
└── <modulo>/
├── domain/ ← Capa de Dominio
│ ├── entities/ ← Entidades de negocio (POJOs puros)
│ └── repositories/ ← Interfaces de repositorios (contratos)
│
├── application/ ← Capa de Aplicación
│ ├── use-cases/ ← Casos de uso (orquestación de lógica)
│ └── services/ ← Servicios de aplicación (SQS, etc.)
│
├── infraestructure/ ← Capa de Infraestructura
│ ├── http/ ← Controllers (entry points HTTP)
│ ├── dto/ ← Data Transfer Objects (request/response)
│ ├── moongose/models/ ← Schemas de Mongoose (persistencia)
│ └── repositories/ ← Implementaciones concretas de repos
│
└── <modulo>.module.ts ← Módulo NestJS (wiring de dependencias)
Principios aplicados
- Inversión de dependencias: El dominio define interfaces (
ITransactionRepository,ITenantRepository). La infraestructura las implementa. Se inyectan via tokens de NestJS. - Entidades puras: Las entidades del dominio no dependen de frameworks (Mongoose, NestJS). Son clases TypeScript planas.
- Casos de uso: Contienen la lógica de orquestación. Reciben DTOs, consultan repositorios, ejecutan acciones (enviar email/sms).
- DTOs con validación: Se usan
class-validatoryclass-transformeren la capa de infraestructura para validar input antes de llegar al use case.
Autenticación y Autorización
- El cliente envía el JWT token (emitido por Cognito) en el header
Authorization. - API Gateway valida el token contra el Cognito User Pool configurado como authorizer.
- Si es válido, API Gateway inyecta los claims del usuario en
event.requestContext.authorizer.claims. - El Lambda handler extrae el
usernamede los claims y lo pasa como headerx-user-usernamea la app NestJS. - Las peticiones que no pasen validación de Cognito reciben un
401 Unauthorizeddirectamente desde API Gateway.
Servicios externos
| Servicio | Uso | Cola SQS |
|---|---|---|
| Envío de comprobantes con template HTML | cetb-ts-send-email |
|
| SMS | Notificación de transacciones | cetb-ts-send-messages |
Los mensajes se publican a SQS y un consumidor separado se encarga del envío real (desacoplamiento).
Deployment
- Build:
nest build(compila TypeScript a JavaScript) - Entry point Lambda:
dist/lambda.handler - Cold start optimizado: La instancia de NestJS se cachea entre invocaciones (
cachedServer) - CORS: Configurado en el response del Lambda handler (headers
Access-Control-Allow-*)