API Structure
Rate Limiting
Strategy: Token Bucket
Rate limiting uses @nestjs/throttler with tiered limits. Production deployments should use Redis adapter for distributed rate limiting across multiple instances.
typescript
// nestjs-throttler with PostgreSQL storage
@Module({
imports: [
ThrottlerModule.forRoot({
throttlers: [
{ name: 'short', ttl: 1000, limit: 10 }, // 10 req/sec
{ name: 'medium', ttl: 60000, limit: 100 }, // 100 req/min
{ name: 'long', ttl: 3600000, limit: 1000 } // 1000 req/hour
],
storage: new ThrottlerStorageService() // DB-backed
})
]
})Per-Endpoint Limits
| Endpoint Category | Limit |
|---|---|
| Auth (login, register) | 5/min |
| Password reset | 3/hour |
| Payment webhooks | 100/sec |
| API general | 100/min |
| Admin endpoints | 200/min |
Financial Endpoint Rate Limits
| Endpoint | Limit |
|---|---|
POST /mlm/payouts/request | 1/min per user |
POST /investment/participations | 3/min per user |
POST /cart/checkout | 2/min per user |
PATCH /users/me (payout details) | 3/hour per user |
POST /admin/commissions/approve | 10/min per admin |
POST /admin/payouts/process | 5/min per admin |
Implementation
typescript
// Custom decorator for financial endpoints
export const FinancialRateLimit = () =>
applyDecorators(
Throttle({ default: { limit: 1, ttl: 60000 } }), // 1 per minute
UseGuards(ThrottlerGuard),
);
// Usage in controller
@Controller('mlm/payouts')
export class PayoutsController {
@Post('request')
@FinancialRateLimit()
async requestPayout(@CurrentUser() user: User, @Body() dto: PayoutRequestDto) {
return this.payoutService.createRequest(user.partnerId, dto);
}
}User-Specific Rate Limiting
For financial endpoints, rate limiting must be per-user, not per-IP:
typescript
@Injectable()
export class UserThrottlerGuard extends ThrottlerGuard {
protected async getTracker(req: Request): Promise<string> {
// Use user ID for authenticated requests (prevents shared IP issues)
const user = req.user as AuthenticatedUser;
if (user?.id) {
return `user:${user.id}`;
}
// Fall back to IP for unauthenticated requests
return req.ip;
}
}Rate Limit Headers
Financial endpoints include additional headers for transparency:
X-RateLimit-Limit: 1
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705329600
X-RateLimit-Policy: financialRate Limit Response
json
{
"statusCode": 429,
"message": "Too Many Requests",
"retryAfter": 45
}Endpoints Overview
/api/v1
├── /auth
│ ├── POST /register
│ ├── POST /login
│ ├── POST /refresh
│ ├── POST /logout
│ └── POST /2fa/*
│
├── /users
│ ├── GET /me
│ ├── PATCH /me
│ └── /kyc/*
│
├── /investment
│ ├── GET /strategies
│ ├── GET /strategies/:id
│ ├── POST /participations
│ ├── GET /participations
│ └── GET /portfolio
│
├── /products
│ ├── GET /
│ ├── GET /:id
│ ├── GET /categories
│ └── POST /reviews
│
├── /cart
│ ├── GET /
│ ├── POST /items
│ ├── PATCH /items/:id
│ ├── DELETE /items/:id
│ └── POST /checkout
│
├── /orders
│ ├── GET /
│ ├── GET /:id
│ └── GET /:id/tracking
│
├── /mlm
│ ├── /partner
│ │ ├── GET /me
│ │ ├── GET /network
│ │ └── GET /network/stats
│ │
│ ├── /referrals
│ │ ├── GET /links
│ │ ├── POST /links
│ │ └── GET /links/:id/stats
│ │
│ ├── /commissions
│ │ ├── GET /
│ │ ├── GET /summary
│ │ └── GET /history
│ │
│ ├── /ranks
│ │ ├── GET /current
│ │ ├── GET /progress
│ │ └── GET /history
│ │
│ └── /payouts
│ ├── GET /balance
│ ├── POST /request
│ └── GET /history
│
└── /admin (Super Admin)
├── /users/*
├── /partners/*
├── /commissions/*
├── /products/*
├── /strategies/*
└── /analytics/*