# PLAN REFINADO: FIX-STUDENT-PORTAL-001 - Corrección Portal Estudiantes **Agente:** Orquestador (Tech Lead) **Tipo de tarea:** Corrección | Validación **Prioridad:** P1 **Fecha refinamiento:** 2026-01-10 **Versión:** 2.0 (Refinado) **Referencia:** 03-VALIDACION-PLAN-FIX-STUDENT-PORTAL-2026-01-10.md --- ## CAMBIOS RESPECTO AL PLAN ORIGINAL | Área | Cambio | Justificación | |------|--------|---------------| | Ciclo 2 | Agregada verificación de triggers | Gap identificado en validación | | Ciclo 3 | Agregada verificación de assignments | Dependencia crítica para ModuleDetail | | Ciclo 4 | Agregado endpoint user-rank | Completitud de validación | | Criterios | Nuevos criterios añadidos | Mejorar cobertura | --- ## OBJETIVO Corregir los 3 problemas del portal de estudiantes asegurando: 1. Leaderboard mostrando usuarios reales de BD 2. Achievements mostrando 20 logros disponibles 3. ModuleDetail cargando ejercicios correctamente **Criterios de Aceptación (Refinados):** - [ ] Leaderboard muestra top 10+ usuarios ordenados por XP - [ ] Página de Achievements muestra 20 logros (locked/unlocked) - [ ] ModuleDetailPage carga ejercicios sin error - [ ] Backend responde correctamente a todos los endpoints - [ ] Base de datos tiene datos consistentes - [ ] Scripts create-database.sh ejecutan sin errores - [ ] **NUEVO:** user_ranks coincide con user_stats en COUNT - [ ] **NUEVO:** Assignments tienen ejercicios asociados --- ## CICLOS DE EJECUCIÓN REFINADOS ### Ciclo 1: Verificación de Ambiente **Duración estimada:** 15 minutos **Objetivo:** Confirmar estado actual del ambiente **Tareas:** 1. Verificar si backend está corriendo (puerto 3006) 2. Verificar si frontend está corriendo (puerto 3005) 3. Verificar variable VITE_USE_MOCK_DATA no activa 4. Verificar conexión a base de datos **Comandos:** ```bash # 1. Backend health check curl -s http://localhost:3006/api/v1/health | jq # 2. Frontend check curl -s -o /dev/null -w "%{http_code}" http://localhost:3005 # 3. Variables de entorno grep "VITE_USE_MOCK_DATA" apps/frontend/.env* 2>/dev/null || echo "No definida (OK)" cat apps/frontend/.env.local 2>/dev/null || echo "No existe .env.local (OK)" # 4. Base de datos psql $DATABASE_URL -c "SELECT version();" ``` **Criterios de éxito:** - [ ] Backend responde 200 en /health - [ ] Frontend responde 200 - [ ] VITE_USE_MOCK_DATA no está definido o es 'false' - [ ] Conexión a BD exitosa --- ### Ciclo 2: Recreación de Base de Datos **Duración estimada:** 20 minutos **Objetivo:** Asegurar BD limpia con todos los seeds **Tareas:** 1. Ejecutar `drop-and-recreate-database.sh` 2. Verificar ejecución sin errores 3. Validar conteo de registros en tablas clave 4. **NUEVO:** Verificar que triggers ejecutaron correctamente **Comandos:** ```bash # 1. Recrear BD cd /home/isem/workspace-v1/projects/gamilit/apps/database ./drop-and-recreate-database.sh "$DATABASE_URL" # 2. Verificar log tail -50 create-database-*.log | grep -E "(ERROR|WARNING|✅)" # 3. Conteo de tablas principales psql $DATABASE_URL -c " SELECT 'user_stats' as tabla, COUNT(*) as registros FROM gamification_system.user_stats UNION ALL SELECT 'user_ranks', COUNT(*) FROM gamification_system.user_ranks UNION ALL SELECT 'achievements', COUNT(*) FROM gamification_system.achievements UNION ALL SELECT 'user_achievements', COUNT(*) FROM gamification_system.user_achievements UNION ALL SELECT 'modules', COUNT(*) FROM educational_content.modules UNION ALL SELECT 'exercises', COUNT(*) FROM educational_content.exercises UNION ALL SELECT 'classrooms', COUNT(*) FROM educational_content.classrooms UNION ALL SELECT 'classroom_students', COUNT(*) FROM educational_content.classroom_students UNION ALL SELECT 'assignments', COUNT(*) FROM educational_content.assignments; " # 4. NUEVO: Verificar integridad de triggers psql $DATABASE_URL -c " SELECT (SELECT COUNT(*) FROM gamification_system.user_stats) as user_stats_count, (SELECT COUNT(*) FROM gamification_system.user_ranks) as user_ranks_count, CASE WHEN (SELECT COUNT(*) FROM gamification_system.user_stats) = (SELECT COUNT(*) FROM gamification_system.user_ranks) THEN 'OK: Triggers ejecutaron correctamente' ELSE 'WARNING: Discrepancia en counts - verificar triggers' END as trigger_status; " ``` **Criterios de éxito:** - [ ] Script ejecuta sin errores (exit code 0) - [ ] user_stats tiene 10+ registros - [ ] user_ranks tiene mismo COUNT que user_stats - [ ] achievements tiene 20 registros - [ ] modules tiene 5 registros - [ ] exercises tiene 50+ registros - [ ] classrooms tiene 1+ registros - [ ] assignments tiene 1+ registros --- ### Ciclo 3: Verificación de Relaciones **Duración estimada:** 15 minutos **Objetivo:** Asegurar relaciones correctas para usuario student@ **Tareas:** 1. Verificar que student@ tiene user_stats 2. Verificar que student@ pertenece a classroom 3. Verificar que classroom tiene assignments 4. **NUEVO:** Verificar que assignments tienen ejercicios asociados **Comandos:** ```sql -- 1. Verificar user_stats para usuario testing SELECT u.email, us.user_id, us.total_xp, us.level, us.current_rank FROM gamification_system.user_stats us JOIN auth.users u ON u.id = us.user_id WHERE u.email = 'student@gamilit.com'; -- 2. Verificar classroom membership SELECT u.email, c.name as classroom, cs.created_at as joined_at FROM auth.users u LEFT JOIN educational_content.classroom_students cs ON cs.student_id = u.id LEFT JOIN educational_content.classrooms c ON c.id = cs.classroom_id WHERE u.email = 'student@gamilit.com'; -- 3. Verificar assignments del classroom SELECT c.name as classroom, a.title as assignment, a.is_published FROM educational_content.classrooms c JOIN educational_content.assignments a ON a.classroom_id = c.id ORDER BY c.name, a.title; -- 4. NUEVO: Verificar que assignments tienen ejercicios SELECT a.title as assignment, COUNT(ae.exercise_id) as ejercicios, CASE WHEN COUNT(ae.exercise_id) > 0 THEN 'OK' ELSE 'WARNING: Sin ejercicios' END as status FROM educational_content.assignments a LEFT JOIN educational_content.assignment_exercises ae ON ae.assignment_id = a.id GROUP BY a.id, a.title ORDER BY a.title; -- 5. Verificar ejercicios por módulo SELECT m.title as modulo, COUNT(e.id) as ejercicios FROM educational_content.modules m LEFT JOIN educational_content.exercises e ON e.module_id = m.id GROUP BY m.id, m.title, m.order_index ORDER BY m.order_index; ``` **Criterios de éxito:** - [ ] student@ tiene registro en user_stats - [ ] student@ pertenece a al menos 1 classroom - [ ] Existe al menos 1 assignment publicado - [ ] **NUEVO:** Cada assignment tiene al menos 1 ejercicio - [ ] Cada módulo tiene ejercicios asociados --- ### Ciclo 4: Verificación de Endpoints Backend **Duración estimada:** 20 minutos **Objetivo:** Confirmar que backend retorna datos correctos **Tareas:** 1. Obtener token JWT válido 2. Probar endpoint de leaderboard global 3. **NUEVO:** Probar endpoint de user-rank 4. Probar endpoint de achievements 5. Probar endpoint de modules/exercises **Comandos:** ```bash # 1. Obtener token (ajustar credenciales si es necesario) TOKEN=$(curl -s -X POST http://localhost:3006/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"student@gamilit.com","password":"Student123!@#"}' | jq -r '.data.accessToken // .accessToken // .token') echo "Token obtenido: ${TOKEN:0:50}..." # 2. Leaderboard global echo "=== LEADERBOARD GLOBAL ===" curl -s -H "Authorization: Bearer $TOKEN" \ http://localhost:3006/api/v1/gamification/leaderboard/global | jq '{ type: .type, entries_count: (.entries | length), first_user: .entries[0].username, totalEntries: .totalEntries }' # 3. NUEVO: User rank echo "=== USER RANK ===" curl -s -H "Authorization: Bearer $TOKEN" \ "http://localhost:3006/api/v1/gamification/leaderboards/user-rank?type=global" | jq # 4. Achievements echo "=== ACHIEVEMENTS ===" curl -s -H "Authorization: Bearer $TOKEN" \ http://localhost:3006/api/v1/gamification/achievements | jq 'length' # 5. User achievements echo "=== USER ACHIEVEMENTS ===" USER_ID=$(curl -s -H "Authorization: Bearer $TOKEN" \ http://localhost:3006/api/v1/auth/me | jq -r '.data.id // .id') curl -s -H "Authorization: Bearer $TOKEN" \ "http://localhost:3006/api/v1/gamification/users/$USER_ID/achievements" | jq '.data.total // length' # 6. Module exercises (módulo 1) echo "=== MODULE EXERCISES ===" curl -s -H "Authorization: Bearer $TOKEN" \ "http://localhost:3006/api/v1/educational/modules/modulo-01-comprension-literal/exercises" | jq 'length' ``` **Criterios de éxito:** - [ ] Login exitoso (token obtenido) - [ ] Leaderboard retorna 10+ entries - [ ] **NUEVO:** User-rank retorna posición del usuario - [ ] Achievements retorna 20 items - [ ] User achievements retorna estructura válida - [ ] Module exercises retorna 5+ items --- ### Ciclo 5: Verificación de Frontend **Duración estimada:** 15 minutos **Objetivo:** Confirmar que UI muestra datos correctamente **Tareas:** 1. Acceder a portal estudiante 2. Login con usuario de prueba 3. Verificar Dashboard 4. Verificar página Leaderboard 5. Verificar página Gamification/Achievements 6. Verificar página ModuleDetail **Procedimiento Manual:** 1. Abrir http://localhost:3005 2. Login con student@gamilit.com / Student123!@# 3. Verificar Dashboard carga sin errores 4. Navegar a /student/leaderboard → Ver tabla con usuarios ordenados por XP 5. Navegar a /student/gamification → Ver grid de achievements 6. Navegar a /student/modules/modulo-01-comprension-literal → Ver lista de ejercicios **Verificación DevTools:** ``` En cada página: 1. Abrir DevTools (F12) 2. Ir a tab Network 3. Verificar requests a API (status 200) 4. Verificar Console sin errores rojos ``` **Criterios de éxito:** - [ ] Dashboard carga sin errores - [ ] Leaderboard muestra tabla con usuarios ordenados - [ ] Gamification muestra grid de achievements (20 items) - [ ] ModuleDetail muestra lista de ejercicios - [ ] No hay errores en consola del navegador - [ ] Todos los requests API responden 200 --- ### Ciclo 6: Validación Final e Integración **Duración estimada:** 15 minutos **Objetivo:** Validar integración completa y documentar **Tareas:** 1. Ejecutar validación de scripts BD 2. Compilar backend 3. Compilar frontend 4. Documentar resultados **Comandos:** ```bash # 1. Validar scripts BD cd /home/isem/workspace-v1/projects/gamilit/apps/database ./validate-create-database.sh 2>&1 | tail -20 # 2. Backend - compilar cd /home/isem/workspace-v1/projects/gamilit/apps/backend npm run build 2>&1 | tail -20 echo "Exit code: $?" # 3. Frontend - compilar cd /home/isem/workspace-v1/projects/gamilit/apps/frontend npm run build 2>&1 | tail -20 echo "Exit code: $?" ``` **Criterios de éxito:** - [ ] validate-create-database.sh pasa - [ ] Backend compila sin errores (exit code 0) - [ ] Frontend compila sin errores (exit code 0) - [ ] Documentación actualizada --- ## DOCUMENTACIÓN A GENERAR **Durante ejecución:** - [ ] 05-EJECUCION.md - Log de cada ciclo con resultados **Post-ejecución:** - [ ] 06-VALIDACION-FINAL.md - Resultados de validación - [ ] Actualización de inventarios si hay cambios --- ## CRITERIOS DE ÉXITO FINALES La tarea se considera **COMPLETADA** cuando: **Base de Datos:** - [x] BD recreada con todos los seeds - [x] user_stats tiene 10+ registros - [x] user_ranks coincide con user_stats - [x] achievements tiene 20 registros - [x] modules tiene 5 registros con ejercicios - [x] Relaciones classroom → student → assignment válidas **Backend:** - [x] Todos los endpoints responden 200 - [x] Leaderboard retorna usuarios ordenados - [x] Achievements retorna catálogo completo - [x] Exercises retorna lista por módulo **Frontend:** - [x] Todas las páginas cargan sin errores - [x] Datos reales mostrados (no mock) - [x] Sin errores en consola **Integración:** - [x] Scripts de BD ejecutan sin errores - [x] Backend compila sin errores - [x] Frontend compila sin errores - [x] Documentación completa --- ## ESTIMACIÓN FINAL **Tiempo total estimado:** 2.5 horas | Ciclo | Duración | Acumulado | |-------|----------|-----------| | Ciclo 1: Ambiente | 15 min | 15 min | | Ciclo 2: BD | 20 min | 35 min | | Ciclo 3: Relaciones | 15 min | 50 min | | Ciclo 4: Endpoints | 20 min | 70 min | | Ciclo 5: Frontend | 15 min | 85 min | | Ciclo 6: Validación | 15 min | 100 min | | Documentación | 20 min | 120 min | | Buffer (15%) | 18 min | 138 min | | **TOTAL** | **~2.5h** | | --- **Versión:** 2.0 (Refinado) **Última actualización:** 2026-01-10 **Estado:** APROBADO PARA EJECUCIÓN