trucostars-core-module 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +423 -0
  3. package/dist/app.controller.d.ts +6 -0
  4. package/dist/app.controller.js +43 -0
  5. package/dist/app.controller.js.map +1 -0
  6. package/dist/app.module.d.ts +4 -0
  7. package/dist/app.module.js +31 -0
  8. package/dist/app.module.js.map +1 -0
  9. package/dist/app.service.d.ts +5 -0
  10. package/dist/app.service.js +28 -0
  11. package/dist/app.service.js.map +1 -0
  12. package/dist/common/common.module.d.ts +2 -0
  13. package/dist/common/common.module.js +58 -0
  14. package/dist/common/common.module.js.map +1 -0
  15. package/dist/common/config/env.validation.d.ts +2 -0
  16. package/dist/common/config/env.validation.js +93 -0
  17. package/dist/common/config/env.validation.js.map +1 -0
  18. package/dist/common/config/firebase.config.d.ts +2 -0
  19. package/dist/common/config/firebase.config.js +9 -0
  20. package/dist/common/config/firebase.config.js.map +1 -0
  21. package/dist/common/config/index.d.ts +1 -0
  22. package/dist/common/config/index.js +18 -0
  23. package/dist/common/config/index.js.map +1 -0
  24. package/dist/common/database/database.module.d.ts +2 -0
  25. package/dist/common/database/database.module.js +54 -0
  26. package/dist/common/database/database.module.js.map +1 -0
  27. package/dist/common/database/database.service.d.ts +25 -0
  28. package/dist/common/database/database.service.js +91 -0
  29. package/dist/common/database/database.service.js.map +1 -0
  30. package/dist/common/decorators/api-performance.decorator.d.ts +1 -0
  31. package/dist/common/decorators/api-performance.decorator.js +42 -0
  32. package/dist/common/decorators/api-performance.decorator.js.map +1 -0
  33. package/dist/common/decorators/index.d.ts +1 -0
  34. package/dist/common/decorators/index.js +18 -0
  35. package/dist/common/decorators/index.js.map +1 -0
  36. package/dist/common/filters/all-exceptions.filter.d.ts +5 -0
  37. package/dist/common/filters/all-exceptions.filter.js +38 -0
  38. package/dist/common/filters/all-exceptions.filter.js.map +1 -0
  39. package/dist/common/firebase/firebase.controller.d.ts +35 -0
  40. package/dist/common/firebase/firebase.controller.js +115 -0
  41. package/dist/common/firebase/firebase.controller.js.map +1 -0
  42. package/dist/common/firebase/firebase.module.d.ts +3 -0
  43. package/dist/common/firebase/firebase.module.js +83 -0
  44. package/dist/common/firebase/firebase.module.js.map +1 -0
  45. package/dist/common/firebase/firebase.service.d.ts +17 -0
  46. package/dist/common/firebase/firebase.service.js +127 -0
  47. package/dist/common/firebase/firebase.service.js.map +1 -0
  48. package/dist/common/firebase/firebase.types.d.ts +22 -0
  49. package/dist/common/firebase/firebase.types.js +3 -0
  50. package/dist/common/firebase/firebase.types.js.map +1 -0
  51. package/dist/common/interceptors/logging.interceptor.d.ts +10 -0
  52. package/dist/common/interceptors/logging.interceptor.js +108 -0
  53. package/dist/common/interceptors/logging.interceptor.js.map +1 -0
  54. package/dist/common/interceptors/performance.interceptor.d.ts +7 -0
  55. package/dist/common/interceptors/performance.interceptor.js +58 -0
  56. package/dist/common/interceptors/performance.interceptor.js.map +1 -0
  57. package/dist/common/middleware/logger.middleware.d.ts +19 -0
  58. package/dist/common/middleware/logger.middleware.js +231 -0
  59. package/dist/common/middleware/logger.middleware.js.map +1 -0
  60. package/dist/common/redis/redis.module.d.ts +2 -0
  61. package/dist/common/redis/redis.module.js +21 -0
  62. package/dist/common/redis/redis.module.js.map +1 -0
  63. package/dist/common/redis/redis.service.d.ts +11 -0
  64. package/dist/common/redis/redis.service.js +52 -0
  65. package/dist/common/redis/redis.service.js.map +1 -0
  66. package/dist/common/sqs/sqs.consumer.d.ts +20 -0
  67. package/dist/common/sqs/sqs.consumer.js +140 -0
  68. package/dist/common/sqs/sqs.consumer.js.map +1 -0
  69. package/dist/common/sqs/sqs.controller.d.ts +21 -0
  70. package/dist/common/sqs/sqs.controller.js +70 -0
  71. package/dist/common/sqs/sqs.controller.js.map +1 -0
  72. package/dist/common/sqs/sqs.example.service.d.ts +27 -0
  73. package/dist/common/sqs/sqs.example.service.js +206 -0
  74. package/dist/common/sqs/sqs.example.service.js.map +1 -0
  75. package/dist/common/sqs/sqs.module.d.ts +2 -0
  76. package/dist/common/sqs/sqs.module.js +24 -0
  77. package/dist/common/sqs/sqs.module.js.map +1 -0
  78. package/dist/common/sqs/sqs.producer.d.ts +13 -0
  79. package/dist/common/sqs/sqs.producer.js +197 -0
  80. package/dist/common/sqs/sqs.producer.js.map +1 -0
  81. package/dist/common/websocket/websocket.gateway.d.ts +9 -0
  82. package/dist/common/websocket/websocket.gateway.js +41 -0
  83. package/dist/common/websocket/websocket.gateway.js.map +1 -0
  84. package/dist/common/websocket/websocket.module.d.ts +2 -0
  85. package/dist/common/websocket/websocket.module.js +22 -0
  86. package/dist/common/websocket/websocket.module.js.map +1 -0
  87. package/dist/common/websocket/websocket.service.d.ts +25 -0
  88. package/dist/common/websocket/websocket.service.js +248 -0
  89. package/dist/common/websocket/websocket.service.js.map +1 -0
  90. package/dist/data/data.d.ts +10 -0
  91. package/dist/data/data.js +10 -0
  92. package/dist/data/data.js.map +1 -0
  93. package/dist/main.d.ts +1 -0
  94. package/dist/main.js +48 -0
  95. package/dist/main.js.map +1 -0
  96. package/dist/products/entities/product.entity.d.ts +56 -0
  97. package/dist/products/entities/product.entity.js +80 -0
  98. package/dist/products/entities/product.entity.js.map +1 -0
  99. package/dist/products/products.controller.d.ts +35 -0
  100. package/dist/products/products.controller.js +98 -0
  101. package/dist/products/products.controller.js.map +1 -0
  102. package/dist/products/products.module.d.ts +2 -0
  103. package/dist/products/products.module.js +27 -0
  104. package/dist/products/products.module.js.map +1 -0
  105. package/dist/products/products.service.d.ts +36 -0
  106. package/dist/products/products.service.example.d.ts +1 -0
  107. package/dist/products/products.service.example.js +3 -0
  108. package/dist/products/products.service.example.js.map +1 -0
  109. package/dist/products/products.service.js +74 -0
  110. package/dist/products/products.service.js.map +1 -0
  111. package/dist/tsconfig.build.tsbuildinfo +1 -0
  112. package/package.json +106 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jorge Nahuel Gerones
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,423 @@
1
+ <p align="center">
2
+ <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
3
+ </p>
4
+
5
+ # TrucoStars API
6
+
7
+ <p align="center">Una API RESTful construida con <a href="http://nestjs.com/" target="_blank">NestJS</a> y <a href="https://www.typescriptlang.org/" target="_blank">TypeScript</a> para gestionar productos, usuarios y comunicación en tiempo real.</p>
8
+
9
+ ## 📑 Índice
10
+
11
+ - [Descripción](#descripcion)
12
+ - [Estructura del Proyecto](#estructura-proyecto)
13
+ - [Stack Tecnológico](#stack-tecnologico)
14
+ - [Módulos Principales](#modulos-principales)
15
+ - [Productos Module](#productos-module)
16
+ - [Firebase Module](#firebase-module)
17
+ - [Redis Module](#redis-module)
18
+ - [WebSocket Module](#websocket-module)
19
+ - [Configuración e Instalación](#configuracion-instalacion)
20
+ - [Ejecución](#ejecucion)
21
+ - [Testing](#testing)
22
+ - [Características Principales](#caracteristicas-principales)
23
+ - [Endpoints Principales](#endpoints-principales)
24
+ - [Dependencias Importantes](#dependencias-importantes)
25
+ - [Archivos de Configuración](#archivos-configuracion)
26
+ - [Autor](#autor)
27
+ - [Licencia](#licencia)
28
+
29
+ <a id="descripcion"></a>
30
+ ## 📋 Descripción
31
+
32
+ TrucoStars API es una aplicación backend moderna construida con **NestJS**, que proporciona funcionalidades completas para:
33
+
34
+ - **Gestión de Productos**: CRUD de productos con almacenamiento en MongoDB
35
+ - **Autenticación y Autorización**: Integración con Firebase para autenticación segura
36
+ - **Caché en Tiempo Real**: Uso de Redis para optimizar el rendimiento
37
+ - **Comunicación WebSocket**: Soporte para comunicación bidireccional en tiempo real
38
+ - **Persistencia de Datos**: MongoDB como base de datos principal
39
+
40
+ <a id="estructura-proyecto"></a>
41
+ ## 🏗️ Estructura del Proyecto
42
+
43
+ ```
44
+ src/
45
+ ├── app.controller.ts # Controlador principal
46
+ ├── app.service.ts # Servicio principal
47
+ ├── app.module.ts # Módulo raíz
48
+ ├── main.ts # Punto de entrada
49
+ ├── firebase/ # Módulo de autenticación Firebase
50
+ │ ├── firebase.config.ts # Configuración de Firebase
51
+ │ ├── firebase.controller.ts # Endpoints de autenticación
52
+ │ ├── firebase.service.ts # Lógica de autenticación
53
+ │ └── firebase.module.ts # Módulo Firebase
54
+ ├── products/ # Módulo de productos
55
+ │ ├── products.controller.ts # Endpoints de productos
56
+ │ ├── products.service.ts # Lógica de negocio de productos
57
+ │ ├── products.module.ts # Módulo de productos
58
+ │ └── entities/
59
+ │ └── product.entity.ts # Esquema/entidad de producto
60
+ ├── redis/ # Módulo de caché Redis
61
+ │ ├── redis.service.ts # Servicio de Redis
62
+ │ └── redis.module.ts # Módulo Redis
63
+ └── websocket/ # Módulo de WebSocket
64
+ ├── websocket.gateway.ts # Gateway de WebSocket
65
+ ├── websocket.service.ts # Lógica de WebSocket
66
+ └── websocket.module.ts # Módulo WebSocket
67
+ ```
68
+
69
+ <a id="stack-tecnologico"></a>
70
+ ## 🛠️ Stack Tecnológico
71
+
72
+ ### Core Framework
73
+ - **NestJS v11**: Framework progresivo para aplicaciones Node.js
74
+ - **TypeScript**: Tipado seguro y desarrollo escalable
75
+
76
+ ### Bases de Datos
77
+ - **MongoDB**: Base de datos NoSQL con Mongoose ODM
78
+ - **Redis**: Sistema de caché en memoria
79
+
80
+ ### Funcionalidades
81
+ - **Firebase Admin SDK**: Autenticación y gestión de usuarios
82
+ - **Socket.io**: Comunicación WebSocket en tiempo real
83
+ - **Swagger**: Documentación API automática
84
+
85
+ ### Testing & Quality
86
+ - **Jest**: Framework de testing
87
+ - **ESLint**: Linting de código
88
+ - **Prettier**: Formateo de código
89
+
90
+ ### Dependencias Principales
91
+ ```json
92
+ "@nestjs/core": "^11.0.1"
93
+ "@nestjs/mongoose": "^11.0.4"
94
+ "@nestjs/websockets": "^11.1.11"
95
+ "@nestjs/swagger": "^11.2.4"
96
+ "firebase-admin": "^13.6.0"
97
+ "mongoose": "^9.1.3"
98
+ "ioredis": "^5.9.2"
99
+ ```
100
+
101
+ <a id="modulos-principales"></a>
102
+ ## 🚀 Módulos Principales
103
+
104
+ <a id="productos-module"></a>
105
+ ### 📦 Productos Module
106
+ Gestión completa de productos con operaciones CRUD, validaciones y caché.
107
+ - `ProductsController`: Endpoints para CRUD de productos
108
+ - `ProductsService`: Lógica de negocio
109
+ - `ProductEntity`: Esquema MongoDB
110
+
111
+ <a id="firebase-module"></a>
112
+ ### 🔐 Firebase Module
113
+ Autenticación y autorización segura mediante Firebase.
114
+ - `FirebaseService`: Gestión de tokens y autenticación
115
+ - `FirebaseController`: Endpoints de login y verificación
116
+
117
+ <a id="redis-module"></a>
118
+ ### ⚡ Redis Module
119
+ Se implementa un sistema de caché distribuido para optimizar el rendimiento de la aplicación, utilizando Redis como backend de almacenamiento, a través del [Cache Manager de NestJS](https://docs.nestjs.com/techniques/caching) y reutilizando el cliente que provee `RedisService`.
120
+
121
+ Esto permite:
122
+
123
+ - Cacheo automático de respuestas HTTP mediante [CacheInterceptor](https://docs.nestjs.com/techniques/caching#auto-caching-responses)
124
+ - Compatibilidad total con interceptores y decoradores estándar de NestJS.
125
+ - Reducción de consultas repetidas a MongoDB
126
+ - Expiración de datos configurable (TTL)
127
+
128
+ Adicionalmente, se implementa Rate Limiting mediante el paquete [`@nestjs/throttler`](https://docs.nestjs.com/security/rate-limiting), que provee un `ThrottlerGuard` que limita la cantidad de solicitudes permitidas por cliente en un período de tiempo configurable, aplicándose a todos los endpoints de la aplicación y reutilizando el mismo cliente Redis expuesto por `RedisService`.
129
+
130
+ Este enfoque desacopla la lógica de caché de la lógica de negocio,
131
+ siguiendo las mejores prácticas recomendadas por NestJS.
132
+
133
+ <a id="websocket-module"></a>
134
+ ### 🔌 WebSocket Module
135
+ Comunicación en tiempo real bidireccional.
136
+ - `WebSocketGateway`: Gestor de conexiones WebSocket
137
+ - `WebSocketService`: Lógica de mensajería
138
+
139
+ <a id="configuracion-instalacion"></a>
140
+ ## ⚙️ Configuración e Instalación
141
+
142
+ ### Requisitos Previos
143
+ - **Node.js**: v18+ recomendado
144
+ - **npm**: v9+
145
+ - **MongoDB**: Instancia local o conexión remota
146
+ - **Redis**: Instancia local o conexión remota
147
+
148
+ ### Instalación
149
+
150
+ ```bash
151
+ # Instalar dependencias
152
+ $ npm install
153
+ ```
154
+
155
+ ### Variables de Entorno
156
+ Crear un archivo `.env` en la raíz del proyecto:
157
+
158
+ ```
159
+ # MongoDB
160
+ MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/?appName=Develop
161
+
162
+ # Redis
163
+ # GENERAL
164
+ REDIS_URL=redis://[usuario]:[password]@[host]:[port]/[db]
165
+ # LOCAL
166
+ REDIS_URL=redis://localhost:6379
167
+
168
+ # Firebase
169
+ FIREBASE_PROJECT_ID=your-project-id
170
+ FIREBASE_PRIVATE_KEY=your-private-key
171
+ FIREBASE_CLIENT_EMAIL=your-client-email
172
+
173
+ # API
174
+ PORT=3000
175
+ NODE_ENV=development
176
+
177
+ # Logging Configuration
178
+ LOG_LEVEL=debug # Nivel de logging: debug | log | warn | error
179
+ ENABLE_HTTP_LOGGING=true # Logs del middleware HTTP (request/response)
180
+ ENABLE_API_LOGGING=true # Logs del interceptor API (controllers/handlers)
181
+ ```
182
+
183
+ #### Control de Logs
184
+
185
+ La aplicación incluye un sistema de logging profesional que puede controlarse mediante variables de entorno:
186
+
187
+ - **`LOG_LEVEL`**: Define el nivel de detalle de los logs
188
+ - `debug`: Todos los logs (desarrollo)
189
+ - `log`: Información general
190
+ - `warn`: Solo advertencias y errores
191
+ - `error`: Solo errores críticos
192
+
193
+ - **`ENABLE_HTTP_LOGGING`**: Controla los logs del middleware HTTP
194
+ - `true`: Muestra logs detallados de requests/responses con formato visual mejorado
195
+ - `false`: Desactiva completamente los logs HTTP
196
+
197
+ - **`ENABLE_API_LOGGING`**: Controla los logs del interceptor API
198
+ - `true`: Muestra logs de controllers, handlers y timing de ejecución
199
+ - `false`: Desactiva los logs de API
200
+
201
+ **Ejemplo para producción (logs mínimos):**
202
+ ```env
203
+ NODE_ENV=production
204
+ LOG_LEVEL=error
205
+ ENABLE_HTTP_LOGGING=false
206
+ ENABLE_API_LOGGING=false
207
+ ```
208
+
209
+ **Ejemplo para desarrollo (logs completos):**
210
+ ```env
211
+ NODE_ENV=development
212
+ LOG_LEVEL=debug
213
+ ENABLE_HTTP_LOGGING=true
214
+ ENABLE_API_LOGGING=true
215
+ ```
216
+
217
+ <a id="ejecucion"></a>
218
+ ## 🚀 Ejecución
219
+
220
+ ```bash
221
+ # Modo desarrollo (con reinicio automático)
222
+ $ npm run start:dev
223
+
224
+ # Modo desarrollo con depuración
225
+ $ npm run start:debug
226
+
227
+ # Modo producción
228
+ $ npm run start:prod
229
+
230
+ # Compilar proyecto
231
+ $ npm run build
232
+ ```
233
+
234
+ <a id="testing"></a>
235
+ ## 🧪 Testing
236
+
237
+ ### Comandos Disponibles
238
+
239
+ ```bash
240
+ # Ejecutar todas las pruebas unitarias
241
+ $ npm run test
242
+
243
+ # Ejecutar tests de módulos comunes (Database, Redis, Firebase, WebSocket)
244
+ $ npm run test:common
245
+
246
+ # Ejecutar solo tests de conexiones e inicialización
247
+ $ npm run test:connections
248
+
249
+ # Modo watch (re-ejecuta al cambiar archivos)
250
+ $ npm run test:watch
251
+
252
+ # Cobertura de pruebas
253
+ $ npm run test:cov
254
+
255
+ # Pruebas end-to-end
256
+ $ npm run test:e2e
257
+ ```
258
+
259
+ ### 📋 Tests de Conexiones e Inicialización
260
+
261
+ El proyecto incluye un conjunto completo de **unit tests** para verificar que las conexiones e inicialización de los módulos funcionen correctamente:
262
+
263
+ #### Tests Implementados
264
+
265
+ | Módulo | Archivo | Tests | Descripción |
266
+ |--------|---------|-------|-------------|
267
+ | **DatabaseService** | `database.service.spec.ts` | 10 tests | Verificación de conexión MongoDB, estados, health checks |
268
+ | **RedisService** | `redis.service.spec.ts` | 7 tests | Configuración de Redis, ciclo de vida, gestión de conexión |
269
+ | **FirebaseService** | `firebase.service.spec.ts` | 6 tests | Inicialización Firebase, notificaciones push, manejo de errores |
270
+ | **WebSocketService** | `websocket.service.spec.ts` | 9 tests | Broadcasting, gestión de conexiones, manejo de errores |
271
+ | **SqsProducer** | `sqs.producer.spec.ts` | 11 tests | Configuración AWS, inicialización cliente SQS, métodos de envío |
272
+ | **SqsConsumer** | `sqs.consumer.spec.ts` | 15 tests | Polling, procesamiento de mensajes, RxJS Subjects, lifecycle |
273
+ | **SqsModule** | `sqs.module.spec.ts` | 9 tests | Compilación módulo, providers, exports, integración |
274
+ | **CommonModule** | `common.module.spec.ts` | 8 tests | Compilación del módulo, configuración global, providers |
275
+
276
+ #### ✅ Qué Verifican los Tests
277
+
278
+ - ✅ **Inicialización correcta** de servicios y conexiones
279
+ - ✅ **Estados de conexión** (conectado, desconectado, conectando)
280
+ - ✅ **Configuración** de variables de entorno
281
+ - ✅ **Health checks** de conexiones a bases de datos y servicios externos
282
+ - ✅ **Manejo de errores** durante la inicialización
283
+ - ✅ **Inyección de dependencias** correcta en todos los módulos
284
+
285
+ #### 📊 Cobertura de Tests
286
+
287
+ ```bash
288
+ # Ejecutar solo tests de conexiones
289
+ $ npm run test:8 passed, 8 total
290
+ # Tests: 74 passed, 74
291
+ # Resultado esperado:
292
+ # Test Suites: 4 passed, 4 total
293
+ # Tests: 32 passed, 32 total
294
+ ```
295
+
296
+ #### 🔍 Ejemplo de Test: DatabaseService
297
+
298
+ ```typescript
299
+ describe('DatabaseService - Connection Initialization', () => {
300
+ it('should initialize with a connected state', () => {
301
+ expect(mockConnection.readyState).toBe(1); // 1 = conectado
302
+ });
303
+
304
+ it('should perform health check successfully', async () => {
305
+ const healthStatus = await service.checkHealth();
306
+ expect(healthStatus.status).toBe('healthy');
307
+ });
308
+ });
309
+ ```
310
+
311
+ #### 📝 Documentación Completa
312
+
313
+ Para más detalles sobre los tests y cómo implementarlos, consulta:
314
+ - **[TESTING.md](src/common/TESTING.md)** - Guía completa de testing
315
+ - Incluye ejemplos de mocks, mejores prácticas y troubleshooting
316
+
317
+ #### 🎯 Beneficios
318
+
319
+ 1. **Detección Temprana**: Identifica problemas de configuración antes del despliegue
320
+ 2. **Documentación Viva**: Los tests sirven como documentación del comportamiento esperado
321
+ 3. **Confianza en Refactoring**: Permite cambiar código con seguridad
322
+ 4. **CI/CD Ready**: Tests automatizables para pipelines de integración continua
323
+
324
+ <a id="caracteristicas-principales"></a>
325
+ ## 📝 Herramientas de Desarrollo
326
+
327
+ ```bash
328
+ # Linting y formateo
329
+ $ npm run lint # Ejecutar ESLint
330
+ $ npm run format # Formatear código con Prettier
331
+
332
+ # Gestión de puertos
333
+ $ npm run kill # Cerrar proceso en puerto 3000
334
+ $ npm run stop-force # Forzar cierre del puerto 3000
335
+ ```
336
+
337
+ ## 📚 Características Principales
338
+
339
+ ### ✅ CRUD de Productos
340
+ - Crear nuevos productos
341
+ - Listar y buscar productos
342
+ - Actualizar información de productos
343
+ - Eliminar productos
344
+ - Caché automático con Redis
345
+
346
+ ### 🔐 Autenticación con Firebase
347
+ - Registro de usuarios
348
+ - Login seguro
349
+ - Verificación de tokens JWT
350
+ - Control de acceso basado en roles
351
+
352
+ ### 💬 WebSocket en Tiempo Real
353
+ - Conexiones persistentes
354
+ - Notificaciones en tiempo real
355
+ - Mensajería bidireccional
356
+ - Manejo de desconexiones automático
357
+
358
+ ### ⚡ Optimización con Redis
359
+ - Caché de productos frecuentes
360
+ - Reducción de consultas a MongoDB
361
+ - Sincronización automática de datos
362
+ - Expiración configurable de datos
363
+
364
+ <a id="endpoints-principales"></a>
365
+ ## 🔗 Endpoints Principales
366
+
367
+ ### Productos
368
+ - `GET /products` - Listar todos los productos
369
+ - `GET /products/:id` - Obtener un producto
370
+ - `POST /products` - Crear nuevo producto
371
+ - `PATCH /products/:id` - Actualizar producto
372
+ - `DELETE /products/:id` - Eliminar producto
373
+
374
+ ### Firebase (Autenticación)
375
+ - `POST /auth/register` - Registrar usuario
376
+ - `POST /auth/login` - Iniciar sesión
377
+ - `POST /auth/verify` - Verificar token
378
+
379
+ ### WebSocket
380
+ - Evento: `message` - Enviar mensaje en tiempo real
381
+ - Evento: `connect` - Conexión establecida
382
+ - Evento: `disconnect` - Conexión cerrada
383
+
384
+ <a id="dependencias-importantes"></a>
385
+ ## 📦 Dependencias Importantes
386
+
387
+ | Paquete | Versión | Propósito |
388
+ |---------|---------|----------|
389
+ | `@nestjs/core` | ^11.0.1 | Core framework |
390
+ | `@nestjs/mongoose` | ^11.0.4 | ODM para MongoDB |
391
+ | `@nestjs/websockets` | ^11.1.11 | Soporte WebSocket |
392
+ | `@nestjs/swagger` | ^11.2.4 | Documentación API |
393
+ | `firebase-admin` | ^13.6.0 | Autenticación Firebase |
394
+ | `mongoose` | ^9.1.3 | MongoDB driver |
395
+ | `ioredis` | ^5.9.2 | Cliente Redis |
396
+
397
+ ## 🛠️ Herramientas de Desarrollo
398
+
399
+ | Herramienta | Propósito |
400
+ |------------|----------|
401
+ | **Jest** | Testing unitario y e2e |
402
+ | **ESLint** | Linting de código |
403
+ | **Prettier** | Formateo de código |
404
+ | **Swagger** | Documentación de API |
405
+ | **TypeScript** | Tipado estático |
406
+
407
+ <a id="archivos-configuracion"></a>
408
+ ## 📄 Archivos de Configuración
409
+
410
+ - **tsconfig.json** - Configuración TypeScript
411
+ - **nest-cli.json** - Configuración NestJS
412
+ - **eslint.config.mjs** - Reglas ESLint
413
+ - **package.json** - Dependencias y scripts
414
+
415
+ <a id="autor"></a>
416
+ ## 🤝 Autor
417
+
418
+ **Fractured Mesh Studios**
419
+
420
+ <a id="licencia"></a>
421
+ ## 📜 Licencia
422
+
423
+ Este proyecto está bajo licencia UNLICENSED.
@@ -0,0 +1,6 @@
1
+ import { AppService } from './app.service';
2
+ export declare class AppController {
3
+ private readonly appService;
4
+ constructor(appService: AppService);
5
+ getHello(): string;
6
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AppController = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const swagger_1 = require("@nestjs/swagger");
15
+ const app_service_1 = require("./app.service");
16
+ let AppController = class AppController {
17
+ appService;
18
+ constructor(appService) {
19
+ this.appService = appService;
20
+ }
21
+ getHello() {
22
+ return this.appService.getHello();
23
+ }
24
+ };
25
+ exports.AppController = AppController;
26
+ __decorate([
27
+ (0, common_1.Get)('/'),
28
+ (0, swagger_1.ApiOperation)({ summary: 'Welcome message' }),
29
+ (0, swagger_1.ApiResponse)({
30
+ status: 200,
31
+ description: 'Returns a welcome message',
32
+ example: 'Hello World!',
33
+ }),
34
+ __metadata("design:type", Function),
35
+ __metadata("design:paramtypes", []),
36
+ __metadata("design:returntype", String)
37
+ ], AppController.prototype, "getHello", null);
38
+ exports.AppController = AppController = __decorate([
39
+ (0, swagger_1.ApiTags)('App'),
40
+ (0, common_1.Controller)(),
41
+ __metadata("design:paramtypes", [app_service_1.AppService])
42
+ ], AppController);
43
+ //# sourceMappingURL=app.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA8D;AAC9D,6CAA+E;AAC/E,+CAA2C;AAIpC,IAAM,aAAa,GAAnB,MAAM,aAAa;IACK;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IASvD,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;IACpC,CAAC;CACF,CAAA;AAbY,sCAAa;AAUxB;IAPC,IAAA,YAAG,EAAC,GAAG,CAAC;IACR,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC5C,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,cAAc;KACxB,CAAC;;;;6CAGD;wBAZU,aAAa;IAFzB,IAAA,iBAAO,EAAC,KAAK,CAAC;IACd,IAAA,mBAAU,GAAE;qCAE8B,wBAAU;GADxC,aAAa,CAazB"}
@@ -0,0 +1,4 @@
1
+ import { MiddlewareConsumer, NestModule } from '@nestjs/common';
2
+ export declare class AppModule implements NestModule {
3
+ configure(consumer: MiddlewareConsumer): void;
4
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const app_controller_1 = require("./app.controller");
12
+ const app_service_1 = require("./app.service");
13
+ const products_module_1 = require("./products/products.module");
14
+ const common_module_1 = require("./common/common.module");
15
+ const logger_middleware_1 = require("./common/middleware/logger.middleware");
16
+ let AppModule = class AppModule {
17
+ configure(consumer) {
18
+ consumer
19
+ .apply(logger_middleware_1.LoggerMiddleware)
20
+ .forRoutes('*');
21
+ }
22
+ };
23
+ exports.AppModule = AppModule;
24
+ exports.AppModule = AppModule = __decorate([
25
+ (0, common_1.Module)({
26
+ imports: [common_module_1.CommonModule, products_module_1.ProductsModule],
27
+ controllers: [app_controller_1.AppController],
28
+ providers: [app_service_1.AppService],
29
+ })
30
+ ], AppModule);
31
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwE;AACxE,qDAAiD;AACjD,+CAA2C;AAC3C,gEAA4D;AAC5D,0DAAsD;AACtD,6EAAyE;AAOlE,IAAM,SAAS,GAAf,MAAM,SAAS;IACpB,SAAS,CAAC,QAA4B;QACpC,QAAQ;aACL,KAAK,CAAC,oCAAgB,CAAC;aACvB,SAAS,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;CACF,CAAA;AANY,8BAAS;oBAAT,SAAS;IALrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,4BAAY,EAAE,gCAAc,CAAC;QACvC,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,wBAAU,CAAC;KACxB,CAAC;GACW,SAAS,CAMrB"}
@@ -0,0 +1,5 @@
1
+ export declare class AppService {
2
+ private readonly logger;
3
+ constructor();
4
+ getHello(): string;
5
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var AppService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.AppService = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ let AppService = AppService_1 = class AppService {
16
+ logger = new common_1.Logger(AppService_1.name);
17
+ constructor() { }
18
+ getHello() {
19
+ this.logger.log('getHello endpoint called');
20
+ return 'Hello World!';
21
+ }
22
+ };
23
+ exports.AppService = AppService;
24
+ exports.AppService = AppService = AppService_1 = __decorate([
25
+ (0, common_1.Injectable)(),
26
+ __metadata("design:paramtypes", [])
27
+ ], AppService);
28
+ //# sourceMappingURL=app.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.service.js","sourceRoot":"","sources":["../src/app.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AAG7C,IAAM,UAAU,kBAAhB,MAAM,UAAU;IACJ,MAAM,GAAG,IAAI,eAAM,CAAC,YAAU,CAAC,IAAI,CAAC,CAAC;IAEtD,gBAAe,CAAC;IAEhB,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAC5C,OAAO,cAAc,CAAC;IACxB,CAAC;CACF,CAAA;AATY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;;GACA,UAAU,CAStB"}
@@ -0,0 +1,2 @@
1
+ export declare class CommonModule {
2
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CommonModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const config_1 = require("@nestjs/config");
12
+ const cache_manager_1 = require("@nestjs/cache-manager");
13
+ const throttler_1 = require("@nestjs/throttler");
14
+ const core_1 = require("@nestjs/core");
15
+ const env_validation_1 = require("./config/env.validation");
16
+ const database_module_1 = require("./database/database.module");
17
+ const redis_module_1 = require("./redis/redis.module");
18
+ const websocket_module_1 = require("./websocket/websocket.module");
19
+ const firebase_module_1 = require("./firebase/firebase.module");
20
+ const sqs_module_1 = require("./sqs/sqs.module");
21
+ let CommonModule = class CommonModule {
22
+ };
23
+ exports.CommonModule = CommonModule;
24
+ exports.CommonModule = CommonModule = __decorate([
25
+ (0, common_1.Global)(),
26
+ (0, common_1.Module)({
27
+ imports: [
28
+ config_1.ConfigModule.forRoot({
29
+ isGlobal: true,
30
+ envFilePath: '.env',
31
+ validationSchema: (0, env_validation_1.createValidationSchema)(),
32
+ validationOptions: {
33
+ allowUnknown: true,
34
+ abortEarly: true,
35
+ },
36
+ expandVariables: true,
37
+ }),
38
+ cache_manager_1.CacheModule.register({
39
+ isGlobal: true,
40
+ }),
41
+ throttler_1.ThrottlerModule.forRoot({
42
+ throttlers: [
43
+ {
44
+ limit: 100,
45
+ ttl: (0, throttler_1.seconds)(60),
46
+ },
47
+ ],
48
+ }),
49
+ database_module_1.DatabaseModule,
50
+ redis_module_1.RedisModule,
51
+ websocket_module_1.WebSocketModule,
52
+ firebase_module_1.FirebaseModule,
53
+ sqs_module_1.SqsModuleCustom,
54
+ ],
55
+ providers: [{ provide: core_1.APP_GUARD, useClass: throttler_1.ThrottlerGuard }],
56
+ })
57
+ ], CommonModule);
58
+ //# sourceMappingURL=common.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.module.js","sourceRoot":"","sources":["../../src/common/common.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,2CAA8C;AAC9C,yDAAoD;AACpD,iDAA6E;AAC7E,uCAAyC;AACzC,4DAAiE;AACjE,gEAA4D;AAC5D,uDAAmD;AACnD,mEAA+D;AAC/D,gEAA4D;AAC5D,iDAAmD;AAuC5C,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IAnCxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,qBAAY,CAAC,OAAO,CAAC;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,MAAM;gBACnB,gBAAgB,EAAE,IAAA,uCAAsB,GAAE;gBAC1C,iBAAiB,EAAE;oBACjB,YAAY,EAAE,IAAI;oBAClB,UAAU,EAAE,IAAI;iBACjB;gBACD,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,2BAAW,CAAC,QAAQ,CAAC;gBACnB,QAAQ,EAAE,IAAI;aACf,CAAC;YAEF,2BAAe,CAAC,OAAO,CAAC;gBACtB,UAAU,EAAE;oBACV;wBACE,KAAK,EAAE,GAAG;wBACV,GAAG,EAAE,IAAA,mBAAO,EAAC,EAAE,CAAC;qBACjB;iBACF;aACF,CAAC;YAEF,gCAAc;YACd,0BAAW;YACX,kCAAe;YACf,gCAAc;YACd,4BAAe;SAChB;QACD,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAS,EAAE,QAAQ,EAAE,0BAAc,EAAE,CAAC;KAC9D,CAAC;GACW,YAAY,CAAG"}
@@ -0,0 +1,2 @@
1
+ import * as Joi from 'joi';
2
+ export declare function createValidationSchema(): Joi.ObjectSchema<any>;