diff --git a/src/lib/db/repos/usageRepo.js b/src/lib/db/repos/usageRepo.js index 41199937..4ea3b8bd 100644 --- a/src/lib/db/repos/usageRepo.js +++ b/src/lib/db/repos/usageRepo.js @@ -5,8 +5,9 @@ import { getMeta, setMeta } from "../helpers/metaStore.js"; function maskApiKey(key) { if (!key || typeof key !== "string") return null; - if (key.length <= 8) return key.charAt(0) + "***"; - return key.slice(0, 8) + "***"; + if (key.length <= 12) return key.charAt(0) + "***"; + // Keep the tail: keys sharing a machine-id prefix (team keys) must not collide. + return key.slice(0, 8) + "***" + key.slice(-4); } const PENDING_TIMEOUT_MS = 60 * 1000; @@ -634,6 +635,8 @@ export async function getUsageStats(period = "all") { const keyInfo = apiKeyMap[r.apiKey]; const keyName = keyInfo?.name || r.apiKey.slice(0, 8) + "..."; const apiKeyMasked = maskApiKey(r.apiKey); + // Key by the FULL api key (same as the daily rollup + lastUsed overlay) + // — masking here collided all keys sharing a prefix into one bucket. const akKey = `${r.apiKey}|${r.model}|${r.provider || "unknown"}`; if (!stats.byApiKey[akKey]) { stats.byApiKey[akKey] = { requests: 0, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0, rawModel: r.model, provider: providerDisplayName, apiKeyMasked, keyName, apiKeyKey: apiKeyMasked, lastUsed: r.timestamp };