Merge pull request 'Agregar trigger para cambios en asignatura fix #74' (#75) from issue/74-agregar-trigger-para-cambios-en-asignatura into main
Deploy Function / deploy (push) Successful in 22s
Deploy Migrations to Production / deploy (push) Successful in 12s
Update database types / deploy (push) Successful in 26s

Reviewed-on: AlexRG/genesis-2#75
This commit was merged in pull request #75.
This commit is contained in:
2026-03-18 22:14:14 +00:00
@@ -0,0 +1,113 @@
set check_function_bodies = off;
CREATE OR REPLACE FUNCTION public.fn_track_cambios_asignatura()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
declare
k text;
old_val jsonb;
new_val jsonb;
v_interaccion_id uuid;
v_usuario uuid;
begin
-- 1. Extraer ID de interacción de IA de meta_origen si existe
v_interaccion_id := nullif(new.meta_origen->>'interaccion_ia_id', '')::uuid;
-- Definir quién hace el cambio
v_usuario := case when tg_op = 'INSERT' then new.creado_por else new.actualizado_por end;
-- ----------------------------------------------------------
-- INSERT -> Registro de creación completo
-- ----------------------------------------------------------
if tg_op = 'INSERT' then
insert into public.cambios_asignatura (
asignatura_id, cambiado_por, tipo, valor_nuevo, interaccion_ia_id
)
values (
new.id, v_usuario, 'CREACION'::public.tipo_cambio, to_jsonb(new), v_interaccion_id
);
return new;
end if;
-- ----------------------------------------------------------
-- DELETE -> Registro de eliminación
-- ----------------------------------------------------------
if tg_op = 'DELETE' then
insert into public.cambios_asignatura (
asignatura_id, cambiado_por, tipo, campo, valor_anterior
)
values (
old.id, old.actualizado_por, 'OTRO'::public.tipo_cambio, 'DELETE', to_jsonb(old)
);
return old;
end if;
-- ----------------------------------------------------------
-- UPDATE -> Registro de cambios específicos
-- ----------------------------------------------------------
-- A) Columnas normales de texto y números
if (new.nombre is distinct from old.nombre) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'nombre', to_jsonb(old.nombre), to_jsonb(new.nombre), v_interaccion_id);
end if;
if (new.codigo is distinct from old.codigo) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'codigo', to_jsonb(old.codigo), to_jsonb(new.codigo), v_interaccion_id);
end if;
if (new.numero_ciclo is distinct from old.numero_ciclo) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'numero_ciclo', to_jsonb(old.numero_ciclo), to_jsonb(new.numero_ciclo), v_interaccion_id);
end if;
if (new.creditos is distinct from old.creditos) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'creditos', to_jsonb(old.creditos), to_jsonb(new.creditos), v_interaccion_id);
end if;
if (new.prerrequisito_asignatura_id is distinct from old.prerrequisito_asignatura_id) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'prerrequisito_asignatura_id', to_jsonb(old.prerrequisito_asignatura_id), to_jsonb(new.prerrequisito_asignatura_id), v_interaccion_id);
end if;
-- B) Cambios en JSONB "datos" (recorriendo llaves)
if (new.datos is distinct from old.datos) then
for k in
select distinct key from (
select jsonb_object_keys(coalesce(old.datos, '{}'::jsonb)) as key
union all
select jsonb_object_keys(coalesce(new.datos, '{}'::jsonb)) as key
) t
loop
old_val := coalesce(old.datos, '{}'::jsonb) -> k;
new_val := coalesce(new.datos, '{}'::jsonb) -> k;
if (old_val is distinct from new_val) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION_CAMPO', k, old_val, new_val, v_interaccion_id);
end if;
end loop;
end if;
-- C) Criterios de Evaluación (JSONB completo)
if (new.criterios_de_evaluacion is distinct from old.criterios_de_evaluacion) then
insert into public.cambios_asignatura (asignatura_id, cambiado_por, tipo, campo, valor_anterior, valor_nuevo, interaccion_ia_id)
values (new.id, v_usuario, 'ACTUALIZACION', 'criterios_de_evaluacion', old.criterios_de_evaluacion, new.criterios_de_evaluacion, v_interaccion_id);
end if;
-- 🔥 Limpiar meta_origen para que interaccion_ia_id no se guarde permanentemente en la tabla base
if v_interaccion_id is not null then
new.meta_origen := new.meta_origen - 'interaccion_ia_id';
end if;
return new;
end;
$function$
;
CREATE TRIGGER trigger_track_cambios_asignatura BEFORE INSERT OR DELETE OR UPDATE ON public.asignaturas FOR EACH ROW EXECUTE FUNCTION public.fn_track_cambios_asignatura();