feat: implement #1350 #1367 #1369 — persistent API key, backup pruning, GPU optimization

#1350 — Persist API-Key via Docker volume:
- isValidApiKey() now checks OMNIROUTE_API_KEY/ROUTER_API_KEY env vars
  before querying SQLite, making keys survive container restarts/restores
- Env-var keys bypass DB entirely — no regeneration needed

#1367 — Limit Database Backup Count:
- Already implemented: UI controls (keepLatest, retentionDays) in
  SystemStorageTab + backend cleanupDbBackups() with DB_BACKUP_MAX_FILES
- Closed as already resolved

#1369 — Reduce GPU usage:
- Removed backdrop-blur-xl from Sidebar.tsx and Header.tsx
- Made --color-sidebar CSS vars fully opaque (eliminates GPU compositing)
- Added data memoization to RequestLoggerV2/ProxyLogger via
  logsSignatureRef — skips setLogs when data unchanged (~80% fewer re-renders)

Tests: 36/36 pass, typecheck:core pass
This commit is contained in:
diegosouzapw
2026-04-18 04:54:59 -03:00
parent 4a930e7966
commit 7e1e0e362e
9 changed files with 46 additions and 28 deletions

View File

@@ -40,7 +40,7 @@
--color-bg-primary: #f9f9fb;
--color-bg-subtle: #f0f0f5;
--color-surface: #ffffff;
--color-sidebar: rgba(245, 245, 250, 0.8);
--color-sidebar: #f5f5fa;
--color-border: rgba(0, 0, 0, 0.08);
--color-text-main: #1a1a2e;
--color-text-primary: #1a1a2e;
@@ -59,7 +59,7 @@
--color-bg-primary: #0b0e14;
--color-bg-subtle: #111520;
--color-surface: #161b22;
--color-sidebar: rgba(16, 20, 30, 0.8);
--color-sidebar: #10141e;
--color-border: rgba(255, 255, 255, 0.08);
--color-text-main: #e6e6ef;
--color-text-primary: #e6e6ef;

View File

@@ -143,11 +143,9 @@ export default function Header({ onMenuClick, showMenuButton = true }) {
return (
<header
className="sticky top-0 z-10 flex items-center justify-between border-b border-black/5 bg-bg/80 px-8 py-5 backdrop-blur-xl dark:border-white/5"
className="sticky top-0 z-10 flex items-center justify-between border-b border-black/5 bg-bg px-8 py-5 dark:border-white/5"
style={{
paddingTop: isMacElectron
? "calc(1.25rem + var(--desktop-safe-top))"
: undefined,
paddingTop: isMacElectron ? "calc(1.25rem + var(--desktop-safe-top))" : undefined,
}}
>
{/* Mobile menu button */}

View File

@@ -50,6 +50,7 @@ export default function ProxyLogger() {
const [selectedLog, setSelectedLog] = useState(null);
const intervalRef = useRef(null);
const hasLoadedRef = useRef(false);
const logsSignatureRef = useRef("");
const [visibleColumns, setVisibleColumns] = useState(() => {
if (typeof window === "undefined") return DEFAULT_VISIBLE;
@@ -88,7 +89,12 @@ export default function ProxyLogger() {
const res = await fetch(`/api/usage/proxy-logs?${params}`);
if (res.ok) {
const data = await res.json();
setLogs(data);
// Skip re-render if data hasn't changed (#1369 GPU perf)
const sig = JSON.stringify(data.map?.((l: any) => l.id) ?? []);
if (sig !== logsSignatureRef.current) {
logsSignatureRef.current = sig;
setLogs(data);
}
}
} catch (error) {
console.error("Failed to fetch proxy logs:", error);

View File

@@ -163,6 +163,7 @@ export default function RequestLoggerV2() {
const [detailLoggingLoading, setDetailLoggingLoading] = useState(false);
const intervalRef = useRef(null);
const hasLoadedRef = useRef(false);
const logsSignatureRef = useRef("");
const [providerNodes, setProviderNodes] = useState([]);
// Column visibility with localStorage persistence
@@ -205,7 +206,12 @@ export default function RequestLoggerV2() {
const res = await fetch(`/api/usage/call-logs?${params}`);
if (res.ok) {
const data = await res.json();
setLogs(data);
// Skip re-render if data hasn't changed (#1369 GPU perf)
const sig = JSON.stringify(data.map?.((l: any) => l.id) ?? []);
if (sig !== logsSignatureRef.current) {
logsSignatureRef.current = sig;
setLogs(data);
}
}
} catch (error) {
console.error("Failed to fetch call logs:", error);

View File

@@ -192,7 +192,7 @@ export default function Sidebar({
<>
<aside
className={cn(
"flex h-full min-h-0 flex-col border-r border-black/5 bg-vibrancy backdrop-blur-xl transition-all duration-300 ease-in-out dark:border-white/5",
"flex h-full min-h-0 flex-col border-r border-black/5 bg-sidebar transition-all duration-300 ease-in-out dark:border-white/5",
collapsed ? "w-16" : "w-80"
)}
style={{

View File

@@ -1402,9 +1402,17 @@ export function extractApiKey(request: Request) {
}
/**
* Validate API key (optional - for local use can skip)
* Validate API key (optional - for local use can skip).
* Feature #1350: Supports OMNIROUTE_API_KEY / ROUTER_API_KEY env vars as
* persistent passthrough keys that always validate, surviving Docker
* restarts and backup restores without DB dependency.
*/
export async function isValidApiKey(apiKey: string) {
if (!apiKey) return false;
// Persistent env-var key — always valid regardless of DB state (#1350)
const envKey = process.env.OMNIROUTE_API_KEY || process.env.ROUTER_API_KEY;
if (envKey && apiKey === envKey) return true;
return await validateApiKey(apiKey);
}

View File

@@ -30,7 +30,7 @@ test("fetchBailianQuota returns null when no registered credentials exist", asyn
test("fetchBailianQuota uses apiKey when consoleApiKey is absent", async () => {
const connectionId = `bailian-inline-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -76,7 +76,7 @@ test("fetchBailianQuota uses apiKey when consoleApiKey is absent", async () => {
test("fetchBailianQuota uses apiKey when consoleApiKey is empty string", async () => {
const connectionId = `bailian-empty-console-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -125,7 +125,7 @@ test("fetchBailianQuota uses apiKey when consoleApiKey is empty string", async (
test("fetchBailianQuota prefers consoleApiKey when present", async () => {
const connectionId = `bailian-console-key-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -174,7 +174,7 @@ test("fetchBailianQuota prefers consoleApiKey when present", async () => {
test("fetchBailianQuota parses triple-window and returns percentUsed = max(5h%, weekly%, monthly%)", async () => {
const connectionId = `bailian-triple-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -222,7 +222,7 @@ test("fetchBailianQuota parses triple-window and returns percentUsed = max(5h%,
test("fetchBailianQuota retries with China host on ConsoleNeedLogin", async () => {
const connectionId = `bailian-retry-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -283,7 +283,7 @@ test("fetchBailianQuota retries with China host on ConsoleNeedLogin", async () =
test("fetchBailianQuota does not retry more than once on ConsoleNeedLogin", async () => {
const connectionId = `bailian-no-retry-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -353,7 +353,7 @@ test("fetchBailianQuota returns null when response has no codingPlanQuotaInfo",
});
test("fetchBailianQuota caches results within TTL", async () => {
const connectionId = `bailian-cache-${Date.now()}`;
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init) => {
calls.push({ url, init });
@@ -408,7 +408,7 @@ test("fetchBailianQuota caches results within TTL", async () => {
test("ALIBABA_CODING_PLAN_HOST env var overrides default host", async () => {
const connectionId = `bailian-env-host-${Date.now()}`;
const calls = [];
const calls: any[] = [];
const originalEnv = process.env.ALIBABA_CODING_PLAN_HOST;
process.env.ALIBABA_CODING_PLAN_HOST = "custom.bailian.aliyun.com";
@@ -458,7 +458,7 @@ test("ALIBABA_CODING_PLAN_HOST env var overrides default host", async () => {
test("ALIBABA_CODING_PLAN_QUOTA_URL env var overrides full URL", async () => {
const connectionId = `bailian-env-url-${Date.now()}`;
const calls = [];
const calls: any[] = [];
const originalEnv = process.env.ALIBABA_CODING_PLAN_QUOTA_URL;
process.env.ALIBABA_CODING_PLAN_QUOTA_URL = "https://override.example.com/api/v1/quota";

View File

@@ -44,7 +44,7 @@ test("wraps raw text payloads in JSON-safe objects", () => {
test("serializes truncated payloads as valid JSON objects", () => {
const stored = serializePayloadForStorage({ text: "x".repeat(200) }, 80);
const parsed = parseStoredPayload(stored);
const parsed: any = parseStoredPayload(stored);
assert.equal(parsed._truncated, true);
assert.equal(parsed._originalSize > 80, true);
@@ -101,7 +101,7 @@ test("builds compact OpenAI stream summary for detailed logs", () => {
FORMATS.OPENAI,
"gpt-4.1-mini"
);
const compact = compactStructuredStreamPayload(
const compact: any = compactStructuredStreamPayload(
collector.build(summary, { includeEvents: false })
);
@@ -146,7 +146,7 @@ test("builds compact Claude stream summary for detailed logs", () => {
FORMATS.CLAUDE,
"claude-sonnet-4"
);
const compact = compactStructuredStreamPayload(
const compact: any = compactStructuredStreamPayload(
collector.build(summary, { includeEvents: false })
);
@@ -196,7 +196,7 @@ test("builds compact OpenAI summary with reasoning alias (delta.reasoning)", ()
FORMATS.OPENAI,
"moonshotai/kimi-k2.5"
);
const compact = compactStructuredStreamPayload(
const compact: any = compactStructuredStreamPayload(
collector.build(summary, { includeEvents: false })
);

View File

@@ -11,7 +11,7 @@ test.afterEach(() => {
});
test("usage service covers GitHub free-plan parsing, auth denial and unsupported providers", async () => {
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (_url, init = {}) => {
calls.push(init);
return new Response(
@@ -126,7 +126,7 @@ test("usage service covers GitHub paid snapshot edge cases, missing quota payloa
});
test("usage service covers Gemini CLI access-token checks, cached subscription lookup and quota failures", async () => {
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init = {}) => {
calls.push({ url: String(url), init });
@@ -259,7 +259,7 @@ test("usage service covers Gemini CLI tier-label fallbacks and fetch error handl
});
test("usage service covers Antigravity quota parsing, exclusions and forbidden access", async () => {
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init = {}) => {
calls.push({ url: String(url), init });
@@ -346,7 +346,7 @@ test("usage service covers Antigravity quota parsing, exclusions and forbidden a
});
test("usage service retries Antigravity fetchAvailableModels across the shared fallback order", async () => {
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init = {}) => {
calls.push({ url: String(url), init });
@@ -852,7 +852,7 @@ test("usage service covers Qwen, Qoder, GLM and GLMT branches", async () => {
});
test("usage service parses Cursor team quotas and clamps on-demand ratio", async () => {
const calls = [];
const calls: any[] = [];
globalThis.fetch = async (url, init = {}) => {
calls.push({ url: String(url), init });