-- Vorlagen: Demo-Webseiten, die wir Kunden zeigen. Layout und Design stecken im Code -- (modules/templates), hier liegen nur die angepassten Inhalte einer Variante. create table public.template_variants ( id uuid primary key default gen_random_uuid(), template_key text not null, name text not null, client_id uuid references public.profiles(id) on delete set null, content jsonb not null default '{}'::jsonb, -- Öffentlicher Link /demo/; null = nicht geteilt share_token text unique, share_expires_at timestamptz, created_by uuid references public.profiles(id) on delete set null default auth.uid(), created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create index template_variants_updated_idx on public.template_variants (updated_at desc); create index template_variants_client_idx on public.template_variants (client_id); create trigger set_updated_at before update on public.template_variants for each row execute function public.set_updated_at(); alter table public.template_variants enable row level security; create policy admin_all on public.template_variants for all to authenticated using ((select public.is_admin())) with check ((select public.is_admin())); -- Kunden ohne Login sehen genau eine Variante über ihren Token, die Tabelle bleibt für anon zu. create or replace function public.get_shared_template_variant(p_token text) returns table (template_key text, name text, content jsonb) language sql stable security definer set search_path = '' as $$ select v.template_key, v.name, v.content from public.template_variants v where v.share_token = p_token and (v.share_expires_at is null or v.share_expires_at > now()); $$; revoke all on function public.get_shared_template_variant(text) from public; grant execute on function public.get_shared_template_variant(text) to anon, authenticated;