-- +goose Up -- Email campaign drafts + generated versions (Marketing suite P0). -- Provider / unsubscribe / send log tables live in 012_integrations_email.sql. CREATE TABLE email_campaigns ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, name TEXT NOT NULL, template_key TEXT NOT NULL DEFAULT 'custom' CHECK (template_key IN ('christmas', 'black_friday', 'spring', 'custom')), status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'ready', 'scheduled', 'sent', 'cancelled')), category_ids UUID[] NOT NULL DEFAULT '{}', product_ids UUID[] NOT NULL DEFAULT '{}', prompt TEXT NOT NULL DEFAULT '', use_default_prompt BOOLEAN NOT NULL DEFAULT true, audience_filter JSONB NOT NULL DEFAULT '{}'::jsonb, scheduled_at TIMESTAMPTZ, sent_at TIMESTAMPTZ, created_by UUID REFERENCES users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX email_campaigns_company_id_idx ON email_campaigns (company_id); CREATE INDEX email_campaigns_company_status_idx ON email_campaigns (company_id, status); CREATE TABLE email_campaign_versions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), campaign_id UUID NOT NULL REFERENCES email_campaigns(id) ON DELETE CASCADE, company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, version INT NOT NULL DEFAULT 1, subject TEXT NOT NULL DEFAULT '', html_body TEXT NOT NULL DEFAULT '', plain_body TEXT NOT NULL DEFAULT '', generation_mode TEXT NOT NULL DEFAULT 'template' CHECK (generation_mode IN ('template', 'ai')), generated_at TIMESTAMPTZ NOT NULL DEFAULT now(), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (campaign_id, version) ); CREATE INDEX email_campaign_versions_campaign_idx ON email_campaign_versions (campaign_id, version DESC); -- +goose Down DROP TABLE IF EXISTS email_campaign_versions; DROP TABLE IF EXISTS email_campaigns;