@nextblock-cms/db 0.10.6 → 0.10.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/supabase/server.d.ts
CHANGED
|
@@ -1799,6 +1799,42 @@ export declare const getServiceRoleSupabaseClient: () => import('@supabase/supab
|
|
|
1799
1799
|
};
|
|
1800
1800
|
Relationships: [];
|
|
1801
1801
|
};
|
|
1802
|
+
system_alerts: {
|
|
1803
|
+
Row: {
|
|
1804
|
+
alert_type: string;
|
|
1805
|
+
created_at: string;
|
|
1806
|
+
id: string;
|
|
1807
|
+
is_resolved: boolean;
|
|
1808
|
+
message: string;
|
|
1809
|
+
metadata: import('./types').Json;
|
|
1810
|
+
resolved_at: string | null;
|
|
1811
|
+
title: string;
|
|
1812
|
+
updated_at: string;
|
|
1813
|
+
};
|
|
1814
|
+
Insert: {
|
|
1815
|
+
alert_type: string;
|
|
1816
|
+
created_at?: string;
|
|
1817
|
+
id?: string;
|
|
1818
|
+
is_resolved?: boolean;
|
|
1819
|
+
message: string;
|
|
1820
|
+
metadata?: import('./types').Json;
|
|
1821
|
+
resolved_at?: string | null;
|
|
1822
|
+
title: string;
|
|
1823
|
+
updated_at?: string;
|
|
1824
|
+
};
|
|
1825
|
+
Update: {
|
|
1826
|
+
alert_type?: string;
|
|
1827
|
+
created_at?: string;
|
|
1828
|
+
id?: string;
|
|
1829
|
+
is_resolved?: boolean;
|
|
1830
|
+
message?: string;
|
|
1831
|
+
metadata?: import('./types').Json;
|
|
1832
|
+
resolved_at?: string | null;
|
|
1833
|
+
title?: string;
|
|
1834
|
+
updated_at?: string;
|
|
1835
|
+
};
|
|
1836
|
+
Relationships: [];
|
|
1837
|
+
};
|
|
1802
1838
|
system_configuration: {
|
|
1803
1839
|
Row: {
|
|
1804
1840
|
auto_accept_signups: boolean;
|
package/lib/supabase/types.d.ts
CHANGED
|
@@ -1867,6 +1867,42 @@ export type Database = {
|
|
|
1867
1867
|
};
|
|
1868
1868
|
Relationships: [];
|
|
1869
1869
|
};
|
|
1870
|
+
system_alerts: {
|
|
1871
|
+
Row: {
|
|
1872
|
+
alert_type: string;
|
|
1873
|
+
created_at: string;
|
|
1874
|
+
id: string;
|
|
1875
|
+
is_resolved: boolean;
|
|
1876
|
+
message: string;
|
|
1877
|
+
metadata: Json;
|
|
1878
|
+
resolved_at: string | null;
|
|
1879
|
+
title: string;
|
|
1880
|
+
updated_at: string;
|
|
1881
|
+
};
|
|
1882
|
+
Insert: {
|
|
1883
|
+
alert_type: string;
|
|
1884
|
+
created_at?: string;
|
|
1885
|
+
id?: string;
|
|
1886
|
+
is_resolved?: boolean;
|
|
1887
|
+
message: string;
|
|
1888
|
+
metadata?: Json;
|
|
1889
|
+
resolved_at?: string | null;
|
|
1890
|
+
title: string;
|
|
1891
|
+
updated_at?: string;
|
|
1892
|
+
};
|
|
1893
|
+
Update: {
|
|
1894
|
+
alert_type?: string;
|
|
1895
|
+
created_at?: string;
|
|
1896
|
+
id?: string;
|
|
1897
|
+
is_resolved?: boolean;
|
|
1898
|
+
message?: string;
|
|
1899
|
+
metadata?: Json;
|
|
1900
|
+
resolved_at?: string | null;
|
|
1901
|
+
title?: string;
|
|
1902
|
+
updated_at?: string;
|
|
1903
|
+
};
|
|
1904
|
+
Relationships: [];
|
|
1905
|
+
};
|
|
1870
1906
|
system_configuration: {
|
|
1871
1907
|
Row: {
|
|
1872
1908
|
auto_accept_signups: boolean;
|
package/package.json
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- System notification layer for the automated upstream-update architecture.
|
|
2
|
+
--
|
|
3
|
+
-- `system_alerts` is the single sink that every update track writes into:
|
|
4
|
+
-- * Track A (the .github/workflows/nextblock-sync.yml GitHub Action) inserts a
|
|
5
|
+
-- 'merge_conflict' row via the Supabase REST API when an upstream merge can't be
|
|
6
|
+
-- auto-resolved, so the CMS dashboard can point an operator at GitHub to sort it.
|
|
7
|
+
-- * Track B (the runtime update engine, app/api/cms/check-updates) inserts a
|
|
8
|
+
-- 'runtime_update_available' row for non-git installs (npm create / local / Docker)
|
|
9
|
+
-- with a download link to the latest verified release tarball.
|
|
10
|
+
-- The dashboard banner (cms/layout.tsx -> SystemAlertsBanner) renders unresolved rows.
|
|
11
|
+
--
|
|
12
|
+
-- Writers always use the service-role key (REST API / getServiceRoleSupabaseClient),
|
|
13
|
+
-- which bypasses RLS; RLS below only governs who can READ/RESOLVE from the dashboard.
|
|
14
|
+
|
|
15
|
+
create table if not exists public.system_alerts (
|
|
16
|
+
id uuid primary key default gen_random_uuid(),
|
|
17
|
+
-- The notification kind. Constrained to the two tracks this system emits; widen the
|
|
18
|
+
-- CHECK in a later migration if new alert kinds are added.
|
|
19
|
+
alert_type text not null check (alert_type in ('merge_conflict', 'runtime_update_available')),
|
|
20
|
+
title text not null,
|
|
21
|
+
message text not null,
|
|
22
|
+
-- Structured context for deep-linking the banner CTA, e.g.
|
|
23
|
+
-- merge_conflict -> { "repo": "owner/name", "branch": "...", "action_url": "https://github.com/owner/name/branches" }
|
|
24
|
+
-- runtime_update_available -> { "latest_version": "0.11.0", "download_url": "https://github.com/.../v0.11.0.tar.gz" }
|
|
25
|
+
metadata jsonb not null default '{}'::jsonb,
|
|
26
|
+
is_resolved boolean not null default false,
|
|
27
|
+
resolved_at timestamptz,
|
|
28
|
+
created_at timestamptz not null default now(),
|
|
29
|
+
updated_at timestamptz not null default now()
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
comment on table public.system_alerts is 'System notifications for the automated upstream-update architecture (merge conflicts, runtime updates available). Written by service-role; read by ADMINs.';
|
|
33
|
+
comment on column public.system_alerts.alert_type is 'One of: merge_conflict, runtime_update_available.';
|
|
34
|
+
comment on column public.system_alerts.metadata is 'Structured deep-link context for the dashboard banner CTA (repo/branch/action_url or latest_version/download_url).';
|
|
35
|
+
comment on column public.system_alerts.is_resolved is 'When true the alert is hidden from the dashboard banner.';
|
|
36
|
+
|
|
37
|
+
-- Banner query: unresolved alerts, newest first.
|
|
38
|
+
create index if not exists idx_system_alerts_unresolved
|
|
39
|
+
on public.system_alerts (is_resolved, created_at desc);
|
|
40
|
+
|
|
41
|
+
-- Keep updated_at fresh on every mutation (same helper used across the schema).
|
|
42
|
+
drop trigger if exists trg_system_alerts_updated_at on public.system_alerts;
|
|
43
|
+
create trigger trg_system_alerts_updated_at
|
|
44
|
+
before update on public.system_alerts
|
|
45
|
+
for each row
|
|
46
|
+
execute function public.set_current_timestamp_updated_at();
|
|
47
|
+
|
|
48
|
+
alter table public.system_alerts enable row level security;
|
|
49
|
+
|
|
50
|
+
-- Only authenticated ADMINs may view alerts in the dashboard. WRITERs and the public
|
|
51
|
+
-- anon role get zero rows (RLS default-deny: no policy applies to them).
|
|
52
|
+
drop policy if exists system_alerts_select_admin on public.system_alerts;
|
|
53
|
+
create policy system_alerts_select_admin
|
|
54
|
+
on public.system_alerts
|
|
55
|
+
for select
|
|
56
|
+
to authenticated
|
|
57
|
+
using ((select public.get_current_user_role()) = 'ADMIN');
|
|
58
|
+
|
|
59
|
+
-- ADMINs may resolve (dismiss) alerts from the dashboard. Inserts are service-role only
|
|
60
|
+
-- (RLS-bypassing), so there is intentionally no INSERT policy.
|
|
61
|
+
drop policy if exists system_alerts_update_admin on public.system_alerts;
|
|
62
|
+
create policy system_alerts_update_admin
|
|
63
|
+
on public.system_alerts
|
|
64
|
+
for update
|
|
65
|
+
to authenticated
|
|
66
|
+
using ((select public.get_current_user_role()) = 'ADMIN')
|
|
67
|
+
with check ((select public.get_current_user_role()) = 'ADMIN');
|
|
68
|
+
|
|
69
|
+
-- Base table privileges (RLS still filters rows on top of these). Mirrors the grant
|
|
70
|
+
-- model the rest of the schema uses; service_role keeps full access for the writers.
|
|
71
|
+
grant select, update on public.system_alerts to authenticated;
|
|
72
|
+
grant all on public.system_alerts to service_role;
|