mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 05:12:11 +03:00
62 lines
2.9 KiB
SQL
62 lines
2.9 KiB
SQL
-- Migration 073: per-API-key token limits (scoped to model and/or provider)
|
|
--
|
|
-- Adds enforcement-grade token budgets attachable to an API key and scoped to a
|
|
-- specific model, a specific provider, or globally (all traffic for the key).
|
|
-- When a key exceeds its configured token budget within the active reset window,
|
|
-- requests are rejected with HTTP 429. This complements (does not replace) the
|
|
-- USD cost budgets in `domain_budgets` / src/domain/costRules.ts. Token usage is
|
|
-- already captured per request in usage_history; these tables provide the
|
|
-- authoritative rolling-window counters used for pre-flight enforcement.
|
|
--
|
|
-- Three tables:
|
|
-- api_key_token_limits - the limit definitions (one per scope per key)
|
|
-- api_key_token_counters - rolling-window usage counters (implicit rollover)
|
|
-- api_key_token_limit_reset_logs - audit trail of window resets
|
|
--
|
|
-- Plus a composite index on usage_history to make the cold-start seed-on-miss
|
|
-- SUM (api_key_id, provider, model, timestamp) an index scan rather than a table
|
|
-- scan. The build does NOT run with PRAGMA foreign_keys=ON, so the FK clause is
|
|
-- declarative only (matches existing repo convention; application code is the
|
|
-- single writer and prunes counters via ON DELETE CASCADE semantics best-effort).
|
|
|
|
CREATE TABLE IF NOT EXISTS api_key_token_limits (
|
|
id TEXT PRIMARY KEY,
|
|
api_key_id TEXT NOT NULL,
|
|
scope_type TEXT NOT NULL CHECK (scope_type IN ('model', 'provider', 'global')),
|
|
scope_value TEXT NOT NULL DEFAULT '',
|
|
token_limit INTEGER NOT NULL CHECK (token_limit > 0),
|
|
reset_interval TEXT NOT NULL DEFAULT 'monthly' CHECK (reset_interval IN ('daily', 'weekly', 'monthly')),
|
|
reset_time TEXT,
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
UNIQUE (api_key_id, scope_type, scope_value)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_aktl_api_key_id
|
|
ON api_key_token_limits (api_key_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS api_key_token_counters (
|
|
limit_id TEXT NOT NULL,
|
|
window_start TEXT NOT NULL,
|
|
tokens_used INTEGER NOT NULL DEFAULT 0,
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
PRIMARY KEY (limit_id, window_start),
|
|
FOREIGN KEY (limit_id) REFERENCES api_key_token_limits (id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS api_key_token_limit_reset_logs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
limit_id TEXT NOT NULL,
|
|
reset_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
prev_tokens INTEGER NOT NULL DEFAULT 0,
|
|
window_start TEXT NOT NULL,
|
|
FOREIGN KEY (limit_id) REFERENCES api_key_token_limits (id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_aktlrl_limit_id
|
|
ON api_key_token_limit_reset_logs (limit_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_uh_key_provider_model_ts
|
|
ON usage_history (api_key_id, provider, model, timestamp);
|