mirror of
http://88.130.71.182:3000/BlitTech/contexta_be.git
synced 2026-06-12 23:23:21 +00:00
- Add new routers: admin, appointments, campaigns - Add storage service and logging config - Add migrations directory and test suite with pytest config - Add supabase_migration_features.sql - Update models, dependencies, config, and existing routers - Remove whatsapp_service (deleted) - Update pyproject.toml and uv.lock dependencies Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
118 lines
6.2 KiB
SQL
118 lines
6.2 KiB
SQL
-- Contexta DB Migration
|
|
-- Run this in your Supabase SQL Editor
|
|
|
|
-- ── chatbots: new columns ─────────────────────────────────────────────────────
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS logo_url TEXT;
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS show_branding BOOLEAN DEFAULT TRUE;
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS lead_capture_enabled BOOLEAN DEFAULT FALSE;
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS lead_capture_fields JSONB DEFAULT '["email"]';
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS lead_capture_trigger VARCHAR(50) DEFAULT 'after_first_message';
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS handoff_enabled BOOLEAN DEFAULT FALSE;
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS handoff_message TEXT DEFAULT 'I''ll connect you with our team. Please wait.';
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS handoff_email TEXT;
|
|
ALTER TABLE chatbots ADD COLUMN IF NOT EXISTS handoff_keywords JSONB DEFAULT '["human", "agent", "speak to someone", "talk to a person", "real person"]';
|
|
|
|
-- ── messages: new columns ─────────────────────────────────────────────────────
|
|
ALTER TABLE messages ADD COLUMN IF NOT EXISTS confidence_score DECIMAL(4,3) DEFAULT NULL;
|
|
ALTER TABLE messages ADD COLUMN IF NOT EXISTS is_handoff BOOLEAN DEFAULT FALSE;
|
|
|
|
-- ── leads table ───────────────────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS leads (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
chatbot_id UUID REFERENCES chatbots(id) ON DELETE CASCADE,
|
|
conversation_id UUID REFERENCES conversations(id) ON DELETE SET NULL,
|
|
email VARCHAR(255),
|
|
name VARCHAR(255),
|
|
phone VARCHAR(50),
|
|
company VARCHAR(255),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_leads_chatbot ON leads(chatbot_id);
|
|
CREATE INDEX IF NOT EXISTS idx_leads_created ON leads(created_at DESC);
|
|
ALTER TABLE leads ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "leads_owner" ON leads FOR ALL USING (
|
|
chatbot_id IN (
|
|
SELECT c.id FROM chatbots c
|
|
JOIN companies co ON c.company_id = co.id
|
|
WHERE co.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- ── url_sources table ─────────────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS url_sources (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
chatbot_id UUID REFERENCES chatbots(id) ON DELETE CASCADE,
|
|
url TEXT NOT NULL,
|
|
status VARCHAR(50) DEFAULT 'pending',
|
|
page_title TEXT,
|
|
chunk_count INT DEFAULT 0,
|
|
error_message TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_url_sources_chatbot ON url_sources(chatbot_id);
|
|
ALTER TABLE url_sources ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "url_sources_owner" ON url_sources FOR ALL USING (
|
|
chatbot_id IN (
|
|
SELECT c.id FROM chatbots c
|
|
JOIN companies co ON c.company_id = co.id
|
|
WHERE co.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- ── message_feedback table ────────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS message_feedback (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
message_id UUID REFERENCES messages(id) ON DELETE CASCADE,
|
|
chatbot_id UUID REFERENCES chatbots(id) ON DELETE CASCADE,
|
|
feedback VARCHAR(20) NOT NULL CHECK (feedback IN ('positive', 'negative')),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_feedback_chatbot ON message_feedback(chatbot_id);
|
|
ALTER TABLE message_feedback ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "feedback_insert" ON message_feedback FOR INSERT WITH CHECK (true);
|
|
CREATE POLICY "feedback_select_owner" ON message_feedback FOR SELECT USING (
|
|
chatbot_id IN (
|
|
SELECT c.id FROM chatbots c
|
|
JOIN companies co ON c.company_id = co.id
|
|
WHERE co.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- ── Supabase Storage ──────────────────────────────────────────────────────────
|
|
-- Create the 'logos' bucket manually in the Supabase dashboard:
|
|
-- Storage → New bucket → Name: logos → Public: ON
|
|
|
|
-- ── channel_connections table ─────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS channel_connections (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
chatbot_id UUID NOT NULL REFERENCES chatbots(id) ON DELETE CASCADE,
|
|
channel VARCHAR(20) NOT NULL CHECK (channel IN ('telegram')),
|
|
bot_token TEXT,
|
|
bot_username TEXT,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(chatbot_id, channel)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_channel_connections_chatbot ON channel_connections(chatbot_id);
|
|
ALTER TABLE channel_connections ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "channel_connections_owner" ON channel_connections FOR ALL USING (
|
|
chatbot_id IN (
|
|
SELECT c.id FROM chatbots c
|
|
JOIN companies co ON c.company_id = co.id
|
|
WHERE co.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- ── channel_sessions table ────────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS channel_sessions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
chatbot_id UUID NOT NULL REFERENCES chatbots(id) ON DELETE CASCADE,
|
|
channel VARCHAR(20) NOT NULL,
|
|
external_id TEXT NOT NULL,
|
|
session_id TEXT NOT NULL,
|
|
last_active TIMESTAMPTZ DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(channel, external_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_channel_sessions_lookup ON channel_sessions(channel, external_id);
|