From 363236f2f6457cce59731d2357f1a789726a5f2a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 06:18:18 +0000 Subject: [PATCH] refactor(api): DRY limit-query clamping onto parseBoundedLimit (BEN-150) /api/events/recent and /api/search both parsed a "limit" query with the same "clamp to [1, max] with fallback" recipe, spelled out slightly differently at each site. Extract a single `parseBoundedLimit` helper and pass fallback + max explicitly per route so the ceilings stay route-specific but the clamping recipe lives in one place. No behavior change; the existing recent-events cap test still passes. --- src/api/server.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api/server.ts b/src/api/server.ts index a2c7c0d..ec4659f 100644 --- a/src/api/server.ts +++ b/src/api/server.ts @@ -61,6 +61,14 @@ const DEFAULT_ERROR_EVENT_TYPES = [ "workspace_destroy_error", ]; +function parseBoundedLimit( + raw: string | undefined, + { fallback, max, min = 1 }: { fallback: number; max: number; min?: number }, +): number { + if (!raw) return fallback; + return Math.max(min, Math.min(max, Number(raw))); +} + const PLACEHOLDER_HTML = ` Symphony @@ -119,8 +127,7 @@ export function createServer({ .map((t) => t.trim()) .filter((t) => t.length > 0) : DEFAULT_ERROR_EVENT_TYPES; - const limitRaw = c.req.query("limit"); - const limit = limitRaw ? Math.max(1, Math.min(200, Number(limitRaw))) : 50; + const limit = parseBoundedLimit(c.req.query("limit"), { fallback: 50, max: 200 }); return c.json({ events: logger.listRecentEvents(types, limit) }); }); @@ -178,8 +185,7 @@ export function createServer({ app.get("/api/search", (c) => { const q = c.req.query("q") ?? ""; - const limitRaw = c.req.query("limit"); - const limit = limitRaw ? Math.max(1, Math.min(500, Number(limitRaw))) : 100; + const limit = parseBoundedLimit(c.req.query("limit"), { fallback: 100, max: 500 }); return c.json({ query: q, matches: logger.search(q, limit) }); });