153 lines
5.7 KiB
PL/PgSQL
153 lines
5.7 KiB
PL/PgSQL
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
CREATE OR REPLACE FUNCTION set_updated_at()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = now();
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
user_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
username text NOT NULL UNIQUE,
|
|
password_hash text NOT NULL,
|
|
display_name text NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
DROP TRIGGER IF EXISTS users_set_updated_at ON users;
|
|
CREATE TRIGGER users_set_updated_at
|
|
BEFORE UPDATE ON users
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS user_totp (
|
|
user_id uuid PRIMARY KEY REFERENCES users(user_id) ON DELETE CASCADE,
|
|
otp_secret text NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
DROP TRIGGER IF EXISTS user_totp_set_updated_at ON user_totp;
|
|
CREATE TRIGGER user_totp_set_updated_at
|
|
BEFORE UPDATE ON user_totp
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
session_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
|
|
expires_at timestamptz NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS sessions_user_id_idx ON sessions(user_id);
|
|
CREATE INDEX IF NOT EXISTS sessions_expires_at_idx ON sessions(expires_at);
|
|
|
|
DROP TRIGGER IF EXISTS sessions_set_updated_at ON sessions;
|
|
CREATE TRIGGER sessions_set_updated_at
|
|
BEFORE UPDATE ON sessions
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS sites (
|
|
site_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
|
|
url text NOT NULL,
|
|
alias text NOT NULL,
|
|
certificate_issuer text,
|
|
certificate_issued_at timestamptz,
|
|
certificate_expires_at timestamptz,
|
|
certificate_checked_at timestamptz,
|
|
certificate_check_error text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE (user_id, url)
|
|
);
|
|
|
|
ALTER TABLE sites
|
|
ADD COLUMN IF NOT EXISTS certificate_issuer text,
|
|
ADD COLUMN IF NOT EXISTS certificate_issued_at timestamptz,
|
|
ADD COLUMN IF NOT EXISTS certificate_expires_at timestamptz,
|
|
ADD COLUMN IF NOT EXISTS certificate_checked_at timestamptz,
|
|
ADD COLUMN IF NOT EXISTS certificate_check_error text;
|
|
|
|
CREATE INDEX IF NOT EXISTS sites_user_id_idx ON sites(user_id);
|
|
|
|
DROP TRIGGER IF EXISTS sites_set_updated_at ON sites;
|
|
CREATE TRIGGER sites_set_updated_at
|
|
BEFORE UPDATE ON sites
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS notification_methods (
|
|
notification_method_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
|
|
notification_type text NOT NULL CHECK (notification_type IN ('webhook', 'push')),
|
|
alias text NOT NULL,
|
|
url text,
|
|
push_endpoint text,
|
|
push_p256dh text,
|
|
push_auth text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS notification_methods_user_id_idx ON notification_methods(user_id);
|
|
|
|
DROP TRIGGER IF EXISTS notification_methods_set_updated_at ON notification_methods;
|
|
CREATE TRIGGER notification_methods_set_updated_at
|
|
BEFORE UPDATE ON notification_methods
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS site_alert_conditions (
|
|
site_alert_condition_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
site_id uuid NOT NULL REFERENCES sites(site_id) ON DELETE CASCADE,
|
|
condition_type text NOT NULL CHECK (condition_type IN ('expires_within_hours')),
|
|
threshold_hours integer NOT NULL CHECK (threshold_hours > 0 AND threshold_hours <= 17520),
|
|
webhook_method_ids uuid[] NOT NULL DEFAULT '{}',
|
|
push_enabled boolean NOT NULL DEFAULT false,
|
|
last_notified_certificate_expires_at timestamptz,
|
|
last_notified_at timestamptz,
|
|
last_notification_skipped_at timestamptz,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE (site_id, condition_type, threshold_hours)
|
|
);
|
|
|
|
ALTER TABLE site_alert_conditions
|
|
ADD COLUMN IF NOT EXISTS last_notified_certificate_expires_at timestamptz,
|
|
ADD COLUMN IF NOT EXISTS last_notified_at timestamptz,
|
|
ADD COLUMN IF NOT EXISTS last_notification_skipped_at timestamptz;
|
|
|
|
CREATE INDEX IF NOT EXISTS site_alert_conditions_site_id_idx ON site_alert_conditions(site_id);
|
|
|
|
DROP TRIGGER IF EXISTS site_alert_conditions_set_updated_at ON site_alert_conditions;
|
|
CREATE TRIGGER site_alert_conditions_set_updated_at
|
|
BEFORE UPDATE ON site_alert_conditions
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE IF NOT EXISTS alert_history (
|
|
alert_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
|
|
site_id uuid REFERENCES sites(site_id) ON DELETE SET NULL,
|
|
alert_type text NOT NULL,
|
|
content text NOT NULL,
|
|
occurred_at timestamptz NOT NULL DEFAULT now(),
|
|
read_at timestamptz,
|
|
delivery_channels text[] NOT NULL DEFAULT ARRAY['app'],
|
|
delivery_result jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
dedupe_key text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE (user_id, dedupe_key)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS alert_history_user_id_idx ON alert_history(user_id);
|
|
CREATE INDEX IF NOT EXISTS alert_history_site_id_idx ON alert_history(site_id);
|
|
CREATE INDEX IF NOT EXISTS alert_history_occurred_at_idx ON alert_history(occurred_at);
|
|
|
|
DROP TRIGGER IF EXISTS alert_history_set_updated_at ON alert_history;
|
|
CREATE TRIGGER alert_history_set_updated_at
|
|
BEFORE UPDATE ON alert_history
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|