package database import ( "context" "fmt" ) // migrateEmail creates email template tables, settings, and indexes (Phase 8). func migrateEmail(db *DB) error { ctx := context.Background() migrations := []string{ // ============================================= // Phase 8: E-Mail Templates (Transactional) // ============================================= // Email templates (like legal_documents) `CREATE TABLE IF NOT EXISTS email_templates ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), type VARCHAR(50) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, is_active BOOLEAN DEFAULT TRUE, sort_order INT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() )`, // Email template versions (like document_versions) `CREATE TABLE IF NOT EXISTS email_template_versions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), template_id UUID REFERENCES email_templates(id) ON DELETE CASCADE, version VARCHAR(20) NOT NULL, language VARCHAR(5) DEFAULT 'de', subject VARCHAR(500) NOT NULL, body_html TEXT NOT NULL, body_text TEXT NOT NULL, summary TEXT, status VARCHAR(20) DEFAULT 'draft', published_at TIMESTAMPTZ, scheduled_publish_at TIMESTAMPTZ, created_by UUID REFERENCES users(id), approved_by UUID REFERENCES users(id), approved_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(template_id, version, language) )`, // Email template approvals (like version_approvals) `CREATE TABLE IF NOT EXISTS email_template_approvals ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), version_id UUID REFERENCES email_template_versions(id) ON DELETE CASCADE, approver_id UUID REFERENCES users(id), action VARCHAR(30) NOT NULL, comment TEXT, created_at TIMESTAMPTZ DEFAULT NOW() )`, // Email send logs for audit `CREATE TABLE IF NOT EXISTS email_send_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE SET NULL, version_id UUID REFERENCES email_template_versions(id) ON DELETE SET NULL, recipient VARCHAR(255) NOT NULL, subject VARCHAR(500) NOT NULL, status VARCHAR(20) DEFAULT 'queued', error_msg TEXT, variables JSONB, sent_at TIMESTAMPTZ, delivered_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() )`, // Global email settings (logo, colors, signature) `CREATE TABLE IF NOT EXISTS email_template_settings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), logo_url TEXT, logo_base64 TEXT, company_name VARCHAR(255) DEFAULT 'BreakPilot', sender_name VARCHAR(255) DEFAULT 'BreakPilot', sender_email VARCHAR(255) DEFAULT 'noreply@breakpilot.app', reply_to_email VARCHAR(255), footer_html TEXT, footer_text TEXT, primary_color VARCHAR(7) DEFAULT '#2563eb', secondary_color VARCHAR(7) DEFAULT '#64748b', updated_at TIMESTAMPTZ DEFAULT NOW(), updated_by UUID REFERENCES users(id) )`, // Insert default email settings `INSERT INTO email_template_settings (id, company_name, sender_name, sender_email, primary_color, secondary_color) VALUES (gen_random_uuid(), 'BreakPilot', 'BreakPilot', 'noreply@breakpilot.app', '#2563eb', '#64748b') ON CONFLICT DO NOTHING`, // Phase 8 Indexes `CREATE INDEX IF NOT EXISTS idx_email_templates_type ON email_templates(type)`, `CREATE INDEX IF NOT EXISTS idx_email_template_versions_template ON email_template_versions(template_id)`, `CREATE INDEX IF NOT EXISTS idx_email_template_versions_status ON email_template_versions(status)`, `CREATE INDEX IF NOT EXISTS idx_email_template_approvals_version ON email_template_approvals(version_id)`, `CREATE INDEX IF NOT EXISTS idx_email_send_logs_user ON email_send_logs(user_id)`, `CREATE INDEX IF NOT EXISTS idx_email_send_logs_created ON email_send_logs(created_at)`, `CREATE INDEX IF NOT EXISTS idx_email_send_logs_status ON email_send_logs(status)`, } for _, migration := range migrations { if _, err := db.Pool.Exec(ctx, migration); err != nil { return fmt.Errorf("migrateEmail: %w", err) } } return nil }