-- ===================================================== -- FUNCTION: education.update_course_stats() -- ===================================================== -- Proyecto: OrbiQuant IA (Trading Platform) -- Módulo: OQI-002 - Education -- Especificación: ET-EDU-001-database.md -- Descripción: Actualiza estadísticas denormalizadas del curso -- ===================================================== -- Función para actualizar estadísticas de reviews CREATE OR REPLACE FUNCTION education.update_course_rating_stats() RETURNS TRIGGER AS $$ DECLARE v_course_id UUID; v_avg_rating DECIMAL(3,2); v_total_reviews INTEGER; BEGIN -- Obtener course_id del NEW o OLD record v_course_id := COALESCE(NEW.course_id, OLD.course_id); -- Calcular promedio solo de reviews aprobadas SELECT COALESCE(AVG(rating), 0), COUNT(*) INTO v_avg_rating, v_total_reviews FROM education.course_reviews WHERE course_id = v_course_id AND is_approved = true; -- Actualizar estadísticas en el curso UPDATE education.courses SET avg_rating = v_avg_rating, total_reviews = v_total_reviews, updated_at = NOW() WHERE id = v_course_id; RETURN COALESCE(NEW, OLD); END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION education.update_course_rating_stats() IS 'Actualiza avg_rating y total_reviews del curso'; -- Triggers para actualizar estadísticas CREATE TRIGGER update_course_rating_on_review_insert AFTER INSERT ON education.course_reviews FOR EACH ROW EXECUTE FUNCTION education.update_course_rating_stats(); CREATE TRIGGER update_course_rating_on_review_update AFTER UPDATE ON education.course_reviews FOR EACH ROW WHEN (OLD.rating IS DISTINCT FROM NEW.rating OR OLD.is_approved IS DISTINCT FROM NEW.is_approved) EXECUTE FUNCTION education.update_course_rating_stats(); CREATE TRIGGER update_course_rating_on_review_delete AFTER DELETE ON education.course_reviews FOR EACH ROW EXECUTE FUNCTION education.update_course_rating_stats();