Files
warmbly/internal/infrastructure/db/migrations/000018_tracking_analytics.up.sql
T
2026-02-14 05:38:27 +01:00

54 lines
2.3 KiB
SQL

-- Add indexes for efficient recent activity queries on campaign_contact_progress
CREATE INDEX IF NOT EXISTS idx_campaign_progress_recent_opens
ON campaign_contact_progress(opened_at DESC) WHERE opened_at IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_campaign_progress_recent_clicks
ON campaign_contact_progress(clicked_at DESC) WHERE clicked_at IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_campaign_progress_recent_replies
ON campaign_contact_progress(replied_at DESC) WHERE replied_at IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_campaign_progress_recent_bounces
ON campaign_contact_progress(bounced_at DESC) WHERE bounced_at IS NOT NULL;
-- Add index for tracking lookups by task_id
-- campaign_tasks already has contact_id and sequence_id columns
CREATE INDEX IF NOT EXISTS idx_campaign_tasks_tracking
ON campaign_tasks(task_id) WHERE contact_id IS NOT NULL;
-- Table for tracking event deduplication at consumer level
-- Prevents duplicate processing if Rust service dedupe fails or events are replayed
CREATE TABLE IF NOT EXISTS tracking_events_processed (
task_id UUID NOT NULL,
event_type VARCHAR(20) NOT NULL, -- 'opened' or 'clicked'
ip_hash VARCHAR(32),
url_hash VARCHAR(16) NOT NULL DEFAULT '', -- For click deduplication per URL
processed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (task_id, event_type, url_hash)
);
-- Auto-cleanup old tracking dedupe records (older than 7 days)
CREATE INDEX IF NOT EXISTS idx_tracking_processed_cleanup
ON tracking_events_processed(processed_at);
-- Add organization_id to campaigns for efficient org-level analytics
-- (This may already exist, IF NOT EXISTS handles that)
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'campaigns' AND column_name = 'organization_id'
) THEN
ALTER TABLE campaigns ADD COLUMN organization_id UUID REFERENCES organizations(id);
CREATE INDEX idx_campaigns_org ON campaigns(organization_id);
END IF;
END $$;
-- Composite indexes for dashboard analytics queries
CREATE INDEX IF NOT EXISTS idx_campaign_progress_org_sent
ON campaign_contact_progress(campaign_id, sent_at DESC) WHERE sent_at IS NOT NULL;
-- Add index for daily trend queries
CREATE INDEX IF NOT EXISTS idx_campaign_progress_daily
ON campaign_contact_progress(sent_at, campaign_id) WHERE sent_at IS NOT NULL;