import { CUSTOMER_RATE_LIMIT, CUSTOMER_RATE_WINDOW_SECONDS, } from "@/lib/constants/cache"; import { withBoundedRedis } from "@/lib/redis"; export type RateLimitResult = | { allowed: true } | { allowed: false; errorCode: "RATE_LIMITED" }; function customerKey(customerId: string): string { return `ratelimit:customer:${customerId}`; } /** 令牌桶:60 次/分钟/customer,超限返回 RATE_LIMITED */ export async function checkRateLimit( customerId: string, ): Promise { const key = customerKey(customerId); const result = await withBoundedRedis(async (redis) => { const count = await redis.incr(key); if (count === 1) { await redis.expire(key, CUSTOMER_RATE_WINDOW_SECONDS); } if (count > CUSTOMER_RATE_LIMIT) { return { allowed: false as const, errorCode: "RATE_LIMITED" as const }; } return { allowed: true as const }; }); if (!result) { return { allowed: true }; } return result; }