raazkumar's picture
Upload production/init.sql
a845c8d verified
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE TABLE IF NOT EXISTS sessions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id VARCHAR(64) DEFAULT 'default',
created_at TIMESTAMPTZ DEFAULT NOW(),
last_active_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ DEFAULT NOW() + INTERVAL '7 days',
budget_usd NUMERIC(10, 6) DEFAULT 10.0,
spent_usd NUMERIC(10, 6) DEFAULT 0.0,
status VARCHAR(32) DEFAULT 'active',
metadata JSONB DEFAULT '{}',
context_json JSONB DEFAULT '[]',
model_name VARCHAR(128),
reasoning_effort VARCHAR(32),
max_iterations INTEGER DEFAULT 300,
yolo_mode BOOLEAN DEFAULT FALSE,
CONSTRAINT positive_budget CHECK (budget_usd >= 0),
CONSTRAINT positive_spent CHECK (spent_usd >= 0)
);
CREATE TABLE IF NOT EXISTS requests (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
session_id UUID REFERENCES sessions(id) ON DELETE CASCADE,
tenant_id VARCHAR(64) DEFAULT 'default',
trace_id VARCHAR(128),
model VARCHAR(128) NOT NULL,
provider VARCHAR(64) NOT NULL,
operation_type VARCHAR(32) DEFAULT 'chat',
input_tokens INTEGER DEFAULT 0,
output_tokens INTEGER DEFAULT 0,
total_tokens INTEGER GENERATED ALWAYS AS (input_tokens + output_tokens) STORED,
cost_usd NUMERIC(10, 6) DEFAULT 0.0,
cached BOOLEAN DEFAULT FALSE,
latency_ms INTEGER,
queue_time_ms INTEGER DEFAULT 0,
request_payload JSONB,
response_payload JSONB,
tool_calls JSONB DEFAULT '[]',
finish_reason VARCHAR(32),
rate_limited BOOLEAN DEFAULT FALSE,
circuit_open BOOLEAN DEFAULT FALSE,
retry_count INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT non_negative_tokens CHECK (input_tokens >= 0 AND output_tokens >= 0)
);
CREATE TABLE IF NOT EXISTS circuit_events (
id SERIAL PRIMARY KEY,
provider VARCHAR(64) NOT NULL,
event_type VARCHAR(32) NOT NULL,
failure_count INTEGER DEFAULT 0,
details JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS budget_events (
id SERIAL PRIMARY KEY,
session_id UUID REFERENCES sessions(id) ON DELETE CASCADE,
event_type VARCHAR(32) NOT NULL,
threshold_percent INTEGER,
spent_before NUMERIC(10, 6),
spent_after NUMERIC(10, 6),
budget NUMERIC(10, 6),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS tool_executions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
request_id UUID REFERENCES requests(id) ON DELETE CASCADE,
tool_name VARCHAR(128) NOT NULL,
tool_args JSONB,
result_json JSONB,
success BOOLEAN DEFAULT TRUE,
error_message TEXT,
latency_ms INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS cache_events (
id SERIAL PRIMARY KEY,
cache_key VARCHAR(256) NOT NULL,
cache_type VARCHAR(32) NOT NULL,
hit BOOLEAN NOT NULL,
ttl_seconds INTEGER,
size_bytes INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sessions_tenant ON sessions(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expires_at);
CREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_sessions_active ON sessions(tenant_id, status) WHERE status = 'active';
CREATE INDEX IF NOT EXISTS idx_sessions_metadata ON sessions USING GIN (metadata);
CREATE INDEX IF NOT EXISTS idx_requests_session ON requests(session_id);
CREATE INDEX IF NOT EXISTS idx_requests_tenant ON requests(tenant_id);
CREATE INDEX IF NOT EXISTS idx_requests_trace ON requests(trace_id);
CREATE INDEX IF NOT EXISTS idx_requests_provider ON requests(provider);
CREATE INDEX IF NOT EXISTS idx_requests_created ON requests(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_requests_model ON requests(model);
CREATE INDEX IF NOT EXISTS idx_requests_payload ON requests USING GIN (request_payload);
CREATE INDEX IF NOT EXISTS idx_circuit_provider ON circuit_events(provider);
CREATE INDEX IF NOT EXISTS idx_circuit_created ON circuit_events(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_budget_session ON budget_events(session_id);
CREATE INDEX IF NOT EXISTS idx_tool_request ON tool_executions(request_id);
CREATE INDEX IF NOT EXISTS idx_tool_name ON tool_executions(tool_name);
CREATE INDEX IF NOT EXISTS idx_cache_key ON cache_events(cache_key);
CREATE INDEX IF NOT EXISTS idx_cache_created ON cache_events(created_at DESC);
CREATE OR REPLACE FUNCTION update_last_active()
RETURNS TRIGGER AS $$
BEGIN
NEW.last_active_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trigger_update_last_active ON sessions;
CREATE TRIGGER trigger_update_last_active
BEFORE UPDATE ON sessions
FOR EACH ROW
EXECUTE FUNCTION update_last_active();
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_daily_costs AS
SELECT
tenant_id,
DATE(created_at) as date,
provider,
model,
COUNT(*) as request_count,
SUM(input_tokens) as total_input_tokens,
SUM(output_tokens) as total_output_tokens,
SUM(cost_usd) as total_cost_usd,
AVG(latency_ms)::NUMERIC(10,2) as avg_latency_ms,
SUM(CASE WHEN cached THEN 1 ELSE 0 END) as cache_hits,
SUM(CASE WHEN NOT cached THEN 1 ELSE 0 END) as cache_misses
FROM requests
GROUP BY tenant_id, DATE(created_at), provider, model;
CREATE UNIQUE INDEX IF NOT EXISTS idx_mv_daily_costs ON mv_daily_costs(tenant_id, date, provider, model);
CREATE OR REPLACE FUNCTION refresh_daily_costs()
RETURNS void AS $$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_daily_costs;
END;
$$ LANGUAGE plpgsql;
ALTER TABLE sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE requests ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_sessions ON sessions
USING (tenant_id = current_setting('app.current_tenant', true));
CREATE POLICY tenant_isolation_requests ON requests
USING (tenant_id = current_setting('app.current_tenant', true));
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ml_intern;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ml_intern;