export const SEARCH_QUERY_CACHE_TTL_MS = 24 * 60 * 60 * 1000; export function normalizeSearchQuery(value: string | null | undefined) { const normalized = value?.trim().toLowerCase() ?? ""; return normalized || null; } export function hasReusableSearchPayload(candidate: { resultCount: number; answerText?: string | null }) { return candidate.resultCount > 0 || Boolean(candidate.answerText?.trim()); } export function isFreshSearchCacheHit( candidate: { updatedAt: Date | string; resultCount: number; answerText?: string | null; isActive?: boolean; }, now = new Date(), ttlMs = SEARCH_QUERY_CACHE_TTL_MS ) { if (candidate.isActive) return false; if (!hasReusableSearchPayload(candidate)) return false; const updatedAtMs = new Date(candidate.updatedAt).getTime(); if (!Number.isFinite(updatedAtMs)) return false; return now.getTime() - updatedAtMs <= ttlMs; }