CREATE OR REPLACE FUNCTION public.user_belongs_to_association(_user_id uuid, _association_id uuid) RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$ SELECT public.has_role(_user_id, 'admin'::public.app_role) OR public.has_role(_user_id, 'manager'::public.app_role) OR EXISTS ( SELECT 1 FROM public.owners o WHERE o.user_id = _user_id AND o.association_id = _association_id ) OR EXISTS ( SELECT 1 FROM public.board_members bm WHERE bm.user_id = _user_id AND bm.association_id = _association_id ) $$; CREATE OR REPLACE FUNCTION public.can_comment_on_status_update(_user_id uuid, _status_update_id uuid) RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$ SELECT EXISTS ( SELECT 1 FROM public.status_updates su WHERE su.id = _status_update_id AND public.user_belongs_to_association(_user_id, su.association_id) ) $$; CREATE OR REPLACE FUNCTION public.can_comment_on_entity(_user_id uuid, _entity_type text, _entity_id uuid) RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$ SELECT CASE _entity_type WHEN 'board_vote' THEN EXISTS ( SELECT 1 FROM public.board_votes bv WHERE bv.id = _entity_id AND public.user_belongs_to_association(_user_id, bv.association_id) ) WHEN 'legal_matter' THEN EXISTS ( SELECT 1 FROM public.legal_matters lm WHERE lm.id = _entity_id AND public.user_belongs_to_association(_user_id, lm.association_id) ) WHEN 'bid_quote' THEN EXISTS ( SELECT 1 FROM public.bids_quotes bq WHERE bq.id = _entity_id AND public.user_belongs_to_association(_user_id, bq.association_id) ) WHEN 'arc_application' THEN EXISTS ( SELECT 1 FROM public.arc_applications aa WHERE aa.id = _entity_id AND public.user_belongs_to_association(_user_id, aa.association_id) ) WHEN 'client_request' THEN EXISTS ( SELECT 1 FROM public.client_requests cr WHERE cr.id = _entity_id AND public.user_belongs_to_association(_user_id, cr.association_id) ) WHEN 'status_update' THEN public.can_comment_on_status_update(_user_id, _entity_id) ELSE false END $$; ALTER POLICY "Authenticated users can insert status_update_comments" ON public.status_update_comments WITH CHECK ( auth.uid() = user_id AND public.can_comment_on_status_update(auth.uid(), status_update_id) ); ALTER POLICY "Authenticated users can insert own entity_comments" ON public.entity_comments WITH CHECK ( auth.uid() = user_id AND public.can_comment_on_entity(auth.uid(), entity_type, entity_id) );