-- Helper: check if a user is an active ARC committee member of an association (matched by email) CREATE OR REPLACE FUNCTION public.is_arc_committee_member_of_association(_user_id uuid, _association_id uuid) RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path TO 'public' AS $$ SELECT EXISTS ( SELECT 1 FROM public.arc_committee_members acm JOIN auth.users u ON lower(u.email) = lower(acm.email) WHERE u.id = _user_id AND acm.association_id = _association_id AND acm.is_active = true AND acm.email IS NOT NULL ); $$; -- Extend can_comment_on_entity so ARC committee members can vote/comment on ARC applications 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 TO '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) OR ( public.has_role(_user_id, 'legal'::public.app_role) AND public.legal_user_assigned_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) OR ( public.has_role(_user_id, 'arc_member'::public.app_role) AND public.is_arc_committee_member_of_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 'homeowner_request' THEN EXISTS ( SELECT 1 FROM public.homeowner_requests hr LEFT JOIN public.owners o ON o.id = hr.owner_id WHERE hr.id = _entity_id AND ( public.user_belongs_to_association(_user_id, hr.association_id) OR o.user_id = _user_id ) ) WHEN 'status_update' THEN public.can_comment_on_status_update(_user_id, _entity_id) ELSE false END $$; -- Allow ARC committee members to view ARC applications for their associations CREATE POLICY "ARC committee members can view association ARC applications" ON public.arc_applications FOR SELECT TO authenticated USING ( public.has_role(auth.uid(), 'arc_member'::public.app_role) AND public.is_arc_committee_member_of_association(auth.uid(), association_id) );