changes
This commit is contained in:
@@ -1,63 +1,147 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
hostname TEXT NOT NULL,
|
||||
is_current BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS domains (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain TEXT UNIQUE NOT NULL,
|
||||
current_node TEXT NOT NULL,
|
||||
node_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
first_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ,
|
||||
last_synced_at TIMESTAMPTZ,
|
||||
notes TEXT DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
first_seen_at TIMESTAMPTZ DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS mailboxes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
id SERIAL PRIMARY KEY,
|
||||
email_address TEXT UNIQUE NOT NULL,
|
||||
local_part TEXT NOT NULL,
|
||||
domain TEXT NOT NULL REFERENCES domains(domain) ON DELETE CASCADE,
|
||||
domain TEXT NOT NULL,
|
||||
node_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
usage_scanned_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
used_bytes BIGINT DEFAULT 0,
|
||||
last_usage_scan_at TIMESTAMPTZ,
|
||||
first_seen_at TIMESTAMPTZ DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS admin_users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
id SERIAL PRIMARY KEY,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'super_admin',
|
||||
allowed_domains TEXT[] NOT NULL DEFAULT '{}',
|
||||
active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
id SERIAL PRIMARY KEY,
|
||||
actor_email TEXT,
|
||||
action TEXT NOT NULL,
|
||||
target_type TEXT NOT NULL,
|
||||
target_id TEXT NOT NULL,
|
||||
details JSONB NOT NULL DEFAULT '{}',
|
||||
ip_address TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
target TEXT,
|
||||
details JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_domains_node ON domains(current_node);
|
||||
CREATE INDEX IF NOT EXISTS idx_mailboxes_domain ON mailboxes(domain);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_created ON audit_log(created_at DESC);
|
||||
-- ============================================================
|
||||
-- Upgrade existing MVP database
|
||||
-- ============================================================
|
||||
|
||||
ALTER TABLE nodes
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
|
||||
|
||||
ALTER TABLE nodes
|
||||
ADD COLUMN IF NOT EXISTS is_current BOOLEAN DEFAULT false;
|
||||
|
||||
ALTER TABLE domains
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
|
||||
|
||||
ALTER TABLE domains
|
||||
ADD COLUMN IF NOT EXISTS last_synced_at TIMESTAMPTZ;
|
||||
|
||||
ALTER TABLE domains
|
||||
ADD COLUMN IF NOT EXISTS notes TEXT DEFAULT '';
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS local_part TEXT;
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS quota_bytes BIGINT;
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS quota_percent NUMERIC(8,3);
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS message_count BIGINT;
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS message_limit BIGINT;
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS usage_scanned_at TIMESTAMPTZ;
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
|
||||
|
||||
ALTER TABLE mailboxes
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||
|
||||
ALTER TABLE admin_users
|
||||
ADD COLUMN IF NOT EXISTS allowed_domains TEXT[] NOT NULL DEFAULT '{}';
|
||||
|
||||
ALTER TABLE admin_users
|
||||
ADD COLUMN IF NOT EXISTS active BOOLEAN NOT NULL DEFAULT true;
|
||||
|
||||
ALTER TABLE admin_users
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();
|
||||
|
||||
ALTER TABLE audit_log
|
||||
ADD COLUMN IF NOT EXISTS target_type TEXT;
|
||||
|
||||
ALTER TABLE audit_log
|
||||
ADD COLUMN IF NOT EXISTS target_id TEXT;
|
||||
|
||||
ALTER TABLE audit_log
|
||||
ADD COLUMN IF NOT EXISTS ip_address TEXT;
|
||||
|
||||
-- details existed already, but make it safer for newer code
|
||||
ALTER TABLE audit_log
|
||||
ALTER COLUMN details SET DEFAULT '{}';
|
||||
|
||||
-- Fill local_part for existing rows
|
||||
UPDATE mailboxes
|
||||
SET local_part = split_part(email_address, '@', 1)
|
||||
WHERE local_part IS NULL
|
||||
AND email_address LIKE '%@%';
|
||||
|
||||
-- Keep old and new usage timestamp columns in sync initially
|
||||
UPDATE mailboxes
|
||||
SET usage_scanned_at = last_usage_scan_at
|
||||
WHERE usage_scanned_at IS NULL
|
||||
AND last_usage_scan_at IS NOT NULL;
|
||||
|
||||
-- Backfill new audit target columns from old target column
|
||||
UPDATE audit_log
|
||||
SET target_id = target
|
||||
WHERE target_id IS NULL
|
||||
AND target IS NOT NULL;
|
||||
|
||||
UPDATE audit_log
|
||||
SET target_type = 'unknown'
|
||||
WHERE target_type IS NULL;
|
||||
|
||||
-- Useful indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_domains_node_name
|
||||
ON domains(node_name);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_mailboxes_domain
|
||||
ON mailboxes(domain);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_mailboxes_node_name
|
||||
ON mailboxes(node_name);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_created
|
||||
ON audit_log(created_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_admin_users_allowed_domains
|
||||
ON admin_users USING GIN(allowed_domains);
|
||||
Reference in New Issue
Block a user