feat: add user notification center

This commit is contained in:
Codex
2026-06-30 03:56:41 +08:00
parent 2fea68fe4d
commit d72ff499ce
24 changed files with 895 additions and 44 deletions

View File

@@ -0,0 +1,64 @@
create table if not exists public.user_notifications (
id uuid primary key default gen_random_uuid(),
tenant_id uuid not null references public.tenants(id) on delete cascade,
user_id uuid not null references public.platform_users(id) on delete cascade,
notification_type text not null,
status text not null default 'unread'
check (status in ('unread', 'read', 'dismissed', 'archived')),
severity text not null default 'info'
check (severity in ('info', 'success', 'warning', 'error')),
title text not null,
message text not null,
action_label text,
action_path text,
source_type text,
source_id uuid,
dedupe_key text,
metadata jsonb not null default '{}'::jsonb,
created_by uuid references public.platform_users(id) on delete set null,
read_at timestamptz,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
comment on table public.user_notifications is
'Tenant-scoped in-app notification inbox for students and tenant members. Business services create records; frontends only display and mark status through API.';
create unique index if not exists idx_user_notifications_dedupe
on public.user_notifications(tenant_id, user_id, notification_type, dedupe_key)
where dedupe_key is not null;
create index if not exists idx_user_notifications_user_status
on public.user_notifications(tenant_id, user_id, status, created_at desc);
create index if not exists idx_user_notifications_source
on public.user_notifications(tenant_id, source_type, source_id);
alter table public.user_notifications enable row level security;
drop policy if exists user_notifications_owner_select on public.user_notifications;
create policy user_notifications_owner_select on public.user_notifications
for select
using (
tenant_id = app.current_tenant_id()
and (
app.is_platform_admin()
or exists (
select 1
from public.platform_users pu
where pu.id = user_notifications.user_id
and pu.auth_user_id = auth.uid()
)
)
);
drop policy if exists user_notifications_platform_admin_all on public.user_notifications;
create policy user_notifications_platform_admin_all on public.user_notifications
for all
using (app.is_platform_admin())
with check (app.is_platform_admin());
drop trigger if exists set_updated_at on public.user_notifications;
create trigger set_updated_at
before update on public.user_notifications
for each row execute function app.touch_updated_at();