import { db } from '@/lib/db'; export async function rateLimit( key: string, maxRequests: number, windowMs: number ): Promise<{ allowed: boolean; retryAfterMs: number }> { const now = new Date(); try { const record = await db.rateLimit.findUnique({ where: { key }, }); if (!record) { await db.rateLimit.create({ data: { key, count: 1, resetAt: new Date(now.getTime() + windowMs), }, }); return { allowed: true, retryAfterMs: 0 }; } if (now >= record.resetAt) { // Window expired — reset const updated = await db.rateLimit.update({ where: { key }, data: { count: 1, resetAt: new Date(now.getTime() + windowMs), }, }); return { allowed: true, retryAfterMs: 0 }; } if (record.count >= maxRequests) { const retryAfterMs = record.resetAt.getTime() - now.getTime(); return { allowed: false, retryAfterMs }; } await db.rateLimit.update({ where: { key }, data: { count: { increment: 1 } }, }); return { allowed: true, retryAfterMs: 0 }; } catch { // On DB error, allow the request through (fail-open) return { allowed: true, retryAfterMs: 0 }; } } // Pre-configured rate limiters export const authRateLimit = (key: string) => rateLimit(key, 5, 60_000); // 5 requests per minute export const uploadRateLimit = (key: string) => rateLimit(key, 20, 60_000); // 20 requests per minute export const chatRateLimit = (key: string) => rateLimit(key, 20, 60_000); // 20 requests per minute export const generalRateLimit = (key: string) => rateLimit(key, 60, 60_000); // 60 requests per minute