-- 0001_admin.sql -- Additive, idempotent migration for the LinumIQ admin interface. -- Safe to run multiple times. -- 1. Admin audit log ------------------------------------------------------- create table if not exists public.admin_audit_log ( id bigint generated always as identity primary key, actor_id uuid, actor_email text, action text not null, target_type text, target_id text, details jsonb not null default '{}'::jsonb, created_at timestamptz not null default now() ); create index if not exists admin_audit_log_created_at_idx on public.admin_audit_log (created_at desc); -- 2. Reserved subdomains --------------------------------------------------- create table if not exists public.reserved_subdomains ( name text primary key, created_at timestamptz not null default now() ); -- Seed with the current hardcoded reserved names (lib/validation.ts). insert into public.reserved_subdomains (name) values ('app'), ('api'), ('www'), ('admin'), ('auth'), ('mail'), ('static') on conflict (name) do nothing; -- 3. Lock down with RLS, NO policies --------------------------------------- -- RLS is enabled with NO policies so that the anon/authenticated roles cannot -- read or write these tables at all. The application performs every admin -- operation through the service-role client, which bypasses RLS. This keeps -- the audit log and reserved list inaccessible to ordinary users. alter table public.admin_audit_log enable row level security; alter table public.reserved_subdomains enable row level security; comment on table public.admin_audit_log is 'Admin action audit trail. RLS enabled with no policies: service-role only.'; comment on table public.reserved_subdomains is 'Reserved subdomain names (admin-managed). RLS enabled with no policies: service-role only.';