forked from wangziqi/gongxue-base
115 lines
5.3 KiB
SQL
115 lines
5.3 KiB
SQL
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();
|