feat: Migrationen für campaigns-Tabellen (PostgreSQL) und email_events (ClickHouse)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
11
migrations/ch/2026-04-17_email_events.sql
Normal file
11
migrations/ch/2026-04-17_email_events.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE IF NOT EXISTS newsletter.email_events (
|
||||
event_type LowCardinality(String),
|
||||
tenant_id String,
|
||||
campaign_id UUID,
|
||||
recipient_hash String,
|
||||
timestamp DateTime64(3, 'UTC'),
|
||||
metadata Map(String, String)
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMM(timestamp)
|
||||
ORDER BY (tenant_id, campaign_id, event_type, timestamp);
|
||||
42
migrations/pg/2026-04-17_campaigns.sql
Normal file
42
migrations/pg/2026-04-17_campaigns.sql
Normal file
@@ -0,0 +1,42 @@
|
||||
-- Wird pro Tenant-Schema ausgeführt (SET search_path = tenant_<id>, public vorher)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS campaigns (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
html_body TEXT NOT NULL,
|
||||
plain_body TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'draft'
|
||||
CHECK (status IN ('draft','scheduled','sending','sent','paused','cancelled')),
|
||||
scheduled_at TIMESTAMPTZ,
|
||||
cron_expression TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS campaign_recipients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
campaign_id UUID NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
list_id UUID,
|
||||
segment_id UUID,
|
||||
CONSTRAINT recipient_has_one CHECK (
|
||||
(list_id IS NOT NULL AND segment_id IS NULL) OR
|
||||
(segment_id IS NOT NULL AND list_id IS NULL)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS campaign_triggers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
campaign_id UUID NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
trigger_type TEXT NOT NULL CHECK (trigger_type IN ('cron', 'event')),
|
||||
trigger_value TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN NEW.updated_at = now(); RETURN NEW; END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER campaigns_updated_at
|
||||
BEFORE UPDATE ON campaigns
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
||||
Reference in New Issue
Block a user