-- ============================================================================= -- F6.2 Lote A — anexa triggers schema-agnósticos aos schemas tenant -- -- O clone (LIKE INCLUDING ALL) NÃO copia triggers. As tabelas tenant nos -- schemas precisam dos triggers de negócio. Lote A: os PROVADAMENTE -- schema-agnósticos (só mexem em NEW/OLD, não referenciam outras tabelas) — -- seguros pra anexar sem reescrever a função: -- família updated_at (8) + prevent_promoting_to_system + -- prevent_system_group_changes -- Os schema-aware (financeiro/audit/notif/timeline/sync) vêm no Lote B. -- -- attach_agnostic_triggers(schema) recria, no schema dado, os triggers de -- public cuja função está na whitelist agnóstica. A função do trigger continua -- sendo a de public (agnóstica → funciona em qualquer schema). Backfill dos 9; -- o wiring no clone_tenant_template acontece no fim da F6.2 (com todos prontos). -- ============================================================================= BEGIN; CREATE OR REPLACE FUNCTION public.attach_agnostic_triggers(p_schema text) RETURNS int LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public', 'pg_temp' AS $$ DECLARE agnostic text[] := ARRAY[ 'set_updated_at','fn_clinical_notes_updated_at','set_insurance_plans_updated_at', 'set_medicos_updated_at','set_services_updated_at','set_updated_at_recurrence', 'update_payment_settings_updated_at','update_professional_pricing_updated_at', 'prevent_promoting_to_system','prevent_system_group_changes' ]; r record; v_def text; v_count int := 0; BEGIN IF p_schema NOT LIKE 'tenant\_%' THEN RAISE EXCEPTION 'attach_agnostic_triggers: schema inválido %', p_schema; END IF; FOR r IN SELECT c.relname AS tab, t.tgname, pg_get_triggerdef(t.oid) AS def FROM pg_trigger t JOIN pg_class c ON c.oid = t.tgrelid JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_proc p ON p.oid = t.tgfoid WHERE n.nspname = 'public' AND NOT t.tgisinternal AND p.proname = ANY(agnostic) AND EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = p_schema AND table_name = c.relname) LOOP -- redireciona o ON public. pro schema do tenant (a função fica em public) v_def := replace(r.def, 'ON public.' || r.tab || ' ', 'ON ' || p_schema || '.' || r.tab || ' '); IF v_def = r.def THEN RAISE EXCEPTION 'attach_agnostic_triggers: não consegui redirecionar % (%.%)', r.tgname, p_schema, r.tab; END IF; EXECUTE format('DROP TRIGGER IF EXISTS %I ON %I.%I', r.tgname, p_schema, r.tab); EXECUTE v_def; v_count := v_count + 1; END LOOP; RETURN v_count; END; $$; -- Backfill dos 9 schemas existentes DO $$ DECLARE r record; v int; BEGIN FOR r IN SELECT schema_name FROM public.tenant_schemas ORDER BY schema_name LOOP v := public.attach_agnostic_triggers(r.schema_name); RAISE NOTICE 'F6.2A %: % triggers agnósticos', r.schema_name, v; END LOOP; END $$; COMMIT;