sync: migrate ai-operator to Gitea (2026-08-10)

This commit is contained in:
konturai-ops
2026-08-10 15:26:52 +00:00
commit 53652b95ad
173 changed files with 16676 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE IF NOT EXISTS schema_migrations (
version text PRIMARY KEY,
applied_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS knowledge_documents (
id uuid PRIMARY KEY,
external_id text NOT NULL UNIQUE,
title text NOT NULL,
language text NOT NULL CHECK (language IN ('ru','kk')),
region_code text NOT NULL DEFAULT 'global' CHECK (length(region_code) > 0),
category text NOT NULL DEFAULT 'general',
source_type text NOT NULL,
source_uri text,
source_hash text NOT NULL,
status text NOT NULL DEFAULT 'published' CHECK (status IN ('draft','published','archived')),
content text NOT NULL,
question text,
short_answer text,
full_answer text,
keywords text[] NOT NULL DEFAULT '{}',
source text,
metadata jsonb NOT NULL DEFAULT '{}',
valid_from timestamptz,
valid_to timestamptz,
priority int NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS knowledge_chunks (
id uuid PRIMARY KEY,
document_id uuid NOT NULL REFERENCES knowledge_documents(id) ON DELETE CASCADE,
chunk_index int NOT NULL,
language text NOT NULL CHECK (language IN ('ru','kk')),
region_code text NOT NULL,
title text NOT NULL,
content text NOT NULL,
content_hash text NOT NULL,
token_estimate int NOT NULL DEFAULT 0,
char_count int NOT NULL DEFAULT 0,
embedding vector(1536),
embedding_model text NOT NULL DEFAULT 'fake',
embedding_provider text NOT NULL DEFAULT 'fake',
metadata jsonb NOT NULL DEFAULT '{}',
tsv tsvector,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE(document_id, chunk_index)
);
CREATE TABLE IF NOT EXISTS knowledge_ingest_runs (
id uuid PRIMARY KEY,
source_path text NOT NULL,
status text NOT NULL,
documents_seen int NOT NULL DEFAULT 0,
documents_ingested int NOT NULL DEFAULT 0,
chunks_created int NOT NULL DEFAULT 0,
skipped int NOT NULL DEFAULT 0,
error text,
started_at timestamptz NOT NULL DEFAULT now(),
finished_at timestamptz
);
CREATE TABLE IF NOT EXISTS knowledge_search_logs (
id uuid PRIMARY KEY,
call_id text,
query text NOT NULL,
language text NOT NULL,
region_code text NOT NULL,
result_count int NOT NULL,
top_score double precision,
cross_language_fallback_used boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now()
);
+20
View File
@@ -0,0 +1,20 @@
CREATE UNIQUE INDEX IF NOT EXISTS idx_kd_external_id ON knowledge_documents(external_id);
CREATE INDEX IF NOT EXISTS idx_kd_language_region_status ON knowledge_documents(language, region_code, status);
CREATE INDEX IF NOT EXISTS idx_kd_source_hash ON knowledge_documents(source_hash);
CREATE INDEX IF NOT EXISTS idx_kd_validity ON knowledge_documents(valid_from, valid_to);
CREATE INDEX IF NOT EXISTS idx_kc_document_id ON knowledge_chunks(document_id);
CREATE INDEX IF NOT EXISTS idx_kc_language_region ON knowledge_chunks(language, region_code);
CREATE INDEX IF NOT EXISTS idx_kc_content_hash ON knowledge_chunks(content_hash);
CREATE INDEX IF NOT EXISTS idx_kc_tsv ON knowledge_chunks USING GIN(tsv);
DO $$
BEGIN
BEGIN
CREATE INDEX IF NOT EXISTS idx_kc_embedding_hnsw ON knowledge_chunks USING hnsw (embedding vector_cosine_ops);
EXCEPTION WHEN OTHERS THEN
BEGIN
CREATE INDEX IF NOT EXISTS idx_kc_embedding_ivfflat ON knowledge_chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'vector index creation skipped: %', SQLERRM;
END;
END;
END $$;
+163
View File
@@ -0,0 +1,163 @@
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE IF NOT EXISTS ai_calls (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text NOT NULL UNIQUE,
asterisk_channel_id text,
route text NOT NULL DEFAULT 'unknown',
caller_number_masked text,
language text,
region_code text,
state text,
started_at timestamptz NOT NULL,
ended_at timestamptz,
duration_ms bigint,
end_reason text,
handoff_status text,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_calls_started_at ON ai_calls(started_at);
CREATE INDEX IF NOT EXISTS idx_ai_calls_route ON ai_calls(route);
CREATE INDEX IF NOT EXISTS idx_ai_calls_language_region ON ai_calls(language, region_code);
CREATE INDEX IF NOT EXISTS idx_ai_calls_state ON ai_calls(state);
CREATE TABLE IF NOT EXISTS ai_call_events (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text NOT NULL,
event_type text NOT NULL,
event_source text NOT NULL,
state_before text,
state_after text,
severity text NOT NULL DEFAULT 'info',
message text,
reason_code text,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_call_events_call_id_created_at ON ai_call_events(call_id, created_at);
CREATE INDEX IF NOT EXISTS idx_ai_call_events_type ON ai_call_events(event_type);
CREATE INDEX IF NOT EXISTS idx_ai_call_events_severity ON ai_call_events(severity);
CREATE TABLE IF NOT EXISTS ai_transcript_events (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text NOT NULL,
speaker text NOT NULL CHECK (speaker IN ('user','assistant','system','tool')),
event_type text NOT NULL,
language text,
text_redacted text,
text_raw_encrypted text,
text_hash text,
char_count int NOT NULL DEFAULT 0,
redaction_applied boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_transcript_events_call_id_created_at ON ai_transcript_events(call_id, created_at);
CREATE INDEX IF NOT EXISTS idx_ai_transcript_events_speaker ON ai_transcript_events(speaker);
CREATE INDEX IF NOT EXISTS idx_ai_transcript_events_language ON ai_transcript_events(language);
CREATE TABLE IF NOT EXISTS ai_tool_audit (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text NOT NULL,
tool_call_id text,
tool_name text NOT NULL,
state text,
language text,
region_code text,
allowed boolean NOT NULL,
denied boolean NOT NULL DEFAULT false,
reason_code text,
args_redacted jsonb NOT NULL DEFAULT '{}',
result_redacted jsonb NOT NULL DEFAULT '{}',
duration_ms bigint,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_tool_audit_call_id_created_at ON ai_tool_audit(call_id, created_at);
CREATE INDEX IF NOT EXISTS idx_ai_tool_audit_tool_name ON ai_tool_audit(tool_name);
CREATE INDEX IF NOT EXISTS idx_ai_tool_audit_denied ON ai_tool_audit(denied);
CREATE TABLE IF NOT EXISTS ai_kb_audit (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text,
query_redacted text NOT NULL,
language text NOT NULL,
region_code text NOT NULL,
result_count int NOT NULL DEFAULT 0,
top_score double precision,
cross_language_fallback_used boolean NOT NULL DEFAULT false,
citations_count int NOT NULL DEFAULT 0,
no_answer boolean NOT NULL DEFAULT false,
duration_ms bigint,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_kb_audit_call_id_created_at ON ai_kb_audit(call_id, created_at);
CREATE INDEX IF NOT EXISTS idx_ai_kb_audit_language_region ON ai_kb_audit(language, region_code);
CREATE INDEX IF NOT EXISTS idx_ai_kb_audit_no_answer ON ai_kb_audit(no_answer);
CREATE TABLE IF NOT EXISTS ai_handoff_audit (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text NOT NULL,
handoff_id text,
mode text NOT NULL,
status text NOT NULL,
reason_code text,
transfer_attempted boolean NOT NULL DEFAULT false,
transfer_succeeded boolean NOT NULL DEFAULT false,
target_redacted text,
summary_redacted text,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS idx_ai_handoff_audit_call_id_created_at ON ai_handoff_audit(call_id, created_at);
CREATE INDEX IF NOT EXISTS idx_ai_handoff_audit_status ON ai_handoff_audit(status);
CREATE INDEX IF NOT EXISTS idx_ai_handoff_audit_mode ON ai_handoff_audit(mode);
CREATE TABLE IF NOT EXISTS ai_provider_audit (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text,
provider text NOT NULL,
event_type text NOT NULL,
severity text NOT NULL DEFAULT 'info',
error_redacted text,
input_audio_bytes bigint NOT NULL DEFAULT 0,
output_audio_bytes bigint NOT NULL DEFAULT 0,
events_received bigint NOT NULL DEFAULT 0,
events_sent bigint NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE TABLE IF NOT EXISTS ai_media_audit (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
call_id text,
event_type text NOT NULL,
severity text NOT NULL DEFAULT 'info',
codec text,
inbound_frames bigint NOT NULL DEFAULT 0,
inbound_bytes bigint NOT NULL DEFAULT 0,
outbound_frames bigint NOT NULL DEFAULT 0,
outbound_bytes bigint NOT NULL DEFAULT 0,
xoff_count bigint NOT NULL DEFAULT 0,
xon_count bigint NOT NULL DEFAULT 0,
error_redacted text,
created_at timestamptz NOT NULL DEFAULT now(),
metadata jsonb NOT NULL DEFAULT '{}'
);
CREATE TABLE IF NOT EXISTS ai_audit_retention_runs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
dry_run boolean NOT NULL DEFAULT true,
status text NOT NULL,
started_at timestamptz NOT NULL DEFAULT now(),
finished_at timestamptz,
calls_deleted int NOT NULL DEFAULT 0,
events_deleted int NOT NULL DEFAULT 0,
transcripts_deleted int NOT NULL DEFAULT 0,
tool_audit_deleted int NOT NULL DEFAULT 0,
error text,
metadata jsonb NOT NULL DEFAULT '{}'
);