forked from wangziqi/gongxue-base
feat: add platform dunning notifications
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
create table if not exists public.platform_dunning_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,
|
||||
reminder_types text[] not null default array['overdue', 'final_notice']::text[],
|
||||
reminder_channels text[] not null default array['internal']::text[],
|
||||
min_reminder_level integer not null default 1 check (min_reminder_level between 1 and 20),
|
||||
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_dunning_notification_reminder_types_check
|
||||
check (reminder_types <@ array['due_soon', 'overdue', 'final_notice', 'manual']::text[]),
|
||||
constraint platform_dunning_notification_reminder_channels_check
|
||||
check (reminder_channels <@ array['manual', 'internal', 'sms', 'email', 'wechat', 'crm']::text[])
|
||||
);
|
||||
|
||||
create table if not exists public.platform_dunning_notification_events (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
channel_id uuid not null references public.platform_dunning_notification_channels(id) on delete cascade,
|
||||
reminder_id uuid not null references public.tenant_invoice_reminders(id) on delete cascade,
|
||||
invoice_id uuid not null references public.tenant_invoices(id) on delete cascade,
|
||||
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
||||
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, reminder_id)
|
||||
);
|
||||
|
||||
create index if not exists idx_platform_dunning_notification_channels_enabled
|
||||
on public.platform_dunning_notification_channels(enabled, min_reminder_level, channel_code);
|
||||
|
||||
create index if not exists idx_platform_dunning_notification_events_due
|
||||
on public.platform_dunning_notification_events(status, coalesce(next_attempt_at, scheduled_at), created_at);
|
||||
|
||||
create index if not exists idx_platform_dunning_notification_events_reminder
|
||||
on public.platform_dunning_notification_events(reminder_id, status, created_at desc);
|
||||
|
||||
create index if not exists idx_platform_dunning_notification_events_invoice
|
||||
on public.platform_dunning_notification_events(invoice_id, status, created_at desc);
|
||||
|
||||
create index if not exists idx_platform_dunning_notification_events_tenant
|
||||
on public.platform_dunning_notification_events(tenant_id, status, created_at desc);
|
||||
|
||||
alter table public.platform_dunning_notification_channels enable row level security;
|
||||
alter table public.platform_dunning_notification_events enable row level security;
|
||||
|
||||
drop policy if exists platform_admin_dunning_notification_channels on public.platform_dunning_notification_channels;
|
||||
create policy platform_admin_dunning_notification_channels on public.platform_dunning_notification_channels
|
||||
for all
|
||||
using (app.is_platform_admin())
|
||||
with check (app.is_platform_admin());
|
||||
|
||||
drop policy if exists platform_admin_dunning_notification_events on public.platform_dunning_notification_events;
|
||||
create policy platform_admin_dunning_notification_events on public.platform_dunning_notification_events
|
||||
for all
|
||||
using (app.is_platform_admin())
|
||||
with check (app.is_platform_admin());
|
||||
|
||||
drop trigger if exists set_updated_at on public.platform_dunning_notification_channels;
|
||||
create trigger set_updated_at
|
||||
before update on public.platform_dunning_notification_channels
|
||||
for each row execute function app.touch_updated_at();
|
||||
|
||||
drop trigger if exists set_updated_at on public.platform_dunning_notification_events;
|
||||
create trigger set_updated_at
|
||||
before update on public.platform_dunning_notification_events
|
||||
for each row execute function app.touch_updated_at();
|
||||
Reference in New Issue
Block a user