Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Backend: - Fix email verification and password recovery services - Fix exercise submission and student progress services Frontend: - Update missions, password, and profile API services - Fix ExerciseContentRenderer component Docs & Scripts: - Add SSL/Certbot deployment guide - Add quick deployment guide - Database scripts for testing and validations - Migration and homologation reports - Functions inventory documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
254 lines
8.9 KiB
PL/PgSQL
254 lines
8.9 KiB
PL/PgSQL
-- =====================================================
|
|
-- Script de Validación: generate_student_alerts() JOINs
|
|
-- Descripción: Valida que los JOINs arquitectónicos sean correctos
|
|
-- Fecha: 2025-11-24
|
|
-- Agente: Database-Agent
|
|
-- =====================================================
|
|
|
|
\echo '========================================='
|
|
\echo 'VALIDACIÓN: generate_student_alerts()'
|
|
\echo 'Verificando JOINs arquitectónicos'
|
|
\echo '========================================='
|
|
\echo ''
|
|
|
|
-- =====================================================
|
|
-- 1. VERIFICAR QUE LA FUNCIÓN EXISTE
|
|
-- =====================================================
|
|
\echo '1. Verificando que la función existe...'
|
|
SELECT
|
|
p.proname as function_name,
|
|
n.nspname as schema_name,
|
|
pg_get_functiondef(p.oid) LIKE '%auth_management.profiles%' as uses_profiles_join,
|
|
pg_get_functiondef(p.oid) LIKE '%JOIN auth.users%' as uses_auth_users_join
|
|
FROM pg_proc p
|
|
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
WHERE p.proname = 'generate_student_alerts'
|
|
AND n.nspname = 'progress_tracking';
|
|
|
|
\echo ''
|
|
\echo ' ✓ Si uses_profiles_join = t y uses_auth_users_join = f → CORRECTO'
|
|
\echo ' ✗ Si uses_auth_users_join = t → INCORRECTO (todavía usa JOINs antiguos)'
|
|
\echo ''
|
|
|
|
-- =====================================================
|
|
-- 2. VERIFICAR FOREIGN KEYS RELEVANTES
|
|
-- =====================================================
|
|
\echo '2. Verificando Foreign Keys relevantes...'
|
|
\echo ''
|
|
|
|
\echo ' 2.1 module_progress.user_id → profiles(id)'
|
|
SELECT
|
|
tc.table_schema,
|
|
tc.table_name,
|
|
kcu.column_name,
|
|
ccu.table_schema AS foreign_table_schema,
|
|
ccu.table_name AS foreign_table_name,
|
|
ccu.column_name AS foreign_column_name
|
|
FROM information_schema.table_constraints AS tc
|
|
JOIN information_schema.key_column_usage AS kcu
|
|
ON tc.constraint_name = kcu.constraint_name
|
|
AND tc.table_schema = kcu.table_schema
|
|
JOIN information_schema.constraint_column_usage AS ccu
|
|
ON ccu.constraint_name = tc.constraint_name
|
|
AND ccu.table_schema = tc.table_schema
|
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
AND tc.table_schema = 'progress_tracking'
|
|
AND tc.table_name = 'module_progress'
|
|
AND kcu.column_name = 'user_id';
|
|
|
|
\echo ''
|
|
\echo ' 2.2 exercise_submissions.user_id → profiles(id)'
|
|
SELECT
|
|
tc.table_schema,
|
|
tc.table_name,
|
|
kcu.column_name,
|
|
ccu.table_schema AS foreign_table_schema,
|
|
ccu.table_name AS foreign_table_name,
|
|
ccu.column_name AS foreign_column_name
|
|
FROM information_schema.table_constraints AS tc
|
|
JOIN information_schema.key_column_usage AS kcu
|
|
ON tc.constraint_name = kcu.constraint_name
|
|
AND tc.table_schema = kcu.table_schema
|
|
JOIN information_schema.constraint_column_usage AS ccu
|
|
ON ccu.constraint_name = tc.constraint_name
|
|
AND ccu.table_schema = tc.table_schema
|
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
AND tc.table_schema = 'progress_tracking'
|
|
AND tc.table_name = 'exercise_submissions'
|
|
AND kcu.column_name = 'user_id';
|
|
|
|
\echo ''
|
|
\echo ' 2.3 student_intervention_alerts.student_id → auth.users(id)'
|
|
SELECT
|
|
tc.table_schema,
|
|
tc.table_name,
|
|
kcu.column_name,
|
|
ccu.table_schema AS foreign_table_schema,
|
|
ccu.table_name AS foreign_table_name,
|
|
ccu.column_name AS foreign_column_name
|
|
FROM information_schema.table_constraints AS tc
|
|
JOIN information_schema.key_column_usage AS kcu
|
|
ON tc.constraint_name = kcu.constraint_name
|
|
AND tc.table_schema = kcu.table_schema
|
|
JOIN information_schema.constraint_column_usage AS ccu
|
|
ON ccu.constraint_name = tc.constraint_name
|
|
AND ccu.table_schema = tc.table_schema
|
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
AND tc.table_schema = 'progress_tracking'
|
|
AND tc.table_name = 'student_intervention_alerts'
|
|
AND kcu.column_name = 'student_id';
|
|
|
|
\echo ''
|
|
\echo ' 2.4 profiles.user_id → auth.users(id)'
|
|
SELECT
|
|
tc.table_schema,
|
|
tc.table_name,
|
|
kcu.column_name,
|
|
ccu.table_schema AS foreign_table_schema,
|
|
ccu.table_name AS foreign_table_name,
|
|
ccu.column_name AS foreign_column_name
|
|
FROM information_schema.table_constraints AS tc
|
|
JOIN information_schema.key_column_usage AS kcu
|
|
ON tc.constraint_name = kcu.constraint_name
|
|
AND tc.table_schema = kcu.table_schema
|
|
JOIN information_schema.constraint_column_usage AS ccu
|
|
ON ccu.constraint_name = tc.constraint_name
|
|
AND ccu.table_schema = tc.table_schema
|
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
AND tc.table_schema = 'auth_management'
|
|
AND tc.table_name = 'profiles'
|
|
AND kcu.column_name = 'user_id';
|
|
|
|
-- =====================================================
|
|
-- 3. RECREAR LA FUNCIÓN ACTUALIZADA
|
|
-- =====================================================
|
|
\echo ''
|
|
\echo '3. Recreando la función con JOINs corregidos...'
|
|
\i apps/database/ddl/schemas/progress_tracking/functions/15-generate_student_alerts.sql
|
|
|
|
-- =====================================================
|
|
-- 4. VERIFICAR DEFINICIÓN DE LA FUNCIÓN
|
|
-- =====================================================
|
|
\echo ''
|
|
\echo '4. Verificando definición de la función...'
|
|
\echo ''
|
|
|
|
-- Contar ocurrencias de JOIN auth_management.profiles
|
|
\echo ' 4.1 Ocurrencias de "JOIN auth_management.profiles":'
|
|
SELECT COUNT(*)::text || ' ocurrencias (esperado: 3)' as resultado
|
|
FROM regexp_matches(
|
|
pg_get_functiondef(
|
|
(SELECT oid FROM pg_proc WHERE proname = 'generate_student_alerts' AND pronamespace = 'progress_tracking'::regnamespace)
|
|
),
|
|
'JOIN auth_management\.profiles',
|
|
'g'
|
|
);
|
|
|
|
-- Contar ocurrencias de JOIN auth.users (debería ser 0)
|
|
\echo ''
|
|
\echo ' 4.2 Ocurrencias de "JOIN auth.users" (debe ser 0):'
|
|
SELECT COALESCE(COUNT(*)::text, '0') || ' ocurrencias (esperado: 0)' as resultado
|
|
FROM regexp_matches(
|
|
pg_get_functiondef(
|
|
(SELECT oid FROM pg_proc WHERE proname = 'generate_student_alerts' AND pronamespace = 'progress_tracking'::regnamespace)
|
|
),
|
|
'JOIN auth\.users',
|
|
'g'
|
|
);
|
|
|
|
-- Contar ocurrencias de p.tenant_id
|
|
\echo ''
|
|
\echo ' 4.3 Ocurrencias de "p.tenant_id":'
|
|
SELECT COUNT(*)::text || ' ocurrencias (esperado: 3)' as resultado
|
|
FROM regexp_matches(
|
|
pg_get_functiondef(
|
|
(SELECT oid FROM pg_proc WHERE proname = 'generate_student_alerts' AND pronamespace = 'progress_tracking'::regnamespace)
|
|
),
|
|
'p\.tenant_id',
|
|
'g'
|
|
);
|
|
|
|
-- Contar ocurrencias de p.user_id (debe aparecer en los 3 INSERTs)
|
|
\echo ''
|
|
\echo ' 4.4 Ocurrencias de "p.user_id":'
|
|
SELECT COUNT(*)::text || ' ocurrencias (esperado: 3)' as resultado
|
|
FROM regexp_matches(
|
|
pg_get_functiondef(
|
|
(SELECT oid FROM pg_proc WHERE proname = 'generate_student_alerts' AND pronamespace = 'progress_tracking'::regnamespace)
|
|
),
|
|
'p\.user_id',
|
|
'g'
|
|
);
|
|
|
|
-- =====================================================
|
|
-- 5. PRUEBA FUNCIONAL (OPCIONAL)
|
|
-- =====================================================
|
|
\echo ''
|
|
\echo '5. Prueba funcional (opcional)...'
|
|
\echo ' Si desea ejecutar la función, ejecute:'
|
|
\echo ' SELECT progress_tracking.generate_student_alerts();'
|
|
\echo ''
|
|
|
|
-- =====================================================
|
|
-- 6. ANÁLISIS DE DATOS DE PRUEBA (SI EXISTEN)
|
|
-- =====================================================
|
|
\echo '6. Analizando datos existentes...'
|
|
\echo ''
|
|
|
|
\echo ' 6.1 Estudiantes con progreso en módulos:'
|
|
SELECT COUNT(DISTINCT user_id) as total_students
|
|
FROM progress_tracking.module_progress;
|
|
|
|
\echo ''
|
|
\echo ' 6.2 Estudiantes con ejercicios intentados:'
|
|
SELECT COUNT(DISTINCT user_id) as total_students
|
|
FROM progress_tracking.exercise_submissions;
|
|
|
|
\echo ''
|
|
\echo ' 6.3 Verificar que profiles.user_id mapea a auth.users.id:'
|
|
SELECT
|
|
COUNT(*) as total_profiles,
|
|
COUNT(DISTINCT p.id) as unique_profile_ids,
|
|
COUNT(DISTINCT p.user_id) as unique_user_ids,
|
|
COUNT(DISTINCT u.id) as unique_auth_user_ids,
|
|
CASE
|
|
WHEN COUNT(DISTINCT p.user_id) = COUNT(DISTINCT u.id) THEN 'CORRECTO ✓'
|
|
ELSE 'INCONSISTENTE ✗'
|
|
END as mapping_status
|
|
FROM auth_management.profiles p
|
|
LEFT JOIN auth.users u ON p.user_id = u.id;
|
|
|
|
\echo ''
|
|
\echo ' 6.4 Alertas generadas actualmente:'
|
|
SELECT
|
|
alert_type,
|
|
COUNT(*) as total,
|
|
COUNT(DISTINCT student_id) as unique_students
|
|
FROM progress_tracking.student_intervention_alerts
|
|
GROUP BY alert_type
|
|
ORDER BY alert_type;
|
|
|
|
-- =====================================================
|
|
-- 7. RESUMEN DE VALIDACIÓN
|
|
-- =====================================================
|
|
\echo ''
|
|
\echo '========================================='
|
|
\echo 'RESUMEN DE VALIDACIÓN'
|
|
\echo '========================================='
|
|
\echo ''
|
|
\echo 'CRITERIOS DE ACEPTACIÓN:'
|
|
\echo ' ✓ Función usa JOIN auth_management.profiles (3 veces)'
|
|
\echo ' ✓ Función NO usa JOIN auth.users (0 veces)'
|
|
\echo ' ✓ Función usa p.tenant_id (3 veces)'
|
|
\echo ' ✓ Función usa p.user_id (3 veces)'
|
|
\echo ' ✓ FKs verificadas:'
|
|
\echo ' - module_progress.user_id → profiles(id)'
|
|
\echo ' - exercise_submissions.user_id → profiles(id)'
|
|
\echo ' - student_intervention_alerts.student_id → auth.users(id)'
|
|
\echo ' - profiles.user_id → auth.users(id)'
|
|
\echo ''
|
|
\echo 'Si todos los criterios se cumplen: ✅ VALIDACIÓN EXITOSA'
|
|
\echo 'Si algún criterio falla: ✗ REVISAR IMPLEMENTACIÓN'
|
|
\echo ''
|
|
\echo '========================================='
|