diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0001_alerts.sql b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0001_alerts.sql new file mode 100644 index 00000000..a6c906af --- /dev/null +++ b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0001_alerts.sql @@ -0,0 +1,110 @@ +-- ©AngelaMos | 2026 +-- 0001_alerts.sql + +-- +goose Up +-- +goose StatementBegin +CREATE TABLE alert_rules ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, + name text NOT NULL, + topic text NOT NULL, + predicate text NOT NULL, + cooldown_sec integer NOT NULL DEFAULT 300, + enabled boolean NOT NULL DEFAULT true, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); +CREATE INDEX idx_alert_rules_user ON alert_rules(user_id) WHERE enabled = true; +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE alert_channels ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, + type text NOT NULL, + label text NOT NULL, + config_enc bytea NOT NULL, + nonce bytea NOT NULL, + invalid boolean NOT NULL DEFAULT false, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); +CREATE INDEX idx_alert_channels_user ON alert_channels(user_id); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE alert_rule_channels ( + rule_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE, + channel_id uuid NOT NULL REFERENCES alert_channels(id) ON DELETE CASCADE, + PRIMARY KEY (rule_id, channel_id) +); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE alert_history ( + id bigserial PRIMARY KEY, + rule_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE, + user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, + fired_at timestamptz NOT NULL DEFAULT now(), + payload jsonb NOT NULL, + delivered_to text[] NOT NULL DEFAULT '{}', + delivery_errors jsonb +); +CREATE INDEX idx_alert_history_user_time ON alert_history(user_id, fired_at DESC); +CREATE INDEX idx_alert_history_fired_brin ON alert_history USING BRIN (fired_at); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE telegram_webhooks ( + user_id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, + webhook_uuid uuid NOT NULL UNIQUE, + secret_token text NOT NULL, + bot_token_enc bytea NOT NULL, + bot_token_nonce bytea NOT NULL, + chat_id bigint, + pending_link boolean NOT NULL DEFAULT true, + created_at timestamptz NOT NULL DEFAULT now() +); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE user_preferences ( + user_id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, + watched_country text, + watched_asns integer[] NOT NULL DEFAULT '{}', + observer_lat double precision, + observer_lon double precision, + observer_alt_m double precision, + digest_enabled boolean NOT NULL DEFAULT false, + digest_local_tz text NOT NULL DEFAULT 'UTC', + digest_local_time time NOT NULL DEFAULT '08:00', + digest_window_hours integer NOT NULL DEFAULT 24, + digest_channel_ids uuid[] NOT NULL DEFAULT '{}', + chime_enabled boolean NOT NULL DEFAULT true, + chime_audio_object text, + presentation_default boolean NOT NULL DEFAULT false, + updated_at timestamptz NOT NULL DEFAULT now() +); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE digest_runs ( + user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, + fired_date date NOT NULL, + fired_at timestamptz NOT NULL DEFAULT now(), + status text NOT NULL, + error text, + PRIMARY KEY (user_id, fired_date) +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS digest_runs; +DROP TABLE IF EXISTS user_preferences; +DROP TABLE IF EXISTS telegram_webhooks; +DROP TABLE IF EXISTS alert_history; +DROP TABLE IF EXISTS alert_rule_channels; +DROP TABLE IF EXISTS alert_channels; +DROP TABLE IF EXISTS alert_rules; +-- +goose StatementEnd diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0002_panel_data.sql b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0002_panel_data.sql new file mode 100644 index 00000000..3bcd3169 --- /dev/null +++ b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0002_panel_data.sql @@ -0,0 +1,151 @@ +-- ©AngelaMos | 2026 +-- 0002_panel_data.sql + +-- +goose Up +-- +goose StatementBegin +CREATE TABLE cve_events ( + cve_id text PRIMARY KEY, + published timestamptz, + last_modified timestamptz NOT NULL, + severity text, + cvss_score numeric(3,1), + epss_score numeric(5,4), + epss_percentile numeric(5,4), + in_kev boolean NOT NULL DEFAULT false, + payload jsonb NOT NULL +); +CREATE INDEX idx_cve_lastmod_brin ON cve_events USING BRIN (last_modified); +CREATE INDEX idx_cve_severity_lastmod ON cve_events (severity, last_modified DESC); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE kev_entries ( + cve_id text PRIMARY KEY, + vendor text, + product text, + vulnerability_name text, + date_added date NOT NULL, + due_date date, + ransomware_use text, + payload jsonb NOT NULL +); +CREATE INDEX idx_kev_dateadded ON kev_entries (date_added DESC); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE earthquakes ( + id text PRIMARY KEY, + occurred_at timestamptz NOT NULL, + mag numeric(3,1) NOT NULL, + place text, + geom_lon double precision NOT NULL, + geom_lat double precision NOT NULL, + depth_km double precision, + payload jsonb NOT NULL +); +CREATE INDEX idx_quakes_time_brin ON earthquakes USING BRIN (occurred_at); +CREATE INDEX idx_quakes_mag ON earthquakes (mag DESC, occurred_at DESC); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE ransomware_victims ( + id text PRIMARY KEY, + post_title text NOT NULL, + group_name text NOT NULL, + discovered_at timestamptz NOT NULL, + country text, + sector text, + payload jsonb NOT NULL +); +CREATE INDEX idx_rans_time_brin ON ransomware_victims USING BRIN (discovered_at); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE btc_eth_ticks ( + symbol text NOT NULL, + ts timestamptz NOT NULL, + price numeric(18,8) NOT NULL, + volume_24h numeric(20,8), + PRIMARY KEY (symbol, ts) +); +CREATE INDEX idx_ticks_time_brin ON btc_eth_ticks USING BRIN (ts); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE btc_eth_minute ( + symbol text NOT NULL, + minute timestamptz NOT NULL, + open numeric(18,8) NOT NULL, + high numeric(18,8) NOT NULL, + low numeric(18,8) NOT NULL, + close numeric(18,8) NOT NULL, + volume numeric(20,8), + PRIMARY KEY (symbol, minute) +); +CREATE INDEX idx_minute_time_brin ON btc_eth_minute USING BRIN (minute); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE outage_events ( + id text PRIMARY KEY, + started_at timestamptz NOT NULL, + ended_at timestamptz, + locations text[] NOT NULL DEFAULT '{}', + asns integer[] NOT NULL DEFAULT '{}', + cause text, + outage_type text, + payload jsonb NOT NULL +); +CREATE INDEX idx_outage_start_brin ON outage_events USING BRIN (started_at); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE bgp_hijack_events ( + id bigint PRIMARY KEY, + detected_at timestamptz NOT NULL, + started_at timestamptz NOT NULL, + duration_sec integer, + confidence smallint, + hijacker_asn integer, + victim_asns integer[] NOT NULL DEFAULT '{}', + prefixes cidr[] NOT NULL DEFAULT '{}', + payload jsonb NOT NULL +); +CREATE INDEX idx_hijack_time_brin ON bgp_hijack_events USING BRIN (detected_at); +CREATE INDEX idx_hijack_conf_time ON bgp_hijack_events (confidence DESC, detected_at DESC); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE dshield_snapshots ( + ts timestamptz NOT NULL, + kind text NOT NULL, + payload jsonb NOT NULL, + PRIMARY KEY (ts, kind) +); +CREATE INDEX idx_dshield_ts_brin ON dshield_snapshots USING BRIN (ts); +-- +goose StatementEnd + +-- +goose StatementBegin +CREATE TABLE world_events ( + id text PRIMARY KEY, + source text NOT NULL, + occurred_at timestamptz NOT NULL, + headline text NOT NULL, + payload jsonb NOT NULL +); +CREATE INDEX idx_world_time_brin ON world_events USING BRIN (occurred_at); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS world_events; +DROP TABLE IF EXISTS dshield_snapshots; +DROP TABLE IF EXISTS bgp_hijack_events; +DROP TABLE IF EXISTS outage_events; +DROP TABLE IF EXISTS btc_eth_minute; +DROP TABLE IF EXISTS btc_eth_ticks; +DROP TABLE IF EXISTS ransomware_victims; +DROP TABLE IF EXISTS earthquakes; +DROP TABLE IF EXISTS kev_entries; +DROP TABLE IF EXISTS cve_events; +-- +goose StatementEnd diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0003_collector_state.sql b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0003_collector_state.sql new file mode 100644 index 00000000..29acdd36 --- /dev/null +++ b/PROJECTS/advanced/monitor-the-situation-dashboard/backend/migrations/0003_collector_state.sql @@ -0,0 +1,20 @@ +-- ©AngelaMos | 2026 +-- 0003_collector_state.sql + +-- +goose Up +-- +goose StatementBegin +CREATE TABLE collector_state ( + name text PRIMARY KEY, + state text NOT NULL, + last_success_at timestamptz, + last_error_at timestamptz, + last_error text, + last_event_count bigint NOT NULL DEFAULT 0, + updated_at timestamptz NOT NULL DEFAULT now() +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS collector_state; +-- +goose StatementEnd