CREATE TABLE public.association_custom_fields ( id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, association_id UUID NOT NULL REFERENCES public.associations(id) ON DELETE CASCADE, field_label TEXT NOT NULL, field_value TEXT, sort_order INTEGER NOT NULL DEFAULT 0, created_by UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_association_custom_fields_assoc ON public.association_custom_fields(association_id); ALTER TABLE public.association_custom_fields ENABLE ROW LEVEL SECURITY; CREATE POLICY "Staff and members can view custom fields" ON public.association_custom_fields FOR SELECT USING (public.user_belongs_to_association(auth.uid(), association_id)); CREATE POLICY "Admins and managers can insert custom fields" ON public.association_custom_fields FOR INSERT WITH CHECK ( public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role) ); CREATE POLICY "Admins and managers can update custom fields" ON public.association_custom_fields FOR UPDATE USING ( public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role) ); CREATE POLICY "Admins and managers can delete custom fields" ON public.association_custom_fields FOR DELETE USING ( public.has_role(auth.uid(), 'admin'::public.app_role) OR public.has_role(auth.uid(), 'manager'::public.app_role) ); CREATE TRIGGER update_association_custom_fields_updated_at BEFORE UPDATE ON public.association_custom_fields FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();