-- Add authorization guard to match_incidents to enforce DB-level access control. -- Without this, SECURITY DEFINER bypasses RLS for any direct caller. create or replace function match_incidents( query_embedding vector(1024), exclude_id uuid, match_count int default 5 ) returns table ( id uuid, reference_no text, incident_type text, description text, severity int, similarity float ) language plpgsql security definer as $$ begin -- Enforce that only hse/admin roles can call this function directly if not exists ( select 1 from public.users where id = auth.uid() and role in ('hse', 'admin') ) then raise exception 'Forbidden' using errcode = 'PGRST301'; end if; return query select i.id, i.reference_no, i.incident_type, i.description, i.severity, 1 - (i.embedding <=> query_embedding) as similarity from incidents i where i.id != exclude_id and i.embedding is not null order by i.embedding <=> query_embedding limit match_count; end; $$;