225 lines
9.4 KiB
SQL
225 lines
9.4 KiB
SQL
|
|
-- Mail plugin initial migration: creates all mail tables
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_accounts (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
email_address VARCHAR(255) NOT NULL,
|
||
|
|
display_name VARCHAR(255) NOT NULL DEFAULT '',
|
||
|
|
imap_host VARCHAR(255) NOT NULL,
|
||
|
|
imap_port INTEGER NOT NULL DEFAULT 993,
|
||
|
|
imap_ssl BOOLEAN NOT NULL DEFAULT TRUE,
|
||
|
|
smtp_host VARCHAR(255) NOT NULL,
|
||
|
|
smtp_port INTEGER NOT NULL DEFAULT 587,
|
||
|
|
smtp_tls BOOLEAN NOT NULL DEFAULT TRUE,
|
||
|
|
username VARCHAR(255) NOT NULL,
|
||
|
|
encrypted_password TEXT NOT NULL,
|
||
|
|
is_shared BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_accounts_user ON mail_accounts(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_accounts_tenant ON mail_accounts(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_folders (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(255) NOT NULL,
|
||
|
|
imap_name VARCHAR(255) NOT NULL,
|
||
|
|
parent_id UUID REFERENCES mail_folders(id) ON DELETE CASCADE,
|
||
|
|
is_standard BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
unread_count INTEGER NOT NULL DEFAULT 0,
|
||
|
|
total_count INTEGER NOT NULL DEFAULT 0,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_folders_account ON mail_folders(account_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_folders_tenant ON mail_folders(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mails (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
folder_id UUID NOT NULL REFERENCES mail_folders(id) ON DELETE CASCADE,
|
||
|
|
message_id VARCHAR(512) NOT NULL,
|
||
|
|
thread_id VARCHAR(512) NOT NULL DEFAULT '',
|
||
|
|
in_reply_to VARCHAR(512),
|
||
|
|
references_header TEXT,
|
||
|
|
subject VARCHAR(512) NOT NULL DEFAULT '',
|
||
|
|
from_address VARCHAR(255) NOT NULL,
|
||
|
|
to_addresses TEXT NOT NULL DEFAULT '',
|
||
|
|
cc_addresses TEXT NOT NULL DEFAULT '',
|
||
|
|
bcc_addresses TEXT NOT NULL DEFAULT '',
|
||
|
|
body_text TEXT NOT NULL DEFAULT '',
|
||
|
|
body_html TEXT NOT NULL DEFAULT '',
|
||
|
|
body_html_sanitized TEXT NOT NULL DEFAULT '',
|
||
|
|
is_seen BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
is_draft BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
is_answered BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
is_forwarded BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
has_attachments BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
size_bytes INTEGER NOT NULL DEFAULT 0,
|
||
|
|
received_at TIMESTAMPTZ,
|
||
|
|
sent_at TIMESTAMPTZ,
|
||
|
|
contact_id UUID,
|
||
|
|
company_id UUID,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mails_folder ON mails(folder_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mails_account ON mails(account_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mails_tenant ON mails(tenant_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mails_thread ON mails(thread_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_attachments (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
|
||
|
|
filename VARCHAR(255) NOT NULL,
|
||
|
|
mime_type VARCHAR(255) NOT NULL DEFAULT 'application/octet-stream',
|
||
|
|
size_bytes INTEGER NOT NULL DEFAULT 0,
|
||
|
|
storage_path VARCHAR(1024) NOT NULL,
|
||
|
|
dms_file_id UUID,
|
||
|
|
content_id VARCHAR(255),
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_attachments_mail ON mail_attachments(mail_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_attachments_tenant ON mail_attachments(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_labels (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
name VARCHAR(100) NOT NULL,
|
||
|
|
color VARCHAR(20) NOT NULL DEFAULT '#808080',
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_labels_tenant ON mail_labels(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_label_assignments (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
|
||
|
|
label_id UUID NOT NULL REFERENCES mail_labels(id) ON DELETE CASCADE,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT uq_mail_label_assignment UNIQUE (mail_id, label_id)
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_label_assign_mail ON mail_label_assignments(mail_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_label_assign_label ON mail_label_assignments(label_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_rules (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(255) NOT NULL,
|
||
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
||
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||
|
|
conditions TEXT NOT NULL DEFAULT '{}',
|
||
|
|
actions TEXT NOT NULL DEFAULT '{}',
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_rules_account ON mail_rules(account_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_rules_tenant ON mail_rules(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_templates (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
name VARCHAR(255) NOT NULL,
|
||
|
|
subject VARCHAR(512) NOT NULL DEFAULT '',
|
||
|
|
body_html TEXT NOT NULL DEFAULT '',
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_templates_tenant ON mail_templates(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_signatures (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
account_id UUID REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(255) NOT NULL,
|
||
|
|
body_html TEXT NOT NULL DEFAULT '',
|
||
|
|
is_default BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_signatures_tenant ON mail_signatures(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS vacation_sent_log (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
sender_address VARCHAR(255) NOT NULL,
|
||
|
|
sent_at TIMESTAMPTZ NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_vacation_sent_log_account ON vacation_sent_log(account_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_vacation_sent_log_tenant ON vacation_sent_log(tenant_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_seen_by (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
seen_at TIMESTAMPTZ NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT uq_mail_seen_by UNIQUE (mail_id, user_id)
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_seen_by_mail ON mail_seen_by(mail_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_account_delegates (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
delegate_user_id UUID NOT NULL,
|
||
|
|
access_level VARCHAR(20) NOT NULL DEFAULT 'read',
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT uq_mail_delegate UNIQUE (account_id, delegate_user_id)
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_delegates_account ON mail_account_delegates(account_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS mail_account_send_permissions (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT uq_mail_send_perm UNIQUE (account_id, user_id)
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_mail_send_perms_account ON mail_account_send_permissions(account_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS pgp_keys (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
user_id UUID NOT NULL,
|
||
|
|
key_id VARCHAR(255) NOT NULL,
|
||
|
|
encrypted_private_key TEXT NOT NULL,
|
||
|
|
public_key_armored TEXT NOT NULL,
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_pgp_keys_user ON pgp_keys(user_id);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS contact_pgp_keys (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
contact_id UUID NOT NULL,
|
||
|
|
public_key_armored TEXT NOT NULL,
|
||
|
|
key_id VARCHAR(255) NOT NULL DEFAULT '',
|
||
|
|
tenant_id UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_contact_pgp_keys_contact ON contact_pgp_keys(contact_id);
|