feat: complete v0.5 operations foundation

This commit is contained in:
2026-07-19 03:58:03 +08:00
parent ca3f706cc1
commit d285f3e275
35 changed files with 248 additions and 39 deletions
+17 -6
View File
@@ -1,8 +1,19 @@
const visits = new Map<string, { count: number; resetAt: number }>();
import { db } from "@/lib/db";
export function withinRateLimit(key: string, limit = 30, windowMs = 60_000) {
const now = Date.now(); const record = visits.get(key);
if (!record || record.resetAt <= now) { visits.set(key, { count: 1, resetAt: now + windowMs }); return true; }
if (record.count >= limit) return false;
record.count += 1; return true;
/** SQLite-backed fixed-window limiter shared by every Web container using this database. */
export function withinRateLimit(bucket: string, limit = 30, windowMs = 60_000) {
const now = Date.now();
const transaction = db.transaction(() => {
const found = db.prepare("SELECT count,reset_at FROM rate_limits WHERE bucket=?").get(bucket) as { count: number; reset_at: number } | undefined;
if (!found || found.reset_at <= now) {
db.prepare("INSERT INTO rate_limits(bucket,count,reset_at) VALUES(?,?,?) ON CONFLICT(bucket) DO UPDATE SET count=excluded.count,reset_at=excluded.reset_at").run(bucket, 1, now + windowMs);
return true;
}
if (found.count >= limit) return false;
db.prepare("UPDATE rate_limits SET count=count+1 WHERE bucket=?").run(bucket);
return true;
});
const allowed = transaction();
if (Math.random() < 0.01) db.prepare("DELETE FROM rate_limits WHERE reset_at<?").run(now);
return allowed;
}