forked from wangziqi/gongxue-base
feat: add platform audit alert notifications
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
create table if not exists app_private.platform_secrets (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
secret_scope text not null check (secret_scope in ('webhook', 'sms', 'email', 'payment', 'system', 'ai')),
|
||||
secret_key text not null,
|
||||
secret_value text,
|
||||
secret_json jsonb not null default '{}'::jsonb,
|
||||
provider text,
|
||||
last_rotated_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (secret_scope, secret_key)
|
||||
);
|
||||
|
||||
comment on table app_private.platform_secrets is
|
||||
'Private platform-level secrets for SaaS operations. API responses must expose only secretRef/masked metadata.';
|
||||
|
||||
create table if not exists public.platform_audit_notification_channels (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
channel_code text not null unique,
|
||||
name text not null,
|
||||
description text,
|
||||
enabled boolean not null default true,
|
||||
provider text not null default 'generic'
|
||||
check (provider in ('generic', 'dingtalk', 'feishu', 'wecom')),
|
||||
webhook_url text not null,
|
||||
secret_ref text,
|
||||
min_severity text not null default 'medium'
|
||||
check (min_severity in ('low', 'medium', 'high', 'critical')),
|
||||
status_filter text[] not null default array['open']::text[],
|
||||
action_patterns text[] not null default '{}'::text[],
|
||||
tenant_ids uuid[] not null default '{}'::uuid[],
|
||||
timeout_sec integer not null default 10 check (timeout_sec between 1 and 60),
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
constraint platform_audit_notification_status_filter_check
|
||||
check (status_filter <@ array['open', 'acknowledged', 'resolved', 'ignored']::text[])
|
||||
);
|
||||
|
||||
create table if not exists public.platform_audit_notification_events (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
channel_id uuid not null references public.platform_audit_notification_channels(id) on delete cascade,
|
||||
alert_id uuid not null references public.platform_audit_alerts(id) on delete cascade,
|
||||
audit_log_id uuid references public.audit_logs(id) on delete set null,
|
||||
provider text not null default 'generic'
|
||||
check (provider in ('generic', 'dingtalk', 'feishu', 'wecom')),
|
||||
status text not null default 'pending'
|
||||
check (status in ('pending', 'processing', 'sent', 'retrying', 'failed', 'discarded')),
|
||||
attempts integer not null default 0 check (attempts >= 0),
|
||||
scheduled_at timestamptz not null default now(),
|
||||
next_attempt_at timestamptz,
|
||||
last_attempt_at timestamptz,
|
||||
sent_at timestamptz,
|
||||
last_error text,
|
||||
last_http_code integer,
|
||||
last_response_summary text,
|
||||
request_payload jsonb not null default '{}'::jsonb,
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (channel_id, alert_id)
|
||||
);
|
||||
|
||||
create index if not exists idx_platform_audit_notification_channels_enabled
|
||||
on public.platform_audit_notification_channels(enabled, min_severity, channel_code);
|
||||
|
||||
create index if not exists idx_platform_audit_notification_events_due
|
||||
on public.platform_audit_notification_events(status, coalesce(next_attempt_at, scheduled_at), created_at);
|
||||
|
||||
create index if not exists idx_platform_audit_notification_events_alert
|
||||
on public.platform_audit_notification_events(alert_id, status, created_at desc);
|
||||
|
||||
create index if not exists idx_platform_audit_notification_events_channel
|
||||
on public.platform_audit_notification_events(channel_id, status, created_at desc);
|
||||
|
||||
create index if not exists idx_platform_secrets_lookup
|
||||
on app_private.platform_secrets(secret_scope, secret_key);
|
||||
|
||||
alter table app_private.platform_secrets enable row level security;
|
||||
alter table public.platform_audit_notification_channels enable row level security;
|
||||
alter table public.platform_audit_notification_events enable row level security;
|
||||
|
||||
drop policy if exists platform_admin_platform_secrets on app_private.platform_secrets;
|
||||
create policy platform_admin_platform_secrets on app_private.platform_secrets
|
||||
for all
|
||||
using (app.is_platform_admin())
|
||||
with check (app.is_platform_admin());
|
||||
|
||||
drop policy if exists platform_admin_audit_notification_channels on public.platform_audit_notification_channels;
|
||||
create policy platform_admin_audit_notification_channels on public.platform_audit_notification_channels
|
||||
for all
|
||||
using (app.is_platform_admin())
|
||||
with check (app.is_platform_admin());
|
||||
|
||||
drop policy if exists platform_admin_audit_notification_events on public.platform_audit_notification_events;
|
||||
create policy platform_admin_audit_notification_events on public.platform_audit_notification_events
|
||||
for all
|
||||
using (app.is_platform_admin())
|
||||
with check (app.is_platform_admin());
|
||||
|
||||
drop trigger if exists set_updated_at on app_private.platform_secrets;
|
||||
create trigger set_updated_at
|
||||
before update on app_private.platform_secrets
|
||||
for each row execute function app.touch_updated_at();
|
||||
|
||||
drop trigger if exists set_updated_at on public.platform_audit_notification_channels;
|
||||
create trigger set_updated_at
|
||||
before update on public.platform_audit_notification_channels
|
||||
for each row execute function app.touch_updated_at();
|
||||
|
||||
drop trigger if exists set_updated_at on public.platform_audit_notification_events;
|
||||
create trigger set_updated_at
|
||||
before update on public.platform_audit_notification_events
|
||||
for each row execute function app.touch_updated_at();
|
||||
Reference in New Issue
Block a user