Initial import with GitLab CI/CD and registry deploy flow

This commit is contained in:
Yera All
2026-04-02 17:05:45 +05:00
commit 5374c202d9
338 changed files with 81297 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
-- Core MVP schema (PostgreSQL)
CREATE TABLE IF NOT EXISTS auth_users (
id BIGSERIAL PRIMARY KEY,
user_id VARCHAR(64) NOT NULL UNIQUE,
username VARCHAR(128) NOT NULL UNIQUE,
password VARCHAR(256) NOT NULL,
full_name VARCHAR(256) NOT NULL,
role VARCHAR(32) NOT NULL,
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_auth_users_user_id ON auth_users (user_id);
CREATE INDEX IF NOT EXISTS ix_auth_users_username ON auth_users (username);
CREATE INDEX IF NOT EXISTS ix_auth_users_role ON auth_users (role);
CREATE TABLE IF NOT EXISTS customers (
id BIGSERIAL PRIMARY KEY,
customer_id VARCHAR(64) NOT NULL UNIQUE,
display_name VARCHAR(256) NOT NULL,
phones_json TEXT NOT NULL DEFAULT '[]',
preferred_phone VARCHAR(64),
tags_json TEXT NOT NULL DEFAULT '[]',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_customers_customer_id ON customers (customer_id);
CREATE INDEX IF NOT EXISTS ix_customers_display_name ON customers (display_name);
CREATE TABLE IF NOT EXISTS interactions (
id BIGSERIAL PRIMARY KEY,
interaction_id VARCHAR(64) NOT NULL UNIQUE,
channel VARCHAR(32) NOT NULL,
subject VARCHAR(512) NOT NULL,
customer_id VARCHAR(64),
queue_id VARCHAR(64),
priority INTEGER NOT NULL DEFAULT 3,
status VARCHAR(32) NOT NULL,
assigned_to VARCHAR(128),
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_interactions_interaction_id ON interactions (interaction_id);
CREATE INDEX IF NOT EXISTS ix_interactions_status ON interactions (status);
CREATE INDEX IF NOT EXISTS ix_interactions_queue_id ON interactions (queue_id);
CREATE INDEX IF NOT EXISTS ix_interactions_assigned_to ON interactions (assigned_to);
CREATE TABLE IF NOT EXISTS interaction_timelines (
id BIGSERIAL PRIMARY KEY,
interaction_id VARCHAR(64) NOT NULL,
timestamp VARCHAR(64) NOT NULL,
action VARCHAR(128) NOT NULL,
metadata_json TEXT NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS ix_interaction_timelines_interaction_id ON interaction_timelines (interaction_id);
CREATE INDEX IF NOT EXISTS ix_interaction_timelines_timestamp ON interaction_timelines (timestamp);
CREATE TABLE IF NOT EXISTS queues (
id BIGSERIAL PRIMARY KEY,
queue_id VARCHAR(64) NOT NULL UNIQUE,
name VARCHAR(256) NOT NULL,
description TEXT NOT NULL DEFAULT '',
rules_json TEXT NOT NULL DEFAULT '[]',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_queues_queue_id ON queues (queue_id);
CREATE INDEX IF NOT EXISTS ix_queues_name ON queues (name);
CREATE TABLE IF NOT EXISTS routing_counters (
id BIGSERIAL PRIMARY KEY,
channel VARCHAR(32) NOT NULL UNIQUE,
counter INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS ix_routing_counters_channel ON routing_counters (channel);
+72
View File
@@ -0,0 +1,72 @@
-- Core MVP schema (SQLite)
CREATE TABLE IF NOT EXISTS auth_users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL UNIQUE,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
full_name TEXT NOT NULL,
role TEXT NOT NULL,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_auth_users_user_id ON auth_users (user_id);
CREATE INDEX IF NOT EXISTS ix_auth_users_username ON auth_users (username);
CREATE INDEX IF NOT EXISTS ix_auth_users_role ON auth_users (role);
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id TEXT NOT NULL UNIQUE,
display_name TEXT NOT NULL,
phones_json TEXT NOT NULL DEFAULT '[]',
preferred_phone TEXT,
tags_json TEXT NOT NULL DEFAULT '[]',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_customers_customer_id ON customers (customer_id);
CREATE INDEX IF NOT EXISTS ix_customers_display_name ON customers (display_name);
CREATE TABLE IF NOT EXISTS interactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
interaction_id TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL,
subject TEXT NOT NULL,
customer_id TEXT,
queue_id TEXT,
priority INTEGER NOT NULL DEFAULT 3,
status TEXT NOT NULL,
assigned_to TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_interactions_interaction_id ON interactions (interaction_id);
CREATE INDEX IF NOT EXISTS ix_interactions_status ON interactions (status);
CREATE INDEX IF NOT EXISTS ix_interactions_queue_id ON interactions (queue_id);
CREATE INDEX IF NOT EXISTS ix_interactions_assigned_to ON interactions (assigned_to);
CREATE TABLE IF NOT EXISTS interaction_timelines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
interaction_id TEXT NOT NULL,
timestamp TEXT NOT NULL,
action TEXT NOT NULL,
metadata_json TEXT NOT NULL DEFAULT '{}'
);
CREATE INDEX IF NOT EXISTS ix_interaction_timelines_interaction_id ON interaction_timelines (interaction_id);
CREATE INDEX IF NOT EXISTS ix_interaction_timelines_timestamp ON interaction_timelines (timestamp);
CREATE TABLE IF NOT EXISTS queues (
id INTEGER PRIMARY KEY AUTOINCREMENT,
queue_id TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
rules_json TEXT NOT NULL DEFAULT '[]',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_queues_queue_id ON queues (queue_id);
CREATE INDEX IF NOT EXISTS ix_queues_name ON queues (name);
CREATE TABLE IF NOT EXISTS routing_counters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channel TEXT NOT NULL UNIQUE,
counter INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS ix_routing_counters_channel ON routing_counters (channel);
+107
View File
@@ -0,0 +1,107 @@
-- Stage 3+ service schema (PostgreSQL)
CREATE TABLE IF NOT EXISTS audit_events (
id BIGSERIAL PRIMARY KEY,
event_id VARCHAR(64) NOT NULL UNIQUE,
actor VARCHAR(128) NOT NULL,
action VARCHAR(128) NOT NULL,
entity VARCHAR(128) NOT NULL,
metadata_json TEXT NOT NULL DEFAULT '{}',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_audit_events_event_id ON audit_events (event_id);
CREATE INDEX IF NOT EXISTS ix_audit_events_actor ON audit_events (actor);
CREATE INDEX IF NOT EXISTS ix_audit_events_action ON audit_events (action);
CREATE INDEX IF NOT EXISTS ix_audit_events_entity ON audit_events (entity);
CREATE INDEX IF NOT EXISTS ix_audit_events_created_at ON audit_events (created_at);
CREATE TABLE IF NOT EXISTS voice_events (
id BIGSERIAL PRIMARY KEY,
event_id VARCHAR(64) NOT NULL UNIQUE,
event_type VARCHAR(64) NOT NULL,
call_id VARCHAR(128) NOT NULL,
interaction_id VARCHAR(64),
payload_json TEXT NOT NULL DEFAULT '{}',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_voice_events_event_id ON voice_events (event_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_event_type ON voice_events (event_type);
CREATE INDEX IF NOT EXISTS ix_voice_events_call_id ON voice_events (call_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_interaction_id ON voice_events (interaction_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_created_at ON voice_events (created_at);
CREATE TABLE IF NOT EXISTS telegram_messages (
id BIGSERIAL PRIMARY KEY,
message_id VARCHAR(64) NOT NULL UNIQUE,
chat_id VARCHAR(128) NOT NULL,
text TEXT NOT NULL,
customer_external_id VARCHAR(128),
payload_json TEXT NOT NULL DEFAULT '{}',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_message_id ON telegram_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_chat_id ON telegram_messages (chat_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_customer_external_id ON telegram_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_created_at ON telegram_messages (created_at);
CREATE TABLE IF NOT EXISTS kb_categories (
id BIGSERIAL PRIMARY KEY,
category_id VARCHAR(64) NOT NULL UNIQUE,
name VARCHAR(256) NOT NULL,
description TEXT NOT NULL DEFAULT '',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_kb_categories_category_id ON kb_categories (category_id);
CREATE INDEX IF NOT EXISTS ix_kb_categories_name ON kb_categories (name);
CREATE INDEX IF NOT EXISTS ix_kb_categories_created_at ON kb_categories (created_at);
CREATE TABLE IF NOT EXISTS kb_articles (
id BIGSERIAL PRIMARY KEY,
article_id VARCHAR(64) NOT NULL UNIQUE,
category_id VARCHAR(64) NOT NULL,
title VARCHAR(512) NOT NULL,
body TEXT NOT NULL,
tags_json TEXT NOT NULL DEFAULT '[]',
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_kb_articles_article_id ON kb_articles (article_id);
CREATE INDEX IF NOT EXISTS ix_kb_articles_category_id ON kb_articles (category_id);
CREATE INDEX IF NOT EXISTS ix_kb_articles_title ON kb_articles (title);
CREATE INDEX IF NOT EXISTS ix_kb_articles_created_at ON kb_articles (created_at);
CREATE INDEX IF NOT EXISTS ix_kb_articles_updated_at ON kb_articles (updated_at);
CREATE TABLE IF NOT EXISTS reporting_events (
id BIGSERIAL PRIMARY KEY,
queue_id VARCHAR(64) NOT NULL,
answered BOOLEAN NOT NULL DEFAULT FALSE,
wait_seconds INTEGER NOT NULL DEFAULT 0,
handle_seconds INTEGER NOT NULL DEFAULT 0,
abandoned BOOLEAN NOT NULL DEFAULT FALSE,
resolved_first_contact BOOLEAN NOT NULL DEFAULT FALSE,
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_reporting_events_queue_id ON reporting_events (queue_id);
CREATE INDEX IF NOT EXISTS ix_reporting_events_created_at ON reporting_events (created_at);
CREATE TABLE IF NOT EXISTS supervisor_agent_states (
id BIGSERIAL PRIMARY KEY,
agent_id VARCHAR(128) NOT NULL UNIQUE,
state VARCHAR(32) NOT NULL,
queue_id VARCHAR(64),
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_agent_id ON supervisor_agent_states (agent_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_state ON supervisor_agent_states (state);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_queue_id ON supervisor_agent_states (queue_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_updated_at ON supervisor_agent_states (updated_at);
CREATE TABLE IF NOT EXISTS supervisor_queue_snapshots (
id BIGSERIAL PRIMARY KEY,
queue_id VARCHAR(64) NOT NULL UNIQUE,
in_queue INTEGER NOT NULL DEFAULT 0,
avg_wait_seconds INTEGER NOT NULL DEFAULT 0,
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_supervisor_queue_snapshots_queue_id ON supervisor_queue_snapshots (queue_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_queue_snapshots_updated_at ON supervisor_queue_snapshots (updated_at);
+107
View File
@@ -0,0 +1,107 @@
-- Stage 3+ service schema (SQLite)
CREATE TABLE IF NOT EXISTS audit_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id TEXT NOT NULL UNIQUE,
actor TEXT NOT NULL,
action TEXT NOT NULL,
entity TEXT NOT NULL,
metadata_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_audit_events_event_id ON audit_events (event_id);
CREATE INDEX IF NOT EXISTS ix_audit_events_actor ON audit_events (actor);
CREATE INDEX IF NOT EXISTS ix_audit_events_action ON audit_events (action);
CREATE INDEX IF NOT EXISTS ix_audit_events_entity ON audit_events (entity);
CREATE INDEX IF NOT EXISTS ix_audit_events_created_at ON audit_events (created_at);
CREATE TABLE IF NOT EXISTS voice_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id TEXT NOT NULL UNIQUE,
event_type TEXT NOT NULL,
call_id TEXT NOT NULL,
interaction_id TEXT,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_voice_events_event_id ON voice_events (event_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_event_type ON voice_events (event_type);
CREATE INDEX IF NOT EXISTS ix_voice_events_call_id ON voice_events (call_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_interaction_id ON voice_events (interaction_id);
CREATE INDEX IF NOT EXISTS ix_voice_events_created_at ON voice_events (created_at);
CREATE TABLE IF NOT EXISTS telegram_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT NOT NULL UNIQUE,
chat_id TEXT NOT NULL,
text TEXT NOT NULL,
customer_external_id TEXT,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_message_id ON telegram_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_chat_id ON telegram_messages (chat_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_customer_external_id ON telegram_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_telegram_messages_created_at ON telegram_messages (created_at);
CREATE TABLE IF NOT EXISTS kb_categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_kb_categories_category_id ON kb_categories (category_id);
CREATE INDEX IF NOT EXISTS ix_kb_categories_name ON kb_categories (name);
CREATE INDEX IF NOT EXISTS ix_kb_categories_created_at ON kb_categories (created_at);
CREATE TABLE IF NOT EXISTS kb_articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
article_id TEXT NOT NULL UNIQUE,
category_id TEXT NOT NULL,
title TEXT NOT NULL,
body TEXT NOT NULL,
tags_json TEXT NOT NULL DEFAULT '[]',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_kb_articles_article_id ON kb_articles (article_id);
CREATE INDEX IF NOT EXISTS ix_kb_articles_category_id ON kb_articles (category_id);
CREATE INDEX IF NOT EXISTS ix_kb_articles_title ON kb_articles (title);
CREATE INDEX IF NOT EXISTS ix_kb_articles_created_at ON kb_articles (created_at);
CREATE INDEX IF NOT EXISTS ix_kb_articles_updated_at ON kb_articles (updated_at);
CREATE TABLE IF NOT EXISTS reporting_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
queue_id TEXT NOT NULL,
answered INTEGER NOT NULL DEFAULT 0,
wait_seconds INTEGER NOT NULL DEFAULT 0,
handle_seconds INTEGER NOT NULL DEFAULT 0,
abandoned INTEGER NOT NULL DEFAULT 0,
resolved_first_contact INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_reporting_events_queue_id ON reporting_events (queue_id);
CREATE INDEX IF NOT EXISTS ix_reporting_events_created_at ON reporting_events (created_at);
CREATE TABLE IF NOT EXISTS supervisor_agent_states (
id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id TEXT NOT NULL UNIQUE,
state TEXT NOT NULL,
queue_id TEXT,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_agent_id ON supervisor_agent_states (agent_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_state ON supervisor_agent_states (state);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_queue_id ON supervisor_agent_states (queue_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_agent_states_updated_at ON supervisor_agent_states (updated_at);
CREATE TABLE IF NOT EXISTS supervisor_queue_snapshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
queue_id TEXT NOT NULL UNIQUE,
in_queue INTEGER NOT NULL DEFAULT 0,
avg_wait_seconds INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_supervisor_queue_snapshots_queue_id ON supervisor_queue_snapshots (queue_id);
CREATE INDEX IF NOT EXISTS ix_supervisor_queue_snapshots_updated_at ON supervisor_queue_snapshots (updated_at);
@@ -0,0 +1,40 @@
-- Wave 2 Track 1 auth/OIDC schema (PostgreSQL)
CREATE TABLE IF NOT EXISTS auth_external_identities (
id SERIAL PRIMARY KEY,
provider VARCHAR(64) NOT NULL,
external_subject VARCHAR(256) NOT NULL,
username VARCHAR(128) NOT NULL,
email VARCHAR(256),
full_name VARCHAR(256),
role VARCHAR(32) NOT NULL,
linked_user_id VARCHAR(64),
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL,
last_login_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_provider ON auth_external_identities (provider);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_external_subject ON auth_external_identities (external_subject);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_username ON auth_external_identities (username);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_email ON auth_external_identities (email);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_role ON auth_external_identities (role);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_linked_user_id ON auth_external_identities (linked_user_id);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_created_at ON auth_external_identities (created_at);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_updated_at ON auth_external_identities (updated_at);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_last_login_at ON auth_external_identities (last_login_at);
CREATE TABLE IF NOT EXISTS auth_oidc_states (
id SERIAL PRIMARY KEY,
state VARCHAR(128) NOT NULL UNIQUE,
nonce VARCHAR(128) NOT NULL,
code_verifier VARCHAR(256) NOT NULL,
redirect_uri VARCHAR(512) NOT NULL,
return_mode VARCHAR(32) NOT NULL DEFAULT 'popup',
created_at VARCHAR(64) NOT NULL,
expires_at VARCHAR(64) NOT NULL,
consumed_at VARCHAR(64)
);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_state ON auth_oidc_states (state);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_created_at ON auth_oidc_states (created_at);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_expires_at ON auth_oidc_states (expires_at);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_consumed_at ON auth_oidc_states (consumed_at);
+40
View File
@@ -0,0 +1,40 @@
-- Wave 2 Track 1 auth/OIDC schema (SQLite)
CREATE TABLE IF NOT EXISTS auth_external_identities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
provider TEXT NOT NULL,
external_subject TEXT NOT NULL,
username TEXT NOT NULL,
email TEXT,
full_name TEXT,
role TEXT NOT NULL,
linked_user_id TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
last_login_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_provider ON auth_external_identities (provider);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_external_subject ON auth_external_identities (external_subject);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_username ON auth_external_identities (username);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_email ON auth_external_identities (email);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_role ON auth_external_identities (role);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_linked_user_id ON auth_external_identities (linked_user_id);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_created_at ON auth_external_identities (created_at);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_updated_at ON auth_external_identities (updated_at);
CREATE INDEX IF NOT EXISTS ix_auth_external_identities_last_login_at ON auth_external_identities (last_login_at);
CREATE TABLE IF NOT EXISTS auth_oidc_states (
id INTEGER PRIMARY KEY AUTOINCREMENT,
state TEXT NOT NULL UNIQUE,
nonce TEXT NOT NULL,
code_verifier TEXT NOT NULL,
redirect_uri TEXT NOT NULL,
return_mode TEXT NOT NULL DEFAULT 'popup',
created_at TEXT NOT NULL,
expires_at TEXT NOT NULL,
consumed_at TEXT
);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_state ON auth_oidc_states (state);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_created_at ON auth_oidc_states (created_at);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_expires_at ON auth_oidc_states (expires_at);
CREATE INDEX IF NOT EXISTS ix_auth_oidc_states_consumed_at ON auth_oidc_states (consumed_at);
+21
View File
@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS webchat_messages (
id SERIAL PRIMARY KEY,
message_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
text TEXT NOT NULL,
visitor_name TEXT NULL,
customer_external_id TEXT NULL,
interaction_id TEXT NULL,
queue_id TEXT NULL,
priority INTEGER NOT NULL DEFAULT 3,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_message_id ON webchat_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_session_id ON webchat_messages (session_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_customer_external_id ON webchat_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_interaction_id ON webchat_messages (interaction_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_queue_id ON webchat_messages (queue_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_priority ON webchat_messages (priority);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_created_at ON webchat_messages (created_at);
+21
View File
@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS webchat_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
text TEXT NOT NULL,
visitor_name TEXT NULL,
customer_external_id TEXT NULL,
interaction_id TEXT NULL,
queue_id TEXT NULL,
priority INTEGER NOT NULL DEFAULT 3,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_message_id ON webchat_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_session_id ON webchat_messages (session_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_customer_external_id ON webchat_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_interaction_id ON webchat_messages (interaction_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_queue_id ON webchat_messages (queue_id);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_priority ON webchat_messages (priority);
CREATE INDEX IF NOT EXISTS ix_webchat_messages_created_at ON webchat_messages (created_at);
+22
View File
@@ -0,0 +1,22 @@
CREATE TABLE IF NOT EXISTS email_messages (
id SERIAL PRIMARY KEY,
message_id TEXT NOT NULL UNIQUE,
from_email TEXT NOT NULL,
subject TEXT NOT NULL,
body TEXT NOT NULL,
customer_external_id TEXT NULL,
interaction_id TEXT NULL,
queue_id TEXT NULL,
priority INTEGER NOT NULL DEFAULT 3,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_email_messages_message_id ON email_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_from_email ON email_messages (from_email);
CREATE INDEX IF NOT EXISTS ix_email_messages_subject ON email_messages (subject);
CREATE INDEX IF NOT EXISTS ix_email_messages_customer_external_id ON email_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_interaction_id ON email_messages (interaction_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_queue_id ON email_messages (queue_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_priority ON email_messages (priority);
CREATE INDEX IF NOT EXISTS ix_email_messages_created_at ON email_messages (created_at);
+22
View File
@@ -0,0 +1,22 @@
CREATE TABLE IF NOT EXISTS email_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT NOT NULL UNIQUE,
from_email TEXT NOT NULL,
subject TEXT NOT NULL,
body TEXT NOT NULL,
customer_external_id TEXT NULL,
interaction_id TEXT NULL,
queue_id TEXT NULL,
priority INTEGER NOT NULL DEFAULT 3,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_email_messages_message_id ON email_messages (message_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_from_email ON email_messages (from_email);
CREATE INDEX IF NOT EXISTS ix_email_messages_subject ON email_messages (subject);
CREATE INDEX IF NOT EXISTS ix_email_messages_customer_external_id ON email_messages (customer_external_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_interaction_id ON email_messages (interaction_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_queue_id ON email_messages (queue_id);
CREATE INDEX IF NOT EXISTS ix_email_messages_priority ON email_messages (priority);
CREATE INDEX IF NOT EXISTS ix_email_messages_created_at ON email_messages (created_at);
@@ -0,0 +1,33 @@
CREATE TABLE IF NOT EXISTS call_recordings (
id SERIAL PRIMARY KEY,
recording_id TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL,
call_id TEXT NOT NULL,
interaction_id TEXT NULL,
source_event_id TEXT NULL,
file_name TEXT NOT NULL,
storage_backend TEXT NOT NULL,
storage_path TEXT NOT NULL,
mime_type TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
duration_seconds INTEGER NULL,
checksum_sha256 TEXT NOT NULL,
status TEXT NOT NULL,
recorded_at TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
archived_at TEXT NULL
);
CREATE INDEX IF NOT EXISTS ix_call_recordings_recording_id ON call_recordings (recording_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_channel ON call_recordings (channel);
CREATE INDEX IF NOT EXISTS ix_call_recordings_call_id ON call_recordings (call_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_interaction_id ON call_recordings (interaction_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_source_event_id ON call_recordings (source_event_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_storage_backend ON call_recordings (storage_backend);
CREATE INDEX IF NOT EXISTS ix_call_recordings_checksum_sha256 ON call_recordings (checksum_sha256);
CREATE INDEX IF NOT EXISTS ix_call_recordings_status ON call_recordings (status);
CREATE INDEX IF NOT EXISTS ix_call_recordings_recorded_at ON call_recordings (recorded_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_created_at ON call_recordings (created_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_updated_at ON call_recordings (updated_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_archived_at ON call_recordings (archived_at);
+33
View File
@@ -0,0 +1,33 @@
CREATE TABLE IF NOT EXISTS call_recordings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
recording_id TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL,
call_id TEXT NOT NULL,
interaction_id TEXT NULL,
source_event_id TEXT NULL,
file_name TEXT NOT NULL,
storage_backend TEXT NOT NULL,
storage_path TEXT NOT NULL,
mime_type TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
duration_seconds INTEGER NULL,
checksum_sha256 TEXT NOT NULL,
status TEXT NOT NULL,
recorded_at TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
archived_at TEXT NULL
);
CREATE INDEX IF NOT EXISTS ix_call_recordings_recording_id ON call_recordings (recording_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_channel ON call_recordings (channel);
CREATE INDEX IF NOT EXISTS ix_call_recordings_call_id ON call_recordings (call_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_interaction_id ON call_recordings (interaction_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_source_event_id ON call_recordings (source_event_id);
CREATE INDEX IF NOT EXISTS ix_call_recordings_storage_backend ON call_recordings (storage_backend);
CREATE INDEX IF NOT EXISTS ix_call_recordings_checksum_sha256 ON call_recordings (checksum_sha256);
CREATE INDEX IF NOT EXISTS ix_call_recordings_status ON call_recordings (status);
CREATE INDEX IF NOT EXISTS ix_call_recordings_recorded_at ON call_recordings (recorded_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_created_at ON call_recordings (created_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_updated_at ON call_recordings (updated_at);
CREATE INDEX IF NOT EXISTS ix_call_recordings_archived_at ON call_recordings (archived_at);
+51
View File
@@ -0,0 +1,51 @@
CREATE TABLE IF NOT EXISTS ivr_flows (
id SERIAL PRIMARY KEY,
flow_id TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
channel TEXT NOT NULL,
queue_id TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
entry_node_id TEXT NOT NULL,
flow_json TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_flow_id ON ivr_flows (flow_id);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_name ON ivr_flows (name);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_channel ON ivr_flows (channel);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_queue_id ON ivr_flows (queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_is_active ON ivr_flows (is_active);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_created_at ON ivr_flows (created_at);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_updated_at ON ivr_flows (updated_at);
CREATE TABLE IF NOT EXISTS ivr_sessions (
id SERIAL PRIMARY KEY,
session_id TEXT NOT NULL UNIQUE,
call_id TEXT NOT NULL,
interaction_id TEXT NULL,
flow_id TEXT NOT NULL,
queue_id TEXT NOT NULL,
current_node_id TEXT NOT NULL,
entered_digits_json TEXT NOT NULL DEFAULT '[]',
status TEXT NOT NULL,
outcome_code TEXT NULL,
resolved_queue_id TEXT NULL,
completed_at TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_session_id ON ivr_sessions (session_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_call_id ON ivr_sessions (call_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_interaction_id ON ivr_sessions (interaction_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_flow_id ON ivr_sessions (flow_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_queue_id ON ivr_sessions (queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_status ON ivr_sessions (status);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_outcome_code ON ivr_sessions (outcome_code);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_resolved_queue_id ON ivr_sessions (resolved_queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_completed_at ON ivr_sessions (completed_at);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_created_at ON ivr_sessions (created_at);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_updated_at ON ivr_sessions (updated_at);
+51
View File
@@ -0,0 +1,51 @@
CREATE TABLE IF NOT EXISTS ivr_flows (
id INTEGER PRIMARY KEY AUTOINCREMENT,
flow_id TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
channel TEXT NOT NULL,
queue_id TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
is_active INTEGER NOT NULL DEFAULT 1,
entry_node_id TEXT NOT NULL,
flow_json TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_flow_id ON ivr_flows (flow_id);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_name ON ivr_flows (name);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_channel ON ivr_flows (channel);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_queue_id ON ivr_flows (queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_is_active ON ivr_flows (is_active);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_created_at ON ivr_flows (created_at);
CREATE INDEX IF NOT EXISTS ix_ivr_flows_updated_at ON ivr_flows (updated_at);
CREATE TABLE IF NOT EXISTS ivr_sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL UNIQUE,
call_id TEXT NOT NULL,
interaction_id TEXT NULL,
flow_id TEXT NOT NULL,
queue_id TEXT NOT NULL,
current_node_id TEXT NOT NULL,
entered_digits_json TEXT NOT NULL DEFAULT '[]',
status TEXT NOT NULL,
outcome_code TEXT NULL,
resolved_queue_id TEXT NULL,
completed_at TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_session_id ON ivr_sessions (session_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_call_id ON ivr_sessions (call_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_interaction_id ON ivr_sessions (interaction_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_flow_id ON ivr_sessions (flow_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_queue_id ON ivr_sessions (queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_status ON ivr_sessions (status);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_outcome_code ON ivr_sessions (outcome_code);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_resolved_queue_id ON ivr_sessions (resolved_queue_id);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_completed_at ON ivr_sessions (completed_at);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_created_at ON ivr_sessions (created_at);
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_updated_at ON ivr_sessions (updated_at);
@@ -0,0 +1,5 @@
ALTER TABLE reporting_events ADD COLUMN IF NOT EXISTS channel VARCHAR(32) NOT NULL DEFAULT 'voice';
ALTER TABLE reporting_events ADD COLUMN IF NOT EXISTS agent_id VARCHAR(128) NULL;
CREATE INDEX IF NOT EXISTS ix_reporting_events_channel ON reporting_events (channel);
CREATE INDEX IF NOT EXISTS ix_reporting_events_agent_id ON reporting_events (agent_id);
@@ -0,0 +1,5 @@
ALTER TABLE reporting_events ADD COLUMN channel TEXT NOT NULL DEFAULT 'voice';
ALTER TABLE reporting_events ADD COLUMN agent_id TEXT NULL;
CREATE INDEX IF NOT EXISTS ix_reporting_events_channel ON reporting_events (channel);
CREATE INDEX IF NOT EXISTS ix_reporting_events_agent_id ON reporting_events (agent_id);
@@ -0,0 +1,55 @@
CREATE TABLE IF NOT EXISTS event_outbox (
id SERIAL PRIMARY KEY,
event_id VARCHAR(64) NOT NULL UNIQUE,
event_type VARCHAR(128) NOT NULL,
event_version INTEGER NOT NULL DEFAULT 1,
producer_service VARCHAR(128) NOT NULL,
entity_type VARCHAR(128) NOT NULL,
entity_id VARCHAR(128) NOT NULL,
correlation_id VARCHAR(128) NULL,
routing_key VARCHAR(128) NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
status VARCHAR(32) NOT NULL,
attempt_count INTEGER NOT NULL DEFAULT 0,
last_error TEXT NULL,
available_at VARCHAR(64) NOT NULL,
published_at VARCHAR(64) NULL,
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_event_outbox_event_id ON event_outbox (event_id);
CREATE INDEX IF NOT EXISTS ix_event_outbox_event_type ON event_outbox (event_type);
CREATE INDEX IF NOT EXISTS ix_event_outbox_status ON event_outbox (status);
CREATE INDEX IF NOT EXISTS ix_event_outbox_available_at ON event_outbox (available_at);
CREATE INDEX IF NOT EXISTS ix_event_outbox_entity_type ON event_outbox (entity_type);
CREATE INDEX IF NOT EXISTS ix_event_outbox_entity_id ON event_outbox (entity_id);
CREATE TABLE IF NOT EXISTS event_inbox (
id SERIAL PRIMARY KEY,
consumer_name VARCHAR(128) NOT NULL,
event_id VARCHAR(64) NOT NULL,
event_type VARCHAR(128) NOT NULL,
processed_at VARCHAR(64) NOT NULL,
status VARCHAR(32) NOT NULL,
notes TEXT NULL
);
CREATE INDEX IF NOT EXISTS ix_event_inbox_consumer_name ON event_inbox (consumer_name);
CREATE INDEX IF NOT EXISTS ix_event_inbox_event_id ON event_inbox (event_id);
CREATE INDEX IF NOT EXISTS ix_event_inbox_event_type ON event_inbox (event_type);
CREATE UNIQUE INDEX IF NOT EXISTS uq_event_inbox_consumer_event ON event_inbox (consumer_name, event_id);
CREATE TABLE IF NOT EXISTS reporting_event_log (
id SERIAL PRIMARY KEY,
event_id VARCHAR(64) NOT NULL,
event_type VARCHAR(128) NOT NULL,
queue_id VARCHAR(64) NULL,
channel VARCHAR(32) NULL,
interaction_id VARCHAR(64) NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_event_id ON reporting_event_log (event_id);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_event_type ON reporting_event_log (event_type);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_queue_id ON reporting_event_log (queue_id);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_channel ON reporting_event_log (channel);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_interaction_id ON reporting_event_log (interaction_id);
+55
View File
@@ -0,0 +1,55 @@
CREATE TABLE IF NOT EXISTS event_outbox (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id TEXT NOT NULL UNIQUE,
event_type TEXT NOT NULL,
event_version INTEGER NOT NULL DEFAULT 1,
producer_service TEXT NOT NULL,
entity_type TEXT NOT NULL,
entity_id TEXT NOT NULL,
correlation_id TEXT NULL,
routing_key TEXT NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
status TEXT NOT NULL,
attempt_count INTEGER NOT NULL DEFAULT 0,
last_error TEXT NULL,
available_at TEXT NOT NULL,
published_at TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_event_outbox_event_id ON event_outbox (event_id);
CREATE INDEX IF NOT EXISTS ix_event_outbox_event_type ON event_outbox (event_type);
CREATE INDEX IF NOT EXISTS ix_event_outbox_status ON event_outbox (status);
CREATE INDEX IF NOT EXISTS ix_event_outbox_available_at ON event_outbox (available_at);
CREATE INDEX IF NOT EXISTS ix_event_outbox_entity_type ON event_outbox (entity_type);
CREATE INDEX IF NOT EXISTS ix_event_outbox_entity_id ON event_outbox (entity_id);
CREATE TABLE IF NOT EXISTS event_inbox (
id INTEGER PRIMARY KEY AUTOINCREMENT,
consumer_name TEXT NOT NULL,
event_id TEXT NOT NULL,
event_type TEXT NOT NULL,
processed_at TEXT NOT NULL,
status TEXT NOT NULL,
notes TEXT NULL
);
CREATE INDEX IF NOT EXISTS ix_event_inbox_consumer_name ON event_inbox (consumer_name);
CREATE INDEX IF NOT EXISTS ix_event_inbox_event_id ON event_inbox (event_id);
CREATE INDEX IF NOT EXISTS ix_event_inbox_event_type ON event_inbox (event_type);
CREATE UNIQUE INDEX IF NOT EXISTS uq_event_inbox_consumer_event ON event_inbox (consumer_name, event_id);
CREATE TABLE IF NOT EXISTS reporting_event_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id TEXT NOT NULL,
event_type TEXT NOT NULL,
queue_id TEXT NULL,
channel TEXT NULL,
interaction_id TEXT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_event_id ON reporting_event_log (event_id);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_event_type ON reporting_event_log (event_type);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_queue_id ON reporting_event_log (queue_id);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_channel ON reporting_event_log (channel);
CREATE INDEX IF NOT EXISTS ix_reporting_event_log_interaction_id ON reporting_event_log (interaction_id);
@@ -0,0 +1,48 @@
CREATE TABLE IF NOT EXISTS asterisk_event_log (
id SERIAL PRIMARY KEY,
bridge_event_id VARCHAR(64) NOT NULL UNIQUE,
ami_event_name VARCHAR(128) NOT NULL,
call_id VARCHAR(128) NOT NULL,
linked_id VARCHAR(128),
interaction_id VARCHAR(64),
recording_id VARCHAR(64),
forward_status VARCHAR(32) NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
last_error TEXT,
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_bridge_event_id ON asterisk_event_log(bridge_event_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_ami_event_name ON asterisk_event_log(ami_event_name);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_call_id ON asterisk_event_log(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_linked_id ON asterisk_event_log(linked_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_interaction_id ON asterisk_event_log(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_recording_id ON asterisk_event_log(recording_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_forward_status ON asterisk_event_log(forward_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_created_at ON asterisk_event_log(created_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_updated_at ON asterisk_event_log(updated_at);
CREATE TABLE IF NOT EXISTS asterisk_call_links (
id SERIAL PRIMARY KEY,
call_id VARCHAR(128) NOT NULL UNIQUE,
linked_id VARCHAR(128),
queue_code VARCHAR(64) NOT NULL,
queue_id VARCHAR(64) NOT NULL,
interaction_id VARCHAR(64) NOT NULL,
caller_number VARCHAR(64),
caller_name VARCHAR(128),
status VARCHAR(32) NOT NULL,
started_at VARCHAR(64) NOT NULL,
ended_at VARCHAR(64),
updated_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_call_id ON asterisk_call_links(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_linked_id ON asterisk_call_links(linked_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_queue_code ON asterisk_call_links(queue_code);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_queue_id ON asterisk_call_links(queue_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_interaction_id ON asterisk_call_links(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_caller_number ON asterisk_call_links(caller_number);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_status ON asterisk_call_links(status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_started_at ON asterisk_call_links(started_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ended_at ON asterisk_call_links(ended_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_updated_at ON asterisk_call_links(updated_at);
@@ -0,0 +1,48 @@
CREATE TABLE IF NOT EXISTS asterisk_event_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
bridge_event_id TEXT NOT NULL UNIQUE,
ami_event_name TEXT NOT NULL,
call_id TEXT NOT NULL,
linked_id TEXT,
interaction_id TEXT,
recording_id TEXT,
forward_status TEXT NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
last_error TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_bridge_event_id ON asterisk_event_log(bridge_event_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_ami_event_name ON asterisk_event_log(ami_event_name);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_call_id ON asterisk_event_log(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_linked_id ON asterisk_event_log(linked_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_interaction_id ON asterisk_event_log(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_recording_id ON asterisk_event_log(recording_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_forward_status ON asterisk_event_log(forward_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_created_at ON asterisk_event_log(created_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_updated_at ON asterisk_event_log(updated_at);
CREATE TABLE IF NOT EXISTS asterisk_call_links (
id INTEGER PRIMARY KEY AUTOINCREMENT,
call_id TEXT NOT NULL UNIQUE,
linked_id TEXT,
queue_code TEXT NOT NULL,
queue_id TEXT NOT NULL,
interaction_id TEXT NOT NULL,
caller_number TEXT,
caller_name TEXT,
status TEXT NOT NULL,
started_at TEXT NOT NULL,
ended_at TEXT,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_call_id ON asterisk_call_links(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_linked_id ON asterisk_call_links(linked_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_queue_code ON asterisk_call_links(queue_code);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_queue_id ON asterisk_call_links(queue_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_interaction_id ON asterisk_call_links(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_caller_number ON asterisk_call_links(caller_number);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_status ON asterisk_call_links(status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_started_at ON asterisk_call_links(started_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ended_at ON asterisk_call_links(ended_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_updated_at ON asterisk_call_links(updated_at);
@@ -0,0 +1,44 @@
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS telephony_status VARCHAR(32) NOT NULL DEFAULT 'ringing';
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS claimed_by_user VARCHAR(128);
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS claimed_at VARCHAR(64);
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS operator_extension VARCHAR(64);
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS channel_name VARCHAR(256);
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS connected_at VARCHAR(64);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_telephony_status ON asterisk_call_links(telephony_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_claimed_by_user ON asterisk_call_links(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_claimed_at ON asterisk_call_links(claimed_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_operator_extension ON asterisk_call_links(operator_extension);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_channel_name ON asterisk_call_links(channel_name);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_connected_at ON asterisk_call_links(connected_at);
UPDATE asterisk_call_links
SET telephony_status = CASE
WHEN status = 'ended' THEN 'ended'
ELSE 'ringing'
END
WHERE telephony_status IS NULL OR telephony_status = '';
CREATE TABLE IF NOT EXISTS asterisk_call_action_log (
id SERIAL PRIMARY KEY,
action_id VARCHAR(64) NOT NULL UNIQUE,
call_id VARCHAR(128) NOT NULL,
interaction_id VARCHAR(64),
action_type VARCHAR(64) NOT NULL,
actor_user VARCHAR(128) NOT NULL,
actor_role VARCHAR(32) NOT NULL,
request_json TEXT NOT NULL DEFAULT '{}',
result_status VARCHAR(32) NOT NULL,
ami_action_id VARCHAR(64),
error TEXT,
created_at VARCHAR(64) NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_action_id ON asterisk_call_action_log(action_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_call_id ON asterisk_call_action_log(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_interaction_id ON asterisk_call_action_log(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_action_type ON asterisk_call_action_log(action_type);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_actor_user ON asterisk_call_action_log(actor_user);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_actor_role ON asterisk_call_action_log(actor_role);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_result_status ON asterisk_call_action_log(result_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_ami_action_id ON asterisk_call_action_log(ami_action_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_created_at ON asterisk_call_action_log(created_at);
@@ -0,0 +1,44 @@
ALTER TABLE asterisk_call_links ADD COLUMN telephony_status TEXT NOT NULL DEFAULT 'ringing';
ALTER TABLE asterisk_call_links ADD COLUMN claimed_by_user TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN claimed_at TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN operator_extension TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN channel_name TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN connected_at TEXT;
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_telephony_status ON asterisk_call_links(telephony_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_claimed_by_user ON asterisk_call_links(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_claimed_at ON asterisk_call_links(claimed_at);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_operator_extension ON asterisk_call_links(operator_extension);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_channel_name ON asterisk_call_links(channel_name);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_connected_at ON asterisk_call_links(connected_at);
UPDATE asterisk_call_links
SET telephony_status = CASE
WHEN status = 'ended' THEN 'ended'
ELSE 'ringing'
END
WHERE telephony_status IS NULL OR telephony_status = '';
CREATE TABLE IF NOT EXISTS asterisk_call_action_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
action_id TEXT NOT NULL UNIQUE,
call_id TEXT NOT NULL,
interaction_id TEXT,
action_type TEXT NOT NULL,
actor_user TEXT NOT NULL,
actor_role TEXT NOT NULL,
request_json TEXT NOT NULL DEFAULT '{}',
result_status TEXT NOT NULL,
ami_action_id TEXT,
error TEXT,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_action_id ON asterisk_call_action_log(action_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_call_id ON asterisk_call_action_log(call_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_interaction_id ON asterisk_call_action_log(interaction_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_action_type ON asterisk_call_action_log(action_type);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_actor_user ON asterisk_call_action_log(actor_user);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_actor_role ON asterisk_call_action_log(actor_role);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_result_status ON asterisk_call_action_log(result_status);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_ami_action_id ON asterisk_call_action_log(ami_action_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_action_log_created_at ON asterisk_call_action_log(created_at);
@@ -0,0 +1,44 @@
CREATE TABLE IF NOT EXISTS telegram_threads (
id SERIAL PRIMARY KEY,
thread_id TEXT NOT NULL UNIQUE,
chat_id TEXT NOT NULL UNIQUE,
interaction_id TEXT NOT NULL,
telegram_user_id TEXT,
username TEXT,
display_name TEXT,
queue_id TEXT,
status TEXT NOT NULL,
claimed_by_user TEXT,
claimed_at TEXT,
last_message_at TEXT NOT NULL,
last_message_preview TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_thread_id ON telegram_threads(thread_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_chat_id ON telegram_threads(chat_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_interaction_id ON telegram_threads(interaction_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_telegram_user_id ON telegram_threads(telegram_user_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_username ON telegram_threads(username);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_display_name ON telegram_threads(display_name);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_queue_id ON telegram_threads(queue_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_status ON telegram_threads(status);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_claimed_by_user ON telegram_threads(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_claimed_at ON telegram_threads(claimed_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_last_message_at ON telegram_threads(last_message_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_created_at ON telegram_threads(created_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_updated_at ON telegram_threads(updated_at);
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS thread_id TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS interaction_id TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS direction TEXT NOT NULL DEFAULT 'inbound';
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS telegram_message_id_external TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS operator_user TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS delivery_status TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_messages_thread_id ON telegram_messages(thread_id);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_interaction_id ON telegram_messages(interaction_id);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_direction ON telegram_messages(direction);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_external_id ON telegram_messages(telegram_message_id_external);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_operator_user ON telegram_messages(operator_user);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_delivery_status ON telegram_messages(delivery_status);
@@ -0,0 +1,44 @@
CREATE TABLE IF NOT EXISTS telegram_threads (
id INTEGER PRIMARY KEY AUTOINCREMENT,
thread_id TEXT NOT NULL UNIQUE,
chat_id TEXT NOT NULL UNIQUE,
interaction_id TEXT NOT NULL,
telegram_user_id TEXT,
username TEXT,
display_name TEXT,
queue_id TEXT,
status TEXT NOT NULL,
claimed_by_user TEXT,
claimed_at TEXT,
last_message_at TEXT NOT NULL,
last_message_preview TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_thread_id ON telegram_threads(thread_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_chat_id ON telegram_threads(chat_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_interaction_id ON telegram_threads(interaction_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_telegram_user_id ON telegram_threads(telegram_user_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_username ON telegram_threads(username);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_display_name ON telegram_threads(display_name);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_queue_id ON telegram_threads(queue_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_status ON telegram_threads(status);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_claimed_by_user ON telegram_threads(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_claimed_at ON telegram_threads(claimed_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_last_message_at ON telegram_threads(last_message_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_created_at ON telegram_threads(created_at);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_updated_at ON telegram_threads(updated_at);
ALTER TABLE telegram_messages ADD COLUMN thread_id TEXT;
ALTER TABLE telegram_messages ADD COLUMN interaction_id TEXT;
ALTER TABLE telegram_messages ADD COLUMN direction TEXT NOT NULL DEFAULT 'inbound';
ALTER TABLE telegram_messages ADD COLUMN telegram_message_id_external TEXT;
ALTER TABLE telegram_messages ADD COLUMN operator_user TEXT;
ALTER TABLE telegram_messages ADD COLUMN delivery_status TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_messages_thread_id ON telegram_messages(thread_id);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_interaction_id ON telegram_messages(interaction_id);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_direction ON telegram_messages(direction);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_external_id ON telegram_messages(telegram_message_id_external);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_operator_user ON telegram_messages(operator_user);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_delivery_status ON telegram_messages(delivery_status);
@@ -0,0 +1,6 @@
ALTER TABLE voice_events ADD COLUMN IF NOT EXISTS source_event_id VARCHAR(64);
CREATE UNIQUE INDEX IF NOT EXISTS ix_voice_events_source_event_id ON voice_events(source_event_id);
DROP INDEX IF EXISTS ix_call_recordings_source_event_id;
CREATE UNIQUE INDEX IF NOT EXISTS ix_call_recordings_source_event_id ON call_recordings(source_event_id);
@@ -0,0 +1,6 @@
ALTER TABLE voice_events ADD COLUMN source_event_id TEXT;
CREATE UNIQUE INDEX IF NOT EXISTS ix_voice_events_source_event_id ON voice_events(source_event_id);
DROP INDEX IF EXISTS ix_call_recordings_source_event_id;
CREATE UNIQUE INDEX IF NOT EXISTS ix_call_recordings_source_event_id ON call_recordings(source_event_id);
@@ -0,0 +1,123 @@
CREATE TABLE IF NOT EXISTS customer_external_identities (
id SERIAL PRIMARY KEY,
identity_id TEXT NOT NULL UNIQUE,
customer_id TEXT NOT NULL,
channel TEXT NOT NULL,
external_subject TEXT NOT NULL,
display_name_snapshot TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ix_customer_external_identities_channel_subject_unique
ON customer_external_identities(channel, external_subject);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_identity_id ON customer_external_identities(identity_id);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_customer_id ON customer_external_identities(customer_id);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_channel ON customer_external_identities(channel);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_external_subject ON customer_external_identities(external_subject);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_created_at ON customer_external_identities(created_at);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_updated_at ON customer_external_identities(updated_at);
CREATE TABLE IF NOT EXISTS ai_sessions (
id SERIAL PRIMARY KEY,
session_id TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL,
thread_id TEXT,
interaction_id TEXT,
customer_id TEXT,
agent_profile TEXT NOT NULL DEFAULT 'telegram_support',
language TEXT,
status TEXT NOT NULL DEFAULT 'active',
summary_text TEXT NOT NULL DEFAULT '',
last_user_message_id TEXT,
last_ai_message_id TEXT,
handoff_reason TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
closed_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_session_id ON ai_sessions(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_channel ON ai_sessions(channel);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_thread_id ON ai_sessions(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_interaction_id ON ai_sessions(interaction_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_customer_id ON ai_sessions(customer_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_agent_profile ON ai_sessions(agent_profile);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_language ON ai_sessions(language);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_status ON ai_sessions(status);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_last_user_message_id ON ai_sessions(last_user_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_last_ai_message_id ON ai_sessions(last_ai_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_created_at ON ai_sessions(created_at);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_updated_at ON ai_sessions(updated_at);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_closed_at ON ai_sessions(closed_at);
CREATE TABLE IF NOT EXISTS ai_jobs (
id SERIAL PRIMARY KEY,
job_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
thread_id TEXT NOT NULL,
trigger_message_id TEXT,
status TEXT NOT NULL DEFAULT 'pending',
attempts INTEGER NOT NULL DEFAULT 0,
next_attempt_at TEXT,
locked_until TEXT,
last_error TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_job_id ON ai_jobs(job_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_session_id ON ai_jobs(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_id ON ai_jobs(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_trigger_message_id ON ai_jobs(trigger_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_status ON ai_jobs(status);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_next_attempt_at ON ai_jobs(next_attempt_at);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_locked_until ON ai_jobs(locked_until);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_created_at ON ai_jobs(created_at);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_updated_at ON ai_jobs(updated_at);
CREATE TABLE IF NOT EXISTS ai_turns (
id SERIAL PRIMARY KEY,
turn_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
thread_id TEXT,
interaction_id TEXT,
role TEXT NOT NULL,
source_type TEXT NOT NULL,
text TEXT NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
model TEXT,
finish_reason TEXT,
latency_ms INTEGER,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_turns_turn_id ON ai_turns(turn_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_session_id ON ai_turns(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_thread_id ON ai_turns(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_interaction_id ON ai_turns(interaction_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_role ON ai_turns(role);
CREATE INDEX IF NOT EXISTS idx_ai_turns_source_type ON ai_turns(source_type);
CREATE INDEX IF NOT EXISTS idx_ai_turns_model ON ai_turns(model);
CREATE INDEX IF NOT EXISTS idx_ai_turns_created_at ON ai_turns(created_at);
ALTER TABLE telegram_threads ADD COLUMN IF NOT EXISTS ai_session_id TEXT;
ALTER TABLE telegram_threads ADD COLUMN IF NOT EXISTS ai_state TEXT;
ALTER TABLE telegram_threads ADD COLUMN IF NOT EXISTS ai_handoff_reason TEXT;
ALTER TABLE telegram_threads ADD COLUMN IF NOT EXISTS ai_last_model_at TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_session_id ON telegram_threads(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_state ON telegram_threads(ai_state);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_last_model_at ON telegram_threads(ai_last_model_at);
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS author_type TEXT NOT NULL DEFAULT 'customer';
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS author_id TEXT;
UPDATE telegram_messages
SET author_type = CASE
WHEN direction = 'outbound' THEN 'human'
WHEN direction = 'system' THEN 'system'
ELSE 'customer'
END
WHERE author_type IS NULL OR TRIM(author_type) = '';
UPDATE telegram_messages
SET author_id = operator_user
WHERE direction = 'outbound'
AND operator_user IS NOT NULL
AND (author_id IS NULL OR TRIM(author_id) = '');
CREATE INDEX IF NOT EXISTS idx_telegram_messages_author_type ON telegram_messages(author_type);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_author_id ON telegram_messages(author_id);
+123
View File
@@ -0,0 +1,123 @@
CREATE TABLE IF NOT EXISTS customer_external_identities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
identity_id TEXT NOT NULL UNIQUE,
customer_id TEXT NOT NULL,
channel TEXT NOT NULL,
external_subject TEXT NOT NULL,
display_name_snapshot TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ix_customer_external_identities_channel_subject_unique
ON customer_external_identities(channel, external_subject);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_identity_id ON customer_external_identities(identity_id);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_customer_id ON customer_external_identities(customer_id);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_channel ON customer_external_identities(channel);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_external_subject ON customer_external_identities(external_subject);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_created_at ON customer_external_identities(created_at);
CREATE INDEX IF NOT EXISTS idx_customer_external_identities_updated_at ON customer_external_identities(updated_at);
CREATE TABLE IF NOT EXISTS ai_sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL,
thread_id TEXT,
interaction_id TEXT,
customer_id TEXT,
agent_profile TEXT NOT NULL DEFAULT 'telegram_support',
language TEXT,
status TEXT NOT NULL DEFAULT 'active',
summary_text TEXT NOT NULL DEFAULT '',
last_user_message_id TEXT,
last_ai_message_id TEXT,
handoff_reason TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
closed_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_session_id ON ai_sessions(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_channel ON ai_sessions(channel);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_thread_id ON ai_sessions(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_interaction_id ON ai_sessions(interaction_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_customer_id ON ai_sessions(customer_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_agent_profile ON ai_sessions(agent_profile);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_language ON ai_sessions(language);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_status ON ai_sessions(status);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_last_user_message_id ON ai_sessions(last_user_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_last_ai_message_id ON ai_sessions(last_ai_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_created_at ON ai_sessions(created_at);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_updated_at ON ai_sessions(updated_at);
CREATE INDEX IF NOT EXISTS idx_ai_sessions_closed_at ON ai_sessions(closed_at);
CREATE TABLE IF NOT EXISTS ai_jobs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
job_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
thread_id TEXT NOT NULL,
trigger_message_id TEXT,
status TEXT NOT NULL DEFAULT 'pending',
attempts INTEGER NOT NULL DEFAULT 0,
next_attempt_at TEXT,
locked_until TEXT,
last_error TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_job_id ON ai_jobs(job_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_session_id ON ai_jobs(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_id ON ai_jobs(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_trigger_message_id ON ai_jobs(trigger_message_id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_status ON ai_jobs(status);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_next_attempt_at ON ai_jobs(next_attempt_at);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_locked_until ON ai_jobs(locked_until);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_created_at ON ai_jobs(created_at);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_updated_at ON ai_jobs(updated_at);
CREATE TABLE IF NOT EXISTS ai_turns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
turn_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
thread_id TEXT,
interaction_id TEXT,
role TEXT NOT NULL,
source_type TEXT NOT NULL,
text TEXT NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
model TEXT,
finish_reason TEXT,
latency_ms INTEGER,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_turns_turn_id ON ai_turns(turn_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_session_id ON ai_turns(session_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_thread_id ON ai_turns(thread_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_interaction_id ON ai_turns(interaction_id);
CREATE INDEX IF NOT EXISTS idx_ai_turns_role ON ai_turns(role);
CREATE INDEX IF NOT EXISTS idx_ai_turns_source_type ON ai_turns(source_type);
CREATE INDEX IF NOT EXISTS idx_ai_turns_model ON ai_turns(model);
CREATE INDEX IF NOT EXISTS idx_ai_turns_created_at ON ai_turns(created_at);
ALTER TABLE telegram_threads ADD COLUMN ai_session_id TEXT;
ALTER TABLE telegram_threads ADD COLUMN ai_state TEXT;
ALTER TABLE telegram_threads ADD COLUMN ai_handoff_reason TEXT;
ALTER TABLE telegram_threads ADD COLUMN ai_last_model_at TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_session_id ON telegram_threads(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_state ON telegram_threads(ai_state);
CREATE INDEX IF NOT EXISTS idx_telegram_threads_ai_last_model_at ON telegram_threads(ai_last_model_at);
ALTER TABLE telegram_messages ADD COLUMN author_type TEXT NOT NULL DEFAULT 'customer';
ALTER TABLE telegram_messages ADD COLUMN author_id TEXT;
UPDATE telegram_messages
SET author_type = CASE
WHEN direction = 'outbound' THEN 'human'
WHEN direction = 'system' THEN 'system'
ELSE 'customer'
END
WHERE author_type IS NULL OR TRIM(author_type) = '';
UPDATE telegram_messages
SET author_id = operator_user
WHERE direction = 'outbound'
AND operator_user IS NOT NULL
AND (author_id IS NULL OR TRIM(author_id) = '');
CREATE INDEX IF NOT EXISTS idx_telegram_messages_author_type ON telegram_messages(author_type);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_author_id ON telegram_messages(author_id);
+82
View File
@@ -0,0 +1,82 @@
ALTER TABLE ai_sessions ADD COLUMN IF NOT EXISTS call_id TEXT;
CREATE INDEX IF NOT EXISTS idx_ai_sessions_call_id ON ai_sessions(call_id);
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS voice_session_id TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS ai_session_id TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS ai_state TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS ai_handoff_reason TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN IF NOT EXISTS ai_last_model_at TEXT;
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_voice_session_id ON asterisk_call_links(voice_session_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_session_id ON asterisk_call_links(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_state ON asterisk_call_links(ai_state);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_last_model_at ON asterisk_call_links(ai_last_model_at);
CREATE TABLE IF NOT EXISTS voice_ai_sessions (
id SERIAL PRIMARY KEY,
session_id TEXT NOT NULL UNIQUE,
call_id TEXT NOT NULL UNIQUE,
linked_id TEXT,
interaction_id TEXT,
customer_id TEXT,
queue_id TEXT,
ai_session_id TEXT,
agent_profile TEXT NOT NULL DEFAULT 'voice_support',
language TEXT,
asr_provider TEXT,
tts_provider TEXT,
status TEXT NOT NULL DEFAULT 'queued',
handoff_reason TEXT,
handoff_target_queue_id TEXT,
disclosure_played_at TEXT,
last_user_utterance_at TEXT,
last_ai_reply_at TEXT,
started_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
ended_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_session_id ON voice_ai_sessions(session_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_call_id ON voice_ai_sessions(call_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_linked_id ON voice_ai_sessions(linked_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_interaction_id ON voice_ai_sessions(interaction_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_customer_id ON voice_ai_sessions(customer_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_queue_id ON voice_ai_sessions(queue_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_ai_session_id ON voice_ai_sessions(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_agent_profile ON voice_ai_sessions(agent_profile);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_language ON voice_ai_sessions(language);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_asr_provider ON voice_ai_sessions(asr_provider);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_tts_provider ON voice_ai_sessions(tts_provider);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_status ON voice_ai_sessions(status);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_handoff_target_queue_id ON voice_ai_sessions(handoff_target_queue_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_disclosure_played_at ON voice_ai_sessions(disclosure_played_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_user_utterance_at ON voice_ai_sessions(last_user_utterance_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_ai_reply_at ON voice_ai_sessions(last_ai_reply_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_started_at ON voice_ai_sessions(started_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_updated_at ON voice_ai_sessions(updated_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_ended_at ON voice_ai_sessions(ended_at);
CREATE TABLE IF NOT EXISTS voice_transcript_segments (
id SERIAL PRIMARY KEY,
segment_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
call_id TEXT NOT NULL,
interaction_id TEXT,
speaker TEXT NOT NULL,
source_type TEXT NOT NULL,
sequence_no INTEGER NOT NULL,
text TEXT NOT NULL,
confidence DOUBLE PRECISION,
is_final BOOLEAN NOT NULL DEFAULT TRUE,
barge_in_interrupted BOOLEAN NOT NULL DEFAULT FALSE,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_segment_id ON voice_transcript_segments(segment_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_session_id ON voice_transcript_segments(session_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_call_id ON voice_transcript_segments(call_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_interaction_id ON voice_transcript_segments(interaction_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_speaker ON voice_transcript_segments(speaker);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_source_type ON voice_transcript_segments(source_type);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_sequence_no ON voice_transcript_segments(sequence_no);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_is_final ON voice_transcript_segments(is_final);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_barge_in_interrupted ON voice_transcript_segments(barge_in_interrupted);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_created_at ON voice_transcript_segments(created_at);
+82
View File
@@ -0,0 +1,82 @@
ALTER TABLE ai_sessions ADD COLUMN call_id TEXT;
CREATE INDEX IF NOT EXISTS idx_ai_sessions_call_id ON ai_sessions(call_id);
ALTER TABLE asterisk_call_links ADD COLUMN voice_session_id TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN ai_session_id TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN ai_state TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN ai_handoff_reason TEXT;
ALTER TABLE asterisk_call_links ADD COLUMN ai_last_model_at TEXT;
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_voice_session_id ON asterisk_call_links(voice_session_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_session_id ON asterisk_call_links(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_state ON asterisk_call_links(ai_state);
CREATE INDEX IF NOT EXISTS idx_asterisk_call_links_ai_last_model_at ON asterisk_call_links(ai_last_model_at);
CREATE TABLE IF NOT EXISTS voice_ai_sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL UNIQUE,
call_id TEXT NOT NULL UNIQUE,
linked_id TEXT,
interaction_id TEXT,
customer_id TEXT,
queue_id TEXT,
ai_session_id TEXT,
agent_profile TEXT NOT NULL DEFAULT 'voice_support',
language TEXT,
asr_provider TEXT,
tts_provider TEXT,
status TEXT NOT NULL DEFAULT 'queued',
handoff_reason TEXT,
handoff_target_queue_id TEXT,
disclosure_played_at TEXT,
last_user_utterance_at TEXT,
last_ai_reply_at TEXT,
started_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
ended_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_session_id ON voice_ai_sessions(session_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_call_id ON voice_ai_sessions(call_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_linked_id ON voice_ai_sessions(linked_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_interaction_id ON voice_ai_sessions(interaction_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_customer_id ON voice_ai_sessions(customer_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_queue_id ON voice_ai_sessions(queue_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_ai_session_id ON voice_ai_sessions(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_agent_profile ON voice_ai_sessions(agent_profile);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_language ON voice_ai_sessions(language);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_asr_provider ON voice_ai_sessions(asr_provider);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_tts_provider ON voice_ai_sessions(tts_provider);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_status ON voice_ai_sessions(status);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_handoff_target_queue_id ON voice_ai_sessions(handoff_target_queue_id);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_disclosure_played_at ON voice_ai_sessions(disclosure_played_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_user_utterance_at ON voice_ai_sessions(last_user_utterance_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_ai_reply_at ON voice_ai_sessions(last_ai_reply_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_started_at ON voice_ai_sessions(started_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_updated_at ON voice_ai_sessions(updated_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_ended_at ON voice_ai_sessions(ended_at);
CREATE TABLE IF NOT EXISTS voice_transcript_segments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
segment_id TEXT NOT NULL UNIQUE,
session_id TEXT NOT NULL,
call_id TEXT NOT NULL,
interaction_id TEXT,
speaker TEXT NOT NULL,
source_type TEXT NOT NULL,
sequence_no INTEGER NOT NULL,
text TEXT NOT NULL,
confidence REAL,
is_final INTEGER NOT NULL DEFAULT 1,
barge_in_interrupted INTEGER NOT NULL DEFAULT 0,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_segment_id ON voice_transcript_segments(segment_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_session_id ON voice_transcript_segments(session_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_call_id ON voice_transcript_segments(call_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_interaction_id ON voice_transcript_segments(interaction_id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_speaker ON voice_transcript_segments(speaker);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_source_type ON voice_transcript_segments(source_type);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_sequence_no ON voice_transcript_segments(sequence_no);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_is_final ON voice_transcript_segments(is_final);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_barge_in_interrupted ON voice_transcript_segments(barge_in_interrupted);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_created_at ON voice_transcript_segments(created_at);
@@ -0,0 +1,11 @@
ALTER TABLE voice_ai_sessions ADD COLUMN IF NOT EXISTS media_uuid TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN IF NOT EXISTS media_status TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN IF NOT EXISTS media_connected_at TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN IF NOT EXISTS media_ended_at TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN IF NOT EXISTS last_media_frame_at TEXT;
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_uuid ON voice_ai_sessions(media_uuid);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_status ON voice_ai_sessions(media_status);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_connected_at ON voice_ai_sessions(media_connected_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_ended_at ON voice_ai_sessions(media_ended_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_media_frame_at ON voice_ai_sessions(last_media_frame_at);
@@ -0,0 +1,11 @@
ALTER TABLE voice_ai_sessions ADD COLUMN media_uuid TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN media_status TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN media_connected_at TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN media_ended_at TEXT;
ALTER TABLE voice_ai_sessions ADD COLUMN last_media_frame_at TEXT;
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_uuid ON voice_ai_sessions(media_uuid);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_status ON voice_ai_sessions(media_status);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_connected_at ON voice_ai_sessions(media_connected_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_media_ended_at ON voice_ai_sessions(media_ended_at);
CREATE INDEX IF NOT EXISTS idx_voice_ai_sessions_last_media_frame_at ON voice_ai_sessions(last_media_frame_at);
@@ -0,0 +1,4 @@
ALTER TABLE ivr_sessions
ADD COLUMN IF NOT EXISTS resolved_queue_code TEXT NULL;
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_resolved_queue_code ON ivr_sessions (resolved_queue_code);
@@ -0,0 +1,3 @@
ALTER TABLE ivr_sessions ADD COLUMN resolved_queue_code TEXT NULL;
CREATE INDEX IF NOT EXISTS ix_ivr_sessions_resolved_queue_code ON ivr_sessions (resolved_queue_code);
@@ -0,0 +1,17 @@
ALTER TABLE kb_articles
ADD COLUMN IF NOT EXISTS article_group_id TEXT NULL;
ALTER TABLE kb_articles
ADD COLUMN IF NOT EXISTS language TEXT NULL DEFAULT 'ru';
UPDATE kb_articles
SET language = 'ru'
WHERE language IS NULL OR BTRIM(language) = '';
UPDATE kb_articles
SET article_group_id = article_id
WHERE article_group_id IS NULL OR BTRIM(article_group_id) = '';
CREATE INDEX IF NOT EXISTS idx_kb_articles_article_group_id ON kb_articles (article_group_id);
CREATE INDEX IF NOT EXISTS idx_kb_articles_language ON kb_articles (language);
@@ -0,0 +1,15 @@
ALTER TABLE kb_articles ADD COLUMN article_group_id TEXT NULL;
ALTER TABLE kb_articles ADD COLUMN language TEXT NULL DEFAULT 'ru';
UPDATE kb_articles
SET language = 'ru'
WHERE language IS NULL OR TRIM(language) = '';
UPDATE kb_articles
SET article_group_id = article_id
WHERE article_group_id IS NULL OR TRIM(article_group_id) = '';
CREATE INDEX IF NOT EXISTS idx_kb_articles_article_group_id ON kb_articles (article_group_id);
CREATE INDEX IF NOT EXISTS idx_kb_articles_language ON kb_articles (language);
@@ -0,0 +1,150 @@
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS delivery_attempts INTEGER NOT NULL DEFAULT 0;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS next_delivery_attempt_at TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS delivery_locked_until TEXT;
ALTER TABLE telegram_messages ADD COLUMN IF NOT EXISTS last_delivery_error TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_messages_next_delivery_attempt_at
ON telegram_messages(next_delivery_attempt_at);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_delivery_locked_until
ON telegram_messages(delivery_locked_until);
CREATE TABLE IF NOT EXISTS whatsapp_threads (
id SERIAL PRIMARY KEY,
thread_id TEXT NOT NULL UNIQUE,
chat_id TEXT NOT NULL UNIQUE,
interaction_id TEXT NOT NULL,
whatsapp_user_id TEXT,
phone_number TEXT,
display_name TEXT,
queue_id TEXT,
is_group BOOLEAN NOT NULL DEFAULT FALSE,
status TEXT NOT NULL,
claimed_by_user TEXT,
claimed_at TEXT,
ai_session_id TEXT,
ai_state TEXT,
ai_handoff_reason TEXT,
ai_last_model_at TEXT,
last_message_at TEXT NOT NULL,
last_message_preview TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS phone_number TEXT;
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS is_group BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS ai_session_id TEXT;
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS ai_state TEXT;
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS ai_handoff_reason TEXT;
ALTER TABLE whatsapp_threads ADD COLUMN IF NOT EXISTS ai_last_model_at TEXT;
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_thread_id ON whatsapp_threads(thread_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_chat_id ON whatsapp_threads(chat_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_interaction_id ON whatsapp_threads(interaction_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_whatsapp_user_id ON whatsapp_threads(whatsapp_user_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_phone_number ON whatsapp_threads(phone_number);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_display_name ON whatsapp_threads(display_name);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_queue_id ON whatsapp_threads(queue_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_is_group ON whatsapp_threads(is_group);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_status ON whatsapp_threads(status);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_claimed_by_user ON whatsapp_threads(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_claimed_at ON whatsapp_threads(claimed_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_session_id ON whatsapp_threads(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_state ON whatsapp_threads(ai_state);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_last_model_at ON whatsapp_threads(ai_last_model_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_last_message_at ON whatsapp_threads(last_message_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_created_at ON whatsapp_threads(created_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_updated_at ON whatsapp_threads(updated_at);
CREATE TABLE IF NOT EXISTS whatsapp_messages (
id SERIAL PRIMARY KEY,
message_id TEXT NOT NULL UNIQUE,
thread_id TEXT,
interaction_id TEXT,
chat_id TEXT NOT NULL,
text TEXT NOT NULL,
customer_id TEXT,
direction TEXT NOT NULL DEFAULT 'inbound',
whatsapp_message_id_external TEXT,
operator_user TEXT,
author_type TEXT NOT NULL DEFAULT 'customer',
author_id TEXT,
delivery_status TEXT,
delivery_attempts INTEGER NOT NULL DEFAULT 0,
next_delivery_attempt_at TEXT,
delivery_locked_until TEXT,
last_delivery_error TEXT,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS thread_id TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS interaction_id TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS customer_id TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS direction TEXT NOT NULL DEFAULT 'inbound';
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS whatsapp_message_id_external TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS operator_user TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS delivery_status TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS delivery_attempts INTEGER NOT NULL DEFAULT 0;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS next_delivery_attempt_at TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS delivery_locked_until TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS last_delivery_error TEXT;
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS author_type TEXT NOT NULL DEFAULT 'customer';
ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS author_id TEXT;
UPDATE whatsapp_messages
SET author_type = CASE
WHEN direction = 'outbound' THEN 'human'
WHEN direction = 'system' THEN 'system'
ELSE 'customer'
END
WHERE author_type IS NULL OR BTRIM(author_type) = '';
UPDATE whatsapp_messages
SET author_id = operator_user
WHERE operator_user IS NOT NULL
AND (
direction = 'outbound'
OR direction IS NULL
OR BTRIM(direction) = ''
)
AND (author_id IS NULL OR BTRIM(author_id) = '');
CREATE UNIQUE INDEX IF NOT EXISTS ix_whatsapp_messages_chat_external_unique
ON whatsapp_messages(chat_id, whatsapp_message_id_external);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_message_id ON whatsapp_messages(message_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_thread_id ON whatsapp_messages(thread_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_interaction_id ON whatsapp_messages(interaction_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_chat_id ON whatsapp_messages(chat_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_customer_id ON whatsapp_messages(customer_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_direction ON whatsapp_messages(direction);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_whatsapp_message_id_external
ON whatsapp_messages(whatsapp_message_id_external);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_operator_user ON whatsapp_messages(operator_user);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_author_type ON whatsapp_messages(author_type);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_author_id ON whatsapp_messages(author_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_delivery_status ON whatsapp_messages(delivery_status);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_next_delivery_attempt_at
ON whatsapp_messages(next_delivery_attempt_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_delivery_locked_until
ON whatsapp_messages(delivery_locked_until);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_created_at ON whatsapp_messages(created_at);
CREATE INDEX IF NOT EXISTS idx_event_outbox_status_available_at_id
ON event_outbox(status, available_at, id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_status_id
ON ai_jobs(thread_id, status, id DESC);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_trigger_id
ON ai_jobs(thread_id, trigger_message_id, id DESC);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_thread_direction_author_created_id
ON telegram_messages(thread_id, direction, author_type, created_at DESC, id DESC);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_thread_direction_author_created_id
ON whatsapp_messages(thread_id, direction, author_type, created_at DESC, id DESC);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_session_speaker_final_id
ON voice_transcript_segments(session_id, speaker, is_final, id DESC);
CREATE UNIQUE INDEX IF NOT EXISTS uq_voice_transcript_segments_session_sequence
ON voice_transcript_segments(session_id, sequence_no);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_name_call_status_id
ON asterisk_event_log(ami_event_name, call_id, forward_status, id DESC);
CREATE INDEX IF NOT EXISTS idx_reporting_events_queue_channel_created_at
ON reporting_events(queue_id, channel, created_at);
@@ -0,0 +1,129 @@
ALTER TABLE telegram_messages ADD COLUMN delivery_attempts INTEGER NOT NULL DEFAULT 0;
ALTER TABLE telegram_messages ADD COLUMN next_delivery_attempt_at TEXT;
ALTER TABLE telegram_messages ADD COLUMN delivery_locked_until TEXT;
ALTER TABLE telegram_messages ADD COLUMN last_delivery_error TEXT;
CREATE INDEX IF NOT EXISTS idx_telegram_messages_next_delivery_attempt_at
ON telegram_messages(next_delivery_attempt_at);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_delivery_locked_until
ON telegram_messages(delivery_locked_until);
CREATE TABLE IF NOT EXISTS whatsapp_threads (
id INTEGER PRIMARY KEY AUTOINCREMENT,
thread_id TEXT NOT NULL UNIQUE,
chat_id TEXT NOT NULL UNIQUE,
interaction_id TEXT NOT NULL,
whatsapp_user_id TEXT,
phone_number TEXT,
display_name TEXT,
queue_id TEXT,
is_group INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL,
claimed_by_user TEXT,
claimed_at TEXT,
ai_session_id TEXT,
ai_state TEXT,
ai_handoff_reason TEXT,
ai_last_model_at TEXT,
last_message_at TEXT NOT NULL,
last_message_preview TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_thread_id ON whatsapp_threads(thread_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_chat_id ON whatsapp_threads(chat_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_interaction_id ON whatsapp_threads(interaction_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_whatsapp_user_id ON whatsapp_threads(whatsapp_user_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_phone_number ON whatsapp_threads(phone_number);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_display_name ON whatsapp_threads(display_name);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_queue_id ON whatsapp_threads(queue_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_is_group ON whatsapp_threads(is_group);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_status ON whatsapp_threads(status);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_claimed_by_user ON whatsapp_threads(claimed_by_user);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_claimed_at ON whatsapp_threads(claimed_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_session_id ON whatsapp_threads(ai_session_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_state ON whatsapp_threads(ai_state);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_ai_last_model_at ON whatsapp_threads(ai_last_model_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_last_message_at ON whatsapp_threads(last_message_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_created_at ON whatsapp_threads(created_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_threads_updated_at ON whatsapp_threads(updated_at);
CREATE TABLE IF NOT EXISTS whatsapp_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT NOT NULL UNIQUE,
thread_id TEXT,
interaction_id TEXT,
chat_id TEXT NOT NULL,
text TEXT NOT NULL,
customer_id TEXT,
direction TEXT NOT NULL DEFAULT 'inbound',
whatsapp_message_id_external TEXT,
operator_user TEXT,
author_type TEXT NOT NULL DEFAULT 'customer',
author_id TEXT,
delivery_status TEXT,
delivery_attempts INTEGER NOT NULL DEFAULT 0,
next_delivery_attempt_at TEXT,
delivery_locked_until TEXT,
last_delivery_error TEXT,
payload_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL
);
UPDATE whatsapp_messages
SET author_type = CASE
WHEN direction = 'outbound' THEN 'human'
WHEN direction = 'system' THEN 'system'
ELSE 'customer'
END
WHERE author_type IS NULL OR TRIM(author_type) = '';
UPDATE whatsapp_messages
SET author_id = operator_user
WHERE operator_user IS NOT NULL
AND (
direction = 'outbound'
OR direction IS NULL
OR TRIM(direction) = ''
)
AND (author_id IS NULL OR TRIM(author_id) = '');
CREATE UNIQUE INDEX IF NOT EXISTS ix_whatsapp_messages_chat_external_unique
ON whatsapp_messages(chat_id, whatsapp_message_id_external);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_message_id ON whatsapp_messages(message_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_thread_id ON whatsapp_messages(thread_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_interaction_id ON whatsapp_messages(interaction_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_chat_id ON whatsapp_messages(chat_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_customer_id ON whatsapp_messages(customer_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_direction ON whatsapp_messages(direction);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_whatsapp_message_id_external
ON whatsapp_messages(whatsapp_message_id_external);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_operator_user ON whatsapp_messages(operator_user);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_author_type ON whatsapp_messages(author_type);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_author_id ON whatsapp_messages(author_id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_delivery_status ON whatsapp_messages(delivery_status);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_next_delivery_attempt_at
ON whatsapp_messages(next_delivery_attempt_at);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_delivery_locked_until
ON whatsapp_messages(delivery_locked_until);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_created_at ON whatsapp_messages(created_at);
CREATE INDEX IF NOT EXISTS idx_event_outbox_status_available_at_id
ON event_outbox(status, available_at, id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_status_id
ON ai_jobs(thread_id, status, id);
CREATE INDEX IF NOT EXISTS idx_ai_jobs_thread_trigger_id
ON ai_jobs(thread_id, trigger_message_id, id);
CREATE INDEX IF NOT EXISTS idx_telegram_messages_thread_direction_author_created_id
ON telegram_messages(thread_id, direction, author_type, created_at, id);
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_thread_direction_author_created_id
ON whatsapp_messages(thread_id, direction, author_type, created_at, id);
CREATE INDEX IF NOT EXISTS idx_voice_transcript_segments_session_speaker_final_id
ON voice_transcript_segments(session_id, speaker, is_final, id);
CREATE UNIQUE INDEX IF NOT EXISTS uq_voice_transcript_segments_session_sequence
ON voice_transcript_segments(session_id, sequence_no);
CREATE INDEX IF NOT EXISTS idx_asterisk_event_log_name_call_status_id
ON asterisk_event_log(ami_event_name, call_id, forward_status, id);
CREATE INDEX IF NOT EXISTS idx_reporting_events_queue_channel_created_at
ON reporting_events(queue_id, channel, created_at);
@@ -0,0 +1,24 @@
CREATE TABLE IF NOT EXISTS reporting_interaction_facts (
id SERIAL PRIMARY KEY,
interaction_id VARCHAR(64) NOT NULL,
channel VARCHAR(32) NULL,
queue_id VARCHAR(64) NULL,
agent_id VARCHAR(128) NULL,
status VARCHAR(32) NULL,
created_at VARCHAR(64) NULL,
updated_at VARCHAR(64) NOT NULL,
closed_at VARCHAR(64) NULL,
answered BOOLEAN NULL,
abandoned BOOLEAN NULL,
wait_seconds INTEGER NULL,
handle_seconds INTEGER NULL,
resolved_first_contact BOOLEAN NULL,
source VARCHAR(64) NOT NULL DEFAULT 'unknown',
CONSTRAINT uq_reporting_interaction_facts_interaction_id UNIQUE (interaction_id)
);
CREATE INDEX IF NOT EXISTS idx_reporting_interaction_facts_created_queue_channel
ON reporting_interaction_facts (created_at, queue_id, channel);
CREATE INDEX IF NOT EXISTS idx_reporting_interaction_facts_status_agent
ON reporting_interaction_facts (status, agent_id);
@@ -0,0 +1,24 @@
CREATE TABLE IF NOT EXISTS reporting_interaction_facts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
interaction_id TEXT NOT NULL,
channel TEXT NULL,
queue_id TEXT NULL,
agent_id TEXT NULL,
status TEXT NULL,
created_at TEXT NULL,
updated_at TEXT NOT NULL,
closed_at TEXT NULL,
answered INTEGER NULL,
abandoned INTEGER NULL,
wait_seconds INTEGER NULL,
handle_seconds INTEGER NULL,
resolved_first_contact INTEGER NULL,
source TEXT NOT NULL DEFAULT 'unknown',
CONSTRAINT uq_reporting_interaction_facts_interaction_id UNIQUE (interaction_id)
);
CREATE INDEX IF NOT EXISTS idx_reporting_interaction_facts_created_queue_channel
ON reporting_interaction_facts (created_at, queue_id, channel);
CREATE INDEX IF NOT EXISTS idx_reporting_interaction_facts_status_agent
ON reporting_interaction_facts (status, agent_id);
@@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS reporting_saved_views (
id SERIAL PRIMARY KEY,
owner_user VARCHAR(128) NOT NULL,
owner_role VARCHAR(32) NULL,
view_id VARCHAR(64) NOT NULL,
name VARCHAR(160) NOT NULL,
snapshot_json TEXT NOT NULL DEFAULT '{}',
created_at VARCHAR(64) NOT NULL,
updated_at VARCHAR(64) NOT NULL,
CONSTRAINT uq_reporting_saved_views_owner_view UNIQUE (owner_user, view_id)
);
CREATE INDEX IF NOT EXISTS idx_reporting_saved_views_owner_updated
ON reporting_saved_views (owner_user, updated_at);
@@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS reporting_saved_views (
id INTEGER PRIMARY KEY AUTOINCREMENT,
owner_user TEXT NOT NULL,
owner_role TEXT NULL,
view_id TEXT NOT NULL,
name TEXT NOT NULL,
snapshot_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
CONSTRAINT uq_reporting_saved_views_owner_view UNIQUE (owner_user, view_id)
);
CREATE INDEX IF NOT EXISTS idx_reporting_saved_views_owner_updated
ON reporting_saved_views (owner_user, updated_at);