muzakkirhussain011's picture
Add application files (text files only)
8bab08d
-- CX AI Agent - Enterprise Database Schema
-- SQLite Schema for Campaign Management, Contact Tracking, and Analytics
-- =============================================================================
-- COMPANIES
-- =============================================================================
CREATE TABLE IF NOT EXISTS companies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
domain TEXT UNIQUE,
industry TEXT,
size TEXT,
revenue TEXT,
location TEXT,
description TEXT,
pain_points TEXT, -- JSON array
website TEXT,
linkedin_url TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_companies_domain ON companies(domain);
CREATE INDEX idx_companies_industry ON companies(industry);
-- =============================================================================
-- CONTACTS
-- =============================================================================
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER,
first_name TEXT,
last_name TEXT,
email TEXT UNIQUE NOT NULL,
phone TEXT,
job_title TEXT,
department TEXT,
seniority_level TEXT, -- C-Level, VP, Director, Manager, Individual Contributor
linkedin_url TEXT,
twitter_url TEXT,
location TEXT,
timezone TEXT,
-- Scoring
fit_score REAL DEFAULT 0.0,
engagement_score REAL DEFAULT 0.0,
intent_score REAL DEFAULT 0.0,
overall_score REAL DEFAULT 0.0,
-- Status & Lifecycle
status TEXT DEFAULT 'new', -- new, contacted, responded, meeting_scheduled, qualified, lost, customer
lifecycle_stage TEXT DEFAULT 'lead', -- lead, mql, sql, opportunity, customer, churned
-- Tracking
source TEXT, -- discovery_agent, manual_import, api, referral
first_contacted_at TIMESTAMP,
last_contacted_at TIMESTAMP,
last_activity_at TIMESTAMP,
-- Metadata
tags TEXT, -- JSON array
notes TEXT,
custom_fields TEXT, -- JSON object for extensibility
is_suppressed BOOLEAN DEFAULT 0,
suppression_reason TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL
);
CREATE INDEX idx_contacts_email ON contacts(email);
CREATE INDEX idx_contacts_company ON contacts(company_id);
CREATE INDEX idx_contacts_status ON contacts(status);
CREATE INDEX idx_contacts_lifecycle_stage ON contacts(lifecycle_stage);
CREATE INDEX idx_contacts_overall_score ON contacts(overall_score);
-- =============================================================================
-- CAMPAIGNS
-- =============================================================================
CREATE TABLE IF NOT EXISTS campaigns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'draft', -- draft, active, paused, completed, archived
-- Targeting
target_industries TEXT, -- JSON array
target_company_sizes TEXT, -- JSON array
target_locations TEXT, -- JSON array
target_job_titles TEXT, -- JSON array
-- Configuration
sequence_id INTEGER,
goal_contacts INTEGER,
goal_response_rate REAL,
goal_meetings INTEGER,
-- Tracking
contacts_discovered INTEGER DEFAULT 0,
contacts_enriched INTEGER DEFAULT 0,
contacts_scored INTEGER DEFAULT 0,
contacts_contacted INTEGER DEFAULT 0,
contacts_responded INTEGER DEFAULT 0,
meetings_booked INTEGER DEFAULT 0,
-- Dates
started_at TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by TEXT,
FOREIGN KEY (sequence_id) REFERENCES sequences(id) ON DELETE SET NULL
);
CREATE INDEX idx_campaigns_status ON campaigns(status);
-- =============================================================================
-- CAMPAIGN CONTACTS (Many-to-Many with Stage Tracking)
-- =============================================================================
CREATE TABLE IF NOT EXISTS campaign_contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
campaign_id INTEGER NOT NULL,
contact_id INTEGER NOT NULL,
stage TEXT DEFAULT 'discovery', -- discovery, enrichment, scoring, outreach, responded, meeting, closed_won, closed_lost
stage_updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
notes TEXT,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE CASCADE,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
UNIQUE(campaign_id, contact_id)
);
CREATE INDEX idx_campaign_contacts_campaign ON campaign_contacts(campaign_id);
CREATE INDEX idx_campaign_contacts_contact ON campaign_contacts(contact_id);
CREATE INDEX idx_campaign_contacts_stage ON campaign_contacts(stage);
-- =============================================================================
-- EMAIL SEQUENCES
-- =============================================================================
CREATE TABLE IF NOT EXISTS sequences (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
category TEXT DEFAULT 'outbound', -- outbound, nurture, re-engagement
is_active BOOLEAN DEFAULT 1,
is_template BOOLEAN DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by TEXT
);
-- =============================================================================
-- SEQUENCE EMAILS (Steps in a sequence)
-- =============================================================================
CREATE TABLE IF NOT EXISTS sequence_emails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sequence_id INTEGER NOT NULL,
step_number INTEGER NOT NULL,
wait_days INTEGER DEFAULT 0, -- Days to wait after previous email
subject TEXT NOT NULL,
body TEXT NOT NULL,
send_time_preference TEXT, -- morning, afternoon, evening, or specific time
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sequence_id) REFERENCES sequences(id) ON DELETE CASCADE,
UNIQUE(sequence_id, step_number)
);
CREATE INDEX idx_sequence_emails_sequence ON sequence_emails(sequence_id);
-- =============================================================================
-- EMAIL ACTIVITIES (Tracking email interactions)
-- =============================================================================
CREATE TABLE IF NOT EXISTS email_activities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER NOT NULL,
campaign_id INTEGER,
sequence_email_id INTEGER,
type TEXT NOT NULL, -- sent, delivered, opened, clicked, replied, bounced, unsubscribed, complained
subject TEXT,
preview TEXT,
link_url TEXT, -- For click tracking
meta_data TEXT, -- JSON for additional data
occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE SET NULL,
FOREIGN KEY (sequence_email_id) REFERENCES sequence_emails(id) ON DELETE SET NULL
);
CREATE INDEX idx_email_activities_contact ON email_activities(contact_id);
CREATE INDEX idx_email_activities_campaign ON email_activities(campaign_id);
CREATE INDEX idx_email_activities_type ON email_activities(type);
CREATE INDEX idx_email_activities_occurred ON email_activities(occurred_at);
-- =============================================================================
-- MEETINGS
-- =============================================================================
CREATE TABLE IF NOT EXISTS meetings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER NOT NULL,
campaign_id INTEGER,
title TEXT NOT NULL,
description TEXT,
scheduled_at TIMESTAMP NOT NULL,
duration_minutes INTEGER DEFAULT 30,
meeting_url TEXT,
location TEXT,
status TEXT DEFAULT 'scheduled', -- scheduled, completed, cancelled, no_show, rescheduled
outcome TEXT, -- interested, not_interested, needs_follow_up, closed_won
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE SET NULL
);
CREATE INDEX idx_meetings_contact ON meetings(contact_id);
CREATE INDEX idx_meetings_campaign ON meetings(campaign_id);
CREATE INDEX idx_meetings_scheduled ON meetings(scheduled_at);
CREATE INDEX idx_meetings_status ON meetings(status);
-- =============================================================================
-- ACTIVITIES (General activity log)
-- =============================================================================
CREATE TABLE IF NOT EXISTS activities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contact_id INTEGER,
campaign_id INTEGER,
meeting_id INTEGER,
type TEXT NOT NULL, -- discovery, enrichment, email_sent, email_opened, reply_received, meeting_scheduled, meeting_completed, note_added, status_changed
description TEXT,
meta_data TEXT, -- JSON for additional context
performed_by TEXT, -- agent_name or 'user'
occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE SET NULL,
FOREIGN KEY (meeting_id) REFERENCES meetings(id) ON DELETE SET NULL
);
CREATE INDEX idx_activities_contact ON activities(contact_id);
CREATE INDEX idx_activities_campaign ON activities(campaign_id);
CREATE INDEX idx_activities_type ON activities(type);
CREATE INDEX idx_activities_occurred ON activities(occurred_at);
-- =============================================================================
-- AB TESTS (for email sequences)
-- =============================================================================
CREATE TABLE IF NOT EXISTS ab_tests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
campaign_id INTEGER NOT NULL,
sequence_id INTEGER NOT NULL,
name TEXT NOT NULL,
description TEXT,
test_type TEXT NOT NULL, -- subject_line, body, send_time, from_name
variant_a TEXT NOT NULL, -- JSON configuration
variant_b TEXT NOT NULL, -- JSON configuration
winner TEXT, -- 'a', 'b', or null if test ongoing
status TEXT DEFAULT 'running', -- running, completed, cancelled
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE CASCADE,
FOREIGN KEY (sequence_id) REFERENCES sequences(id) ON DELETE CASCADE
);
-- =============================================================================
-- AB TEST RESULTS
-- =============================================================================
CREATE TABLE IF NOT EXISTS ab_test_results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ab_test_id INTEGER NOT NULL,
variant TEXT NOT NULL, -- 'a' or 'b'
emails_sent INTEGER DEFAULT 0,
emails_delivered INTEGER DEFAULT 0,
emails_opened INTEGER DEFAULT 0,
emails_clicked INTEGER DEFAULT 0,
emails_replied INTEGER DEFAULT 0,
meetings_booked INTEGER DEFAULT 0,
FOREIGN KEY (ab_test_id) REFERENCES ab_tests(id) ON DELETE CASCADE,
UNIQUE(ab_test_id, variant)
);
-- =============================================================================
-- TEMPLATES (Email templates)
-- =============================================================================
CREATE TABLE IF NOT EXISTS templates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
category TEXT, -- cold_outreach, follow_up, meeting_request, thank_you
subject TEXT NOT NULL,
body TEXT NOT NULL,
variables TEXT, -- JSON array of variable names
is_active BOOLEAN DEFAULT 1,
usage_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- =============================================================================
-- ANALYTICS SNAPSHOTS (Daily/hourly aggregated metrics)
-- =============================================================================
CREATE TABLE IF NOT EXISTS analytics_snapshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
campaign_id INTEGER,
date DATE NOT NULL,
hour INTEGER, -- null for daily snapshots
-- Metrics
contacts_discovered INTEGER DEFAULT 0,
contacts_enriched INTEGER DEFAULT 0,
emails_sent INTEGER DEFAULT 0,
emails_opened INTEGER DEFAULT 0,
emails_clicked INTEGER DEFAULT 0,
emails_replied INTEGER DEFAULT 0,
meetings_booked INTEGER DEFAULT 0,
-- Rates
open_rate REAL DEFAULT 0.0,
click_rate REAL DEFAULT 0.0,
response_rate REAL DEFAULT 0.0,
meeting_rate REAL DEFAULT 0.0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE CASCADE,
UNIQUE(campaign_id, date, hour)
);
CREATE INDEX idx_analytics_campaign ON analytics_snapshots(campaign_id);
CREATE INDEX idx_analytics_date ON analytics_snapshots(date);
-- =============================================================================
-- SETTINGS (Application configuration)
-- =============================================================================
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
description TEXT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insert default settings
INSERT OR IGNORE INTO settings (key, value, description) VALUES
('company_name', 'Your Company', 'Company name for email footers'),
('company_address', '123 Main St, City, State 12345', 'Physical address for CAN-SPAM compliance'),
('sender_name', 'Sales Team', 'Default sender name for emails'),
('sender_email', 'hello@example.com', 'Default sender email'),
('daily_email_limit', '1000', 'Maximum emails to send per day'),
('enable_tracking', '1', 'Enable email open and click tracking'),
('auto_pause_on_low_score', '1', 'Automatically pause contacts with low engagement'),
('min_engagement_score', '0.3', 'Minimum engagement score before auto-pause');