mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-18 13:14:56 +03:00
fix(dashboard): use an indexable UTC month-range predicate for used-this-month (#10381)
sumUsageTokensThisMonth() filtered usage_history with
substr(timestamp, 1, 7) = strftime('%Y-%m', 'now') — a substr() expression
SQLite cannot use a range index on, and fragile against any timestamp
that isn't exactly ISO-shaped. Replace with an indexable inclusive-start/
exclusive-end UTC range: timestamp >= <month start> AND timestamp <
<next month start>, matching the ISO 8601 format saveRequestUsage()
already writes.
Adds a boundary regression test: the first instant of the current month
is included, the last instant of the previous month is excluded, and a
next-month row is excluded too (covers the upper bound substr() could
never express).
This commit is contained in:
@@ -25,7 +25,8 @@ export function sumUsageTokensThisMonth(db: SqliteAdapter = getDbInstance()): nu
|
||||
COALESCE((
|
||||
SELECT SUM(tokens_input + tokens_output)
|
||||
FROM usage_history
|
||||
WHERE substr(timestamp, 1, 7) = strftime('%Y-%m', 'now')
|
||||
WHERE timestamp >= strftime('%Y-%m-01T00:00:00.000Z','now')
|
||||
AND timestamp < strftime('%Y-%m-01T00:00:00.000Z','now','+1 month')
|
||||
), 0) +
|
||||
COALESCE((
|
||||
SELECT SUM(total_input_tokens + total_output_tokens)
|
||||
|
||||
@@ -60,3 +60,42 @@ test("sumUsageTokensThisMonth includes the current month's raw usage_history row
|
||||
|
||||
assert.equal(sumUsageTokensThisMonth(), 400 + 50);
|
||||
});
|
||||
|
||||
// #10509 sweep: the `substr(timestamp, 1, 7) = strftime('%Y-%m', 'now')` predicate was
|
||||
// fragile/non-indexable (SQLite cannot use a range index on a substr() expression, and a
|
||||
// non-ISO-shaped timestamp string silently mismatches). Replaced with an indexable UTC
|
||||
// month-range comparison (`timestamp >= <month start> AND timestamp < <next month start>`).
|
||||
// This test pins the exact boundary: the first instant of the current month is INCLUDED,
|
||||
// the last instant of the PREVIOUS month is EXCLUDED, and a NEXT-month row is EXCLUDED too
|
||||
// (guards the upper-bound half of the range, which substr() could never express directly).
|
||||
test("sumUsageTokensThisMonth uses an inclusive-start/exclusive-end UTC month range (#10509)", () => {
|
||||
const db = getDbInstance();
|
||||
db.exec(`CREATE TABLE IF NOT EXISTS usage_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, provider TEXT, model TEXT, connection_id TEXT,
|
||||
api_key_id TEXT, api_key_name TEXT, tokens_input INTEGER DEFAULT 0, tokens_output INTEGER DEFAULT 0,
|
||||
tokens_cache_read INTEGER DEFAULT 0, tokens_cache_creation INTEGER DEFAULT 0, tokens_reasoning INTEGER DEFAULT 0,
|
||||
service_tier TEXT DEFAULT 'standard', status TEXT, success INTEGER DEFAULT 1, latency_ms INTEGER DEFAULT 0,
|
||||
ttft_ms INTEGER DEFAULT 0, error_code TEXT, timestamp TEXT NOT NULL);`);
|
||||
db.exec(`CREATE TABLE IF NOT EXISTS daily_usage_summary (id INTEGER PRIMARY KEY AUTOINCREMENT, provider TEXT NOT NULL, model TEXT NOT NULL, date TEXT NOT NULL, total_requests INTEGER NOT NULL DEFAULT 0, total_input_tokens INTEGER NOT NULL DEFAULT 0, total_output_tokens INTEGER NOT NULL DEFAULT 0, total_cost REAL NOT NULL DEFAULT 0.0, created_at TEXT NOT NULL DEFAULT (datetime('now')));`);
|
||||
db.exec("DELETE FROM usage_history");
|
||||
db.exec("DELETE FROM daily_usage_summary");
|
||||
|
||||
const monthStart = db
|
||||
.prepare("SELECT strftime('%Y-%m-01T00:00:00.000Z','now') AS s")
|
||||
.get() as { s: string };
|
||||
const nextMonthStart = db
|
||||
.prepare("SELECT strftime('%Y-%m-01T00:00:00.000Z','now','+1 month') AS s")
|
||||
.get() as { s: string };
|
||||
const lastInstantOfPrevMonth = new Date(
|
||||
new Date(monthStart.s).getTime() - 1
|
||||
).toISOString();
|
||||
|
||||
const insHistory = db.prepare(
|
||||
"INSERT INTO usage_history (provider, model, tokens_input, tokens_output, timestamp) VALUES (?,?,?,?,?)"
|
||||
);
|
||||
insHistory.run("openai", "gpt-4.1", 10, 0, monthStart.s); // first instant of THIS month — included
|
||||
insHistory.run("openai", "gpt-4.1", 9999, 0, lastInstantOfPrevMonth); // last ms of PREV month — excluded
|
||||
insHistory.run("openai", "gpt-4.1", 9999, 0, nextMonthStart.s); // first instant of NEXT month — excluded
|
||||
|
||||
assert.equal(sumUsageTokensThisMonth(), 10);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user