-- ============================================ -- rioCata - Funciones y Triggers -- ============================================ -- ============================================ -- FUNCIÓN: Actualizar updated_at -- ============================================ CREATE OR REPLACE FUNCTION set_updated_at() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NEW.updated_at := clock_timestamp(); RETURN NEW; END $$; COMMENT ON FUNCTION set_updated_at() IS 'Actualiza automáticamente el campo updated_at al timestamp actual'; -- Trigger para actualizar updated_at en evaluacion CREATE TRIGGER trg_eval_updated_at BEFORE UPDATE ON evaluacion FOR EACH ROW EXECUTE FUNCTION set_updated_at(); -- ============================================ -- FUNCIÓN: Calcular puntaje final -- ============================================ -- Calcula el puntaje_final sumando SOLO los valores afectivos presentes CREATE OR REPLACE FUNCTION eval_compute_score() RETURNS trigger LANGUAGE plpgsql AS $$ DECLARE s int := 0; BEGIN -- Suma todos los valores afectivos presentes en intensidades -- Si alguno es null, COALESCE lo convierte en 0 s := s + COALESCE((NEW.intensidades->'fragancia' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'aroma' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'sabor' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'saborResidual' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'acidez' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'dulzor' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'sensacionBoca' ->>'afectiva')::int, 0); s := s + COALESCE((NEW.intensidades->'impresionGlobal'->>'afectiva')::int, 0); NEW.puntaje_final := s; RETURN NEW; END $$; COMMENT ON FUNCTION eval_compute_score() IS 'Calcula automáticamente el puntaje_final como suma de valores afectivos'; -- Trigger para calcular puntaje_final en INSERT y UPDATE CREATE TRIGGER trg_eval_score_bi BEFORE INSERT OR UPDATE OF intensidades ON evaluacion FOR EACH ROW EXECUTE FUNCTION eval_compute_score(); -- ============================================ -- FUNCIONES AUXILIARES DE CONSULTA -- ============================================ -- Función para obtener el promedio de un parámetro afectivo en una sesión CREATE OR REPLACE FUNCTION get_promedio_parametro_afectivo( p_sesion_id uuid, p_parametro text -- 'fragancia', 'aroma', 'sabor', etc. ) RETURNS numeric AS $$ BEGIN RETURN ( SELECT AVG(((e.intensidades -> p_parametro ->>'afectiva')::int)) FROM sesion s JOIN muestra m ON m.sesion_id = s.id JOIN evaluacion e ON e.muestra_id = m.id WHERE s.id = p_sesion_id ); END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION get_promedio_parametro_afectivo(uuid, text) IS 'Obtiene el promedio de un parámetro afectivo para una sesión'; -- Función para obtener las top N muestras de una sesión por puntaje CREATE OR REPLACE FUNCTION get_top_muestras( p_sesion_id uuid, p_limit int DEFAULT 3 ) RETURNS TABLE ( muestra_codigo text, puntaje_final int, catador_email text, catador_nombre text ) AS $$ BEGIN RETURN QUERY SELECT m.codigo, e.puntaje_final, u.email, u.nombre FROM muestra m JOIN evaluacion e ON e.muestra_id = m.id JOIN sesion_participante sp ON sp.id = e.sesion_participante_id JOIN auth.users u ON u.id = sp.catador_id WHERE m.sesion_id = p_sesion_id ORDER BY e.puntaje_final DESC LIMIT p_limit; END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION get_top_muestras(uuid, int) IS 'Obtiene las muestras con mejor puntaje de una sesión';