veylant/migrations/000003_routing_rules.up.sql
2026-02-23 13:35:04 +01:00

46 lines
2.2 KiB
SQL

-- Migration 000003: Routing rules — intelligent routing engine (Sprint 5)
-- Stores per-tenant routing rules with JSONB conditions and actions.
-- Evaluated in priority order (ASC); first fully matching rule wins.
CREATE TABLE routing_rules (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
-- conditions: JSON array of condition objects, ALL must match (AND logic).
-- Each condition: {"field":"request.sensitivity","operator":"gte","value":"high"}
-- Supported fields: user.role, user.department, request.sensitivity,
-- request.model, request.use_case, request.token_estimate
-- Supported operators: eq, neq, in, nin, gte, lte, contains, matches
-- Empty array [] means the rule matches all requests (catch-all).
conditions JSONB NOT NULL DEFAULT '[]',
-- action: routing decision when rule matches.
-- {"provider":"ollama","model":"llama3","fallback_providers":["openai","anthropic"]}
action JSONB NOT NULL,
-- priority: lower value = higher priority. Evaluated in ASC order.
priority INT NOT NULL DEFAULT 100,
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Fast lookup: active rules for a tenant, sorted by priority.
CREATE INDEX idx_routing_rules_tenant_active
ON routing_rules (tenant_id, is_enabled, priority);
-- Validate that the 'provider' field in action is one of the known providers.
ALTER TABLE routing_rules
ADD CONSTRAINT chk_routing_rules_provider
CHECK ((action->>'provider') IN ('openai', 'anthropic', 'azure', 'mistral', 'ollama'));
-- Auto-update updated_at on row modification.
CREATE TRIGGER routing_rules_updated_at
BEFORE UPDATE ON routing_rules
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
-- Row-Level Security: tenants can only access their own rules.
ALTER TABLE routing_rules ENABLE ROW LEVEL SECURITY;
CREATE POLICY routing_rules_tenant_isolation ON routing_rules
USING (tenant_id = current_setting('app.current_tenant_id', TRUE)::UUID);