workspace-v1/shared/libs/rate-limiting/README.md
rckrdmrd 66161b1566 feat: Workspace-v1 complete migration with NEXUS v3.4
Sistema NEXUS v3.4 migrado con:

Estructura principal:
- core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles)
- core/catalog: Catalogo de funcionalidades reutilizables
- shared/knowledge-base: Base de conocimiento compartida
- devtools/scripts: Herramientas de desarrollo
- control-plane/registries: Control de servicios y CI/CD
- orchestration/: Configuracion de orquestacion de agentes

Proyectos incluidos (11):
- gamilit (submodule -> GitHub)
- trading-platform (OrbiquanTIA)
- erp-suite con 5 verticales:
  - erp-core, construccion, vidrio-templado
  - mecanicas-diesel, retail, clinicas
- betting-analytics
- inmobiliaria-analytics
- platform_marketing_content
- pos-micro, erp-basico

Configuracion:
- .gitignore completo para Node.js/Python/Docker
- gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git)
- Sistema de puertos estandarizado (3005-3199)

Generated with NEXUS v3.4 Migration System
EPIC-010: Configuracion Git y Repositorios
2026-01-04 03:37:42 -06:00

355 lines
6.5 KiB
Markdown

# Limitación de Tasa (Rate Limiting)
**Versión:** 1.0.0
**Origen:** projects/gamilit
**Estado:** Producción
**Última actualización:** 2025-12-08
---
## Descripción
Sistema de limitación de tasa para proteger APIs contra abuso:
- Rate limiting por IP/usuario
- Configuración por endpoint
- Headers HTTP estándar
- Respuestas 429 con Retry-After
---
## Características
| Característica | Descripción |
|----------------|-------------|
| Por IP | Limita requests por dirección IP |
| Por Usuario | Limita requests por usuario autenticado |
| Por Endpoint | Configuración individual por ruta |
| Global | Límite base para toda la aplicación |
| Headers Estándar | X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After |
---
## Stack Tecnológico
```yaml
backend:
framework: NestJS
library: "@nestjs/throttler"
storage: "Memory (default) | Redis (producción)"
```
---
## Dependencias NPM
```json
{
"@nestjs/throttler": "^5.x"
}
```
Para producción con Redis:
```json
{
"@nestjs/throttler-storage-redis": "^0.x",
"redis": "^4.x"
}
```
---
## Configuración Básica
### En módulo principal
```typescript
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';
@Module({
imports: [
ThrottlerModule.forRoot([{
ttl: 60000, // 60 segundos
limit: 100, // 100 requests por TTL
}]),
],
providers: [
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
],
})
export class AppModule {}
```
### Configuración por ambiente
```typescript
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ([{
ttl: config.get('THROTTLE_TTL', 60000),
limit: config.get('THROTTLE_LIMIT', 100),
}]),
})
```
---
## Uso por Endpoint
### Sobrescribir límites
```typescript
import { Throttle, SkipThrottle } from '@nestjs/throttler';
@Controller('auth')
export class AuthController {
// Más estricto: 5 intentos por minuto
@Throttle({ default: { limit: 5, ttl: 60000 } })
@Post('login')
login() {}
// Omitir rate limiting
@SkipThrottle()
@Get('public')
publicEndpoint() {}
}
```
### En controlador completo
```typescript
@Controller('api')
@Throttle({ default: { limit: 50, ttl: 60000 } })
export class ApiController {
// Todos los endpoints heredan el límite
}
```
---
## Múltiples Límites
```typescript
ThrottlerModule.forRoot([
{
name: 'short',
ttl: 1000, // 1 segundo
limit: 3, // 3 requests por segundo
},
{
name: 'medium',
ttl: 10000, // 10 segundos
limit: 20, // 20 requests por 10 segundos
},
{
name: 'long',
ttl: 60000, // 1 minuto
limit: 100, // 100 requests por minuto
},
])
```
Usar en endpoint:
```typescript
@Throttle({
short: { limit: 1, ttl: 1000 },
long: { limit: 10, ttl: 60000 },
})
@Post('expensive-operation')
expensiveOperation() {}
```
---
## Rate Limiting por Usuario
### Custom ThrottlerGuard
```typescript
import { Injectable, ExecutionContext } from '@nestjs/common';
import { ThrottlerGuard } from '@nestjs/throttler';
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
protected async getTracker(req: Record<string, any>): Promise<string> {
// Si hay usuario autenticado, usar su ID
if (req.user?.id) {
return req.user.id;
}
// Fallback a IP
return req.ip;
}
}
```
Registrar:
```typescript
providers: [
{
provide: APP_GUARD,
useClass: CustomThrottlerGuard,
},
],
```
---
## Almacenamiento Redis (Producción)
```typescript
import { ThrottlerStorageRedisService } from '@nestjs/throttler-storage-redis';
import Redis from 'ioredis';
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
throttlers: [{
ttl: config.get('THROTTLE_TTL', 60000),
limit: config.get('THROTTLE_LIMIT', 100),
}],
storage: new ThrottlerStorageRedisService(new Redis({
host: config.get('REDIS_HOST', 'localhost'),
port: config.get('REDIS_PORT', 6379),
})),
}),
})
```
---
## Headers de Respuesta
El módulo agrega automáticamente:
```
X-RateLimit-Limit: 100 # Límite máximo
X-RateLimit-Remaining: 95 # Requests restantes
X-RateLimit-Reset: 1234567890 # Timestamp de reset
```
En respuesta 429:
```
Retry-After: 60 # Segundos hasta poder reintentar
```
---
## Excepciones Personalizadas
```typescript
import { ThrottlerException } from '@nestjs/throttler';
// En el guard personalizado
protected throwThrottlingException(): void {
throw new ThrottlerException(
'Demasiadas solicitudes. Por favor, espere un momento.',
);
}
```
---
## Variables de Entorno
```env
# Configuración básica
THROTTLE_TTL=60000 # Ventana de tiempo en ms
THROTTLE_LIMIT=100 # Requests por ventana
# Redis (producción)
REDIS_HOST=localhost
REDIS_PORT=6379
```
---
## Casos de Uso Comunes
### 1. Login (anti brute-force)
```typescript
@Throttle({ default: { limit: 5, ttl: 300000 } }) // 5 por 5 minutos
@Post('login')
login() {}
```
### 2. Registro (anti spam)
```typescript
@Throttle({ default: { limit: 3, ttl: 3600000 } }) // 3 por hora
@Post('register')
register() {}
```
### 3. API pública
```typescript
@Throttle({ default: { limit: 1000, ttl: 3600000 } }) // 1000 por hora
@Get('public-data')
getData() {}
```
### 4. Endpoints costosos
```typescript
@Throttle({ default: { limit: 10, ttl: 60000 } }) // 10 por minuto
@Post('generate-report')
generateReport() {}
```
---
## Métricas y Logging
```typescript
@Injectable()
export class ThrottlerLoggerGuard extends ThrottlerGuard {
protected async handleRequest(
context: ExecutionContext,
limit: number,
ttl: number,
): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const tracker = await this.getTracker(req);
const result = await super.handleRequest(context, limit, ttl);
if (!result) {
this.logger.warn(`Rate limit exceeded for: ${tracker}`);
}
return result;
}
}
```
---
## Adaptaciones Necesarias
1. **Límites**: Ajustar según tráfico esperado
2. **Storage**: Memory para desarrollo, Redis para producción
3. **Tracker**: IP vs Usuario según necesidad
4. **Mensajes**: Personalizar respuestas 429
---
## Referencias
- [NestJS Throttler](https://docs.nestjs.com/security/rate-limiting)
- [RFC 6585](https://tools.ietf.org/html/rfc6585#section-4) (429 Too Many Requests)
---
**Mantenido por:** Sistema NEXUS
**Proyecto origen:** Gamilit Platform