export interface RateLimitRule { windowMs: number; limit: number; } export const RATE_LIMIT_RULES = { host: [ { windowMs: 60_000, limit: 1_200 }, { windowMs: 300_000, limit: 12_000 }, { windowMs: 3_600_000, limit: 20_000 }, { windowMs: 86_400_000, limit: 100_000 }, ] as RateLimitRule[], hostPerEndpoint: [ { windowMs: 60_000, limit: 600 }, { windowMs: 300_000, limit: 6_000 }, { windowMs: 3_600_000, limit: 10_000 }, { windowMs: 86_400_000, limit: 50_000 }, ] as RateLimitRule[], endpoints: { availabilities: [ { windowMs: 60_000, limit: 120 }, ] as RateLimitRule[], listings: [ { windowMs: 60_000, limit: 120 }, ] as RateLimitRule[], reservations: [ { windowMs: 60_000, limit: 60 }, ] as RateLimitRule[], conversations: [ { windowMs: 5_000, limit: 5 }, { windowMs: 3_600_000, limit: 1_000 }, ] as RateLimitRule[], } as Record, }; type EndpointCategory = keyof typeof RATE_LIMIT_RULES.endpoints | 'default'; const ENDPOINT_MATCHERS: Array<{ method: string; pattern: RegExp; category: string; }> = [ { method: 'POST', pattern: /^\/availabilities/, category: 'availabilities' }, { method: 'POST', pattern: /^\/listings/, category: 'listings' }, { method: 'POST', pattern: /^\/reservations$/, category: 'reservations' }, { method: 'POST', pattern: /^\/conversations/, category: 'conversations' }, ]; export function categorizeRequest(method: string, url: string): EndpointCategory { const upperMethod = method.toUpperCase(); for (const matcher of ENDPOINT_MATCHERS) { if (upperMethod === matcher.method && matcher.pattern.test(url)) { return matcher.category as EndpointCategory; } } return 'default'; }