From d58b939e1c137165caf89361da6e5ac78083be4e Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 13 Jun 2026 12:57:43 -0300 Subject: [PATCH] F6.2 Lote A: anexa triggers schema-agnosticos aos schemas tenant attach_agnostic_triggers(schema) recria nos schemas os triggers de public cuja funcao e provadamente schema-agnostica (so mexe em NEW/OLD): familia updated_at (8: set_updated_at, fn_clinical_notes_updated_at, set_insurance_plans/medicos/ services_updated_at, set_updated_at_recurrence, update_payment_settings/ professional_pricing_updated_at) + prevent_promoting_to_system + prevent_system_group_changes. Backfill dos 9 (54 triggers/schema). Smoke: set_updated_at dispara no schema. Schema-aware vem no Lote B; wiring no clone no fim da F6.2 Co-Authored-By: Claude Fable 5 --- ...3000004_f6_2a_attach_agnostic_triggers.sql | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 database-novo/migrations/20260613000004_f6_2a_attach_agnostic_triggers.sql diff --git a/database-novo/migrations/20260613000004_f6_2a_attach_agnostic_triggers.sql b/database-novo/migrations/20260613000004_f6_2a_attach_agnostic_triggers.sql new file mode 100644 index 0000000..52ff5db --- /dev/null +++ b/database-novo/migrations/20260613000004_f6_2a_attach_agnostic_triggers.sql @@ -0,0 +1,76 @@ +-- ============================================================================= +-- 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;