-- GoChat Captain AI Tables -- Reference: Chatwoot enterprise/app/models/captain/ models -- Adds AI assistant, document, response, scenario, custom_tool, and inbox tables -- Captain Assistants CREATE TABLE IF NOT EXISTS captain_assistants ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(1024), config JSONB NOT NULL DEFAULT '{}', guardrails JSONB, response_guidelines JSONB, status VARCHAR(50) DEFAULT 'active', created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_captain_assistants_deleted_at ON captain_assistants(deleted_at); CREATE INDEX idx_captain_assistants_account_id ON captain_assistants(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_assistants_status ON captain_assistants(status) WHERE deleted_at IS NULL; -- Captain Documents CREATE TABLE IF NOT EXISTS captain_documents ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, assistant_id INTEGER NOT NULL, name VARCHAR(255), external_link VARCHAR(2048) NOT NULL, content TEXT, content_fingerprint VARCHAR(64), status VARCHAR(50) DEFAULT 'in_progress' NOT NULL, sync_status VARCHAR(50), last_synced_at BIGINT, last_sync_attempted_at BIGINT, last_sync_error_code VARCHAR(50), metadata JSONB, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_captain_documents_deleted_at ON captain_documents(deleted_at); CREATE INDEX idx_captain_documents_account_id ON captain_documents(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_documents_assistant_id ON captain_documents(assistant_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_documents_status ON captain_documents(status) WHERE deleted_at IS NULL; -- Captain Assistant Responses (FAQ entries with embeddings) CREATE TABLE IF NOT EXISTS captain_assistant_responses ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, assistant_id INTEGER NOT NULL, documentable_id INTEGER, documentable_type VARCHAR(50), question VARCHAR(1024) NOT NULL, answer TEXT NOT NULL, status VARCHAR(50) DEFAULT 'approved' NOT NULL, edited BOOLEAN DEFAULT FALSE NOT NULL, embedding vector(1536), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_captain_responses_deleted_at ON captain_assistant_responses(deleted_at); CREATE INDEX idx_captain_responses_account_id ON captain_assistant_responses(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_responses_assistant_id ON captain_assistant_responses(assistant_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_responses_status ON captain_assistant_responses(status) WHERE deleted_at IS NULL; -- Captain Scenarios CREATE TABLE IF NOT EXISTS captain_scenarios ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, assistant_id INTEGER NOT NULL, title VARCHAR(255), description TEXT, instruction TEXT, enabled BOOLEAN DEFAULT TRUE NOT NULL, tools JSONB, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_captain_scenarios_deleted_at ON captain_scenarios(deleted_at); CREATE INDEX idx_captain_scenarios_account_id ON captain_scenarios(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_scenarios_assistant_id ON captain_scenarios(assistant_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_scenarios_enabled ON captain_scenarios(enabled) WHERE deleted_at IS NULL; -- Captain Custom Tools CREATE TABLE IF NOT EXISTS captain_custom_tools ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, title VARCHAR(255) NOT NULL, slug VARCHAR(64) NOT NULL, description TEXT, endpoint_url TEXT NOT NULL, http_method VARCHAR(10) DEFAULT 'GET' NOT NULL, auth_type VARCHAR(20) DEFAULT 'none', auth_config JSONB, param_schema JSONB, request_template TEXT, response_template TEXT, enabled BOOLEAN DEFAULT TRUE NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE, UNIQUE(account_id, slug) ); CREATE INDEX idx_captain_custom_tools_deleted_at ON captain_custom_tools(deleted_at); CREATE INDEX idx_captain_custom_tools_account_id ON captain_custom_tools(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_custom_tools_slug ON captain_custom_tools(slug) WHERE deleted_at IS NULL; -- Captain Inboxes (join table: assistant ↔ inbox) CREATE TABLE IF NOT EXISTS captain_inboxes ( id SERIAL PRIMARY KEY, captain_assistant_id INTEGER NOT NULL, inbox_id INTEGER NOT NULL, account_id INTEGER NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_captain_inboxes_deleted_at ON captain_inboxes(deleted_at); CREATE INDEX idx_captain_inboxes_assistant_id ON captain_inboxes(captain_assistant_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_inboxes_inbox_id ON captain_inboxes(inbox_id) WHERE deleted_at IS NULL; CREATE INDEX idx_captain_inboxes_account_id ON captain_inboxes(account_id) WHERE deleted_at IS NULL; -- Copilot Threads CREATE TABLE IF NOT EXISTS copilot_threads ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, user_id INTEGER NOT NULL, assistant_id INTEGER, title VARCHAR(255) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_copilot_threads_deleted_at ON copilot_threads(deleted_at); CREATE INDEX idx_copilot_threads_account_id ON copilot_threads(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_copilot_threads_user_id ON copilot_threads(user_id) WHERE deleted_at IS NULL; CREATE INDEX idx_copilot_threads_assistant_id ON copilot_threads(assistant_id) WHERE deleted_at IS NULL; -- Copilot Messages CREATE TABLE IF NOT EXISTS copilot_messages ( id SERIAL PRIMARY KEY, account_id INTEGER NOT NULL, copilot_thread_id INTEGER NOT NULL, message_type VARCHAR(50) DEFAULT 'user' NOT NULL, message JSONB NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), deleted_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX idx_copilot_messages_deleted_at ON copilot_messages(deleted_at); CREATE INDEX idx_copilot_messages_account_id ON copilot_messages(account_id) WHERE deleted_at IS NULL; CREATE INDEX idx_copilot_messages_thread_id ON copilot_messages(copilot_thread_id) WHERE deleted_at IS NULL; -- Enable pgvector extension if not already enabled CREATE EXTENSION IF NOT EXISTS vector;