# REPORTE DE ANÁLISIS - STUDENT PORTAL ## Validación de Integraciones y Funcionalidades **Fecha:** 2025-11-28 **Analista:** Architecture-Analyst **Alcance:** Portal de Estudiantes - Autenticación, Guardado de Ejercicios, Integraciones **Estado:** FASE 1 COMPLETADA --- ## 📋 RESUMEN EJECUTIVO Se ha completado un análisis exhaustivo del portal de estudiantes identificando **15 problemas** distribuidos en: - **7 Críticos (P0)** - Bloquean funcionalidad core - **6 Mayores (P1)** - Afectan experiencia de usuario - **2 Medios (P2)** - Mejoras importantes ### Áreas Más Afectadas 1. **Guardado de Ejercicios** - Auto-save NO funciona (userId hardcodeado) 2. **Autenticación** - Password recovery/change NO implementados 3. **Base de Datos** - Inconsistencia crítica de IDs (auth.users vs profiles) 4. **Permisos** - Endpoints de profesor sin validación de roles --- ## 🔴 PROBLEMAS CRÍTICOS (P0) ### P0-001: Auto-Save de Ejercicios NO FUNCIONA **Ubicación:** `apps/backend/src/modules/progress/controllers/exercise-submission.controller.ts` **Líneas:** 683, 750 **Problema:** ```typescript // userId está HARDCODEADO - NO obtiene del JWT userId: 'temp-user-id' // ❌ CRÍTICO ``` **Impacto:** - Los estudiantes PIERDEN su trabajo si recargan la página - Progreso NO se guarda en la base de datos - Frontend cree que guardó pero backend ignora el usuario real **Solución Requerida:** - Implementar `@Request() req` para obtener userId del JWT - Convertir auth.users.id → profiles.id usando getProfileId() --- ### P0-002: Validación de Respuestas Inconsistente (FE-061) **Ubicación:** `apps/backend/src/modules/educational/controllers/exercises.controller.ts` **Líneas:** 841-854 **Problema:** ```typescript // WORKAROUND temporal que acepta dos formatos // Frontend envía: { answers: { clues: {...} } } // Backend espera: { clues: {...} } ``` **Impacto:** - Validación frágil, puede fallar silenciosamente - Respuestas pueden no guardarse correctamente - Ejercicios pueden marcarse incorrectamente como completados/fallidos **Solución Requerida:** - Estandarizar estructura de respuestas en contrato API - Documentar formato esperado por cada tipo de ejercicio - Implementar validación estricta con mensajes de error claros --- ### P0-003: Inconsistencia de IDs de Usuario en Base de Datos **Ubicación:** Múltiples tablas en `apps/database/ddl/schemas/` **Problema:** Algunas tablas referencian `auth.users.id`, otras `auth_management.profiles.id`: | Tabla | Referencia | Estado | |-------|-----------|--------| | progress_tracking.module_progress | profiles.id | ✅ Correcto | | progress_tracking.exercise_attempts | profiles.id | ✅ Correcto | | progress_tracking.exercise_submissions | profiles.id | ✅ Correcto | | **gamification_system.user_stats** | **auth.users.id** | ❌ Inconsistente | | **gamification_system.user_ranks** | **auth.users.id** | ❌ Inconsistente | | **progress_tracking.engagement_metrics** | **auth.users.id** | ❌ Inconsistente | | **progress_tracking.mastery_tracking** | **auth.users.id** | ❌ Inconsistente | **Impacto:** - JOINs complejos y propensos a errores - Riesgo de datos huérfanos - Backend debe convertir IDs constantemente - Foreign key errors si no se convierte correctamente **Solución Requerida:** - Estandarizar TODAS las tablas a usar `auth_management.profiles.id` - Actualizar triggers y funciones afectadas - Migrar datos existentes --- ### P0-004: Permisos de Profesor NO Se Validan **Ubicación:** `apps/backend/src/modules/progress/controllers/exercise-submission.controller.ts` **Endpoints Afectados:** - `gradeSubmission()` - Calificar ejercicio - `provideFeedback()` - Dar feedback - `findPendingReview()` - Ver entregas pendientes **Problema:** ```typescript // ❌ Sin @UseGuards(RolesGuard) ni @Roles(TEACHER) @Patch(':id/grade') async gradeSubmission() { ... } ``` **Impacto:** - ⚠️ Cualquier estudiante puede calificar sus propios ejercicios - ⚠️ Estudiantes pueden acceder a entregas de otros - ⚠️ Pueden modificar feedback **Solución Requerida:** - Agregar `@UseGuards(RolesGuard)` y `@Roles('admin_teacher', 'super_admin')` - Validar que profesor tenga acceso al classroom del estudiante --- ### P0-005: Password Recovery NO Implementado **Ubicación:** `apps/backend/src/modules/auth/controllers/password.controller.ts` **Problema:** ```typescript // Endpoints retornan respuestas FAKE requestPasswordReset() { return { message: 'Password reset email sent' }; // TODO: Real implementation } resetPassword() { return { message: 'Password reset successful' }; // TODO: Real implementation } ``` **Impacto:** - Estudiantes NO pueden recuperar contraseña olvidada - Bloqueados de sus cuentas permanentemente - Soporte manual requerido **Solución Requerida:** - Implementar generación de tokens de reset - Integrar con servicio de email - Validar tokens y actualizar contraseña --- ### P0-006: Change Password NO Implementado **Ubicación:** `apps/backend/src/modules/auth/controllers/password.controller.ts` **Problema:** ```typescript // Endpoint retorna respuesta FAKE changePassword() { return { message: 'Password changed' }; // TODO: Real implementation } ``` **Impacto:** - Estudiantes NO pueden cambiar su contraseña - Frontend muestra éxito pero contraseña NO cambia - Riesgo de seguridad si contraseña comprometida **Solución Requerida:** - Validar contraseña actual con bcrypt - Hashear nueva contraseña - Actualizar en base de datos --- ### P0-007: Session Management Incompleto **Ubicación:** `apps/backend/src/modules/auth/services/session-management.service.ts` **Problema:** ```typescript // getSessions() siempre retorna array vacío async getSessions(userId: string) { return []; // TODO: Implement } // revokeSession() no hace nada async revokeSession(sessionId: string) { return { message: 'Session revoked' }; // TODO: Implement } ``` **Impacto:** - Usuarios no pueden ver sus sesiones activas - No pueden cerrar sesiones remotas - No hay control de dispositivos conectados --- ## 🟠 PROBLEMAS MAYORES (P1) ### P1-001: Rangos No Se Actualizan al Subir de Nivel **Ubicación:** `apps/backend/src/modules/gamification/services/user-stats.service.ts` **Línea:** 282 **Problema:** ```typescript // ranked_up se calcula pero NO actualiza current_rank const ranked_up = checkRankPromotion(newXp); // Falta: UPDATE user_ranks SET current_rank = newRank ``` **Impacto:** - Estudiante puede tener level=25 pero rank='Ajaw' (inicial) - UI muestra progreso incorrecto - Frustración del estudiante --- ### P1-002: Comodines No Se Deducen del Inventario **Ubicación:** `apps/backend/src/modules/progress/services/exercise-attempt.service.ts` **Problema:** ```typescript // Se registra uso pero NO se deducen del inventario comodines_used: ['hint', 'skip'] // Se guarda // Falta: UPDATE comodines_inventory SET quantity = quantity - 1 ``` **Impacto:** - Estudiantes pueden usar comodines ilimitadamente - Economía de ML Coins rota - Sin incentivo para ganar/comprar comodines --- ### P1-003: Calificación Manual NO Funciona **Ubicación:** `apps/backend/src/modules/progress/controllers/exercise-submission.controller.ts` **Línea:** 362 **Problema:** ```typescript // final_score del request se IGNORA async gradeSubmission(id: string, dto: GradeSubmissionDto) { // NOTE: gradeSubmission service only accepts id return this.service.gradeSubmission(id); // dto.final_score ignorado } ``` **Impacto:** - Profesores no pueden asignar calificaciones personalizadas - Solo calificación automática funciona - Ejercicios abiertos no pueden evaluarse --- ### P1-004: Trigger Faltante para exercise_submissions **Ubicación:** Base de datos **Problema:** - `exercise_attempts` tiene triggers que actualizan `module_progress` - `exercise_submissions` NO tiene triggers equivalentes - Progreso del módulo no se actualiza para ejercicios evaluados manualmente **Impacto:** - Desincronización entre progress_percentage y realidad - Estudiantes que completan ejercicios manuales no ven progreso --- ### P1-005: WebSocket NO Implementado para Leaderboard **Ubicación:** `apps/frontend/src/apps/student/pages/LeaderboardPage.tsx` **Problema:** ```typescript // Comentario en código: "WebSocket not implemented" // Datos de tabla no se actualizan en tiempo real ``` **Impacto:** - Posiciones desactualizadas - Necesita refrescar manualmente - Experiencia de competencia degradada --- ### P1-006: Datos Mock en Gamificación **Ubicación:** `apps/frontend/src/apps/student/hooks/useUserGamification.ts` **Problema:** ```typescript // Hook devuelve datos MOCK hasta que backend esté listo return { ml_coins: 350, // Hardcoded achievements: 12, // Hardcoded streak: 7, // Hardcoded }; ``` **Impacto:** - Todos los estudiantes ven mismos valores - No refleja progreso real - Inconsistencia con ProfilePage que sí usa backend real --- ## 🟡 PROBLEMAS MEDIOS (P2) ### P2-001: Campos Duplicados en Componentes **Ubicación:** Múltiples archivos frontend **Problema:** ```typescript // Búsqueda inconsistente de classroomId const userClassroomId = (user as any)?.classroomId || (user as any)?.classroom_id || undefined; ``` **Impacto:** - Casting a `any` viola TypeScript - Posibles errores si backend cambia estructura - Difícil mantener --- ### P2-002: Almacenamiento Local de Filtros Sin Sincronización **Ubicación:** `apps/frontend/src/apps/student/pages/AchievementsPage.tsx` **Problema:** ```typescript // Filtros en localStorage localStorage.setItem('achievementFilters', JSON.stringify(filters)); ``` **Impacto:** - Filtros no se sincronizan entre dispositivos - Experiencia inconsistente - Datos pueden quedar obsoletos --- ## 📊 MATRIZ DE OBJETOS AFECTADOS ### Base de Datos (10 tablas) | Tabla | Schema | Problema | Prioridad | |-------|--------|----------|-----------| | user_stats | gamification_system | FK a auth.users | P0 | | user_ranks | gamification_system | FK a auth.users | P0 | | exercise_submissions | progress_tracking | Sin trigger | P1 | | engagement_metrics | progress_tracking | FK a auth.users | P0 | | mastery_tracking | progress_tracking | FK a auth.users | P0 | | comodines_inventory | gamification_system | No se deduce | P1 | ### Backend (8 archivos) | Archivo | Módulo | Problema | Prioridad | |---------|--------|----------|-----------| | exercise-submission.controller.ts | progress | userId hardcodeado | P0 | | exercises.controller.ts | educational | FE-061 workaround | P0 | | password.controller.ts | auth | Endpoints fake | P0 | | session-management.service.ts | auth | No implementado | P0 | | user-stats.service.ts | gamification | Ranks no update | P1 | | exercise-attempt.service.ts | progress | Comodines no deduct | P1 | ### Frontend (6 archivos) | Archivo | Ubicación | Problema | Prioridad | |---------|-----------|----------|-----------| | ExercisePage.tsx | student/pages | Auto-save frontend | P0 | | LeaderboardPage.tsx | student/pages | No WebSocket | P1 | | useUserGamification.ts | hooks | Mock data | P1 | | SettingsPage.tsx | student/pages | Backend PUT fake | P0 | | AchievementsPage.tsx | student/pages | localStorage | P2 | --- ## 🔗 DEPENDENCIAS ENTRE PROBLEMAS ``` P0-003 (IDs inconsistentes) ↓ afecta P0-001 (Auto-save) → Necesita convertir IDs correctamente ↓ afecta P1-004 (Trigger faltante) → Usa IDs inconsistentes P0-004 (Permisos) ↓ afecta P1-003 (Calificación manual) → Sin permisos, cualquiera califica P0-005 + P0-006 (Password) ↓ afecta Flujo completo de autenticación ``` --- ## 📈 IMPACTO EN DOCUMENTACIÓN ### Documentos Existentes que Requieren Actualización 1. **docs/student-portal/README.md** - Agregar sección de nuevos GAPs identificados - Actualizar estado de features 2. **docs/student-portal/dependencies/DEPENDENCY-MATRIX.md** - Agregar nuevas dependencias identificadas - Actualizar matriz de acoplamiento 3. **docs/frontend/api-architecture.md** - Documentar flujo de auto-save - Documentar estructura de respuestas de ejercicios ### Documentos Nuevos Requeridos 1. **STUDENT-GAP-009-autosave-exercises.md** - P0 2. **STUDENT-GAP-010-password-recovery.md** - P0 3. **STUDENT-GAP-011-permissions-validation.md** - P0 4. **STUDENT-GAP-012-database-ids-consistency.md** - P0 5. **STUDENT-GAP-013-exercise-validation.md** - P0 --- ## ✅ CONCLUSIÓN DE FASE 1 ### Hallazgos Clave 1. **Guardado de Ejercicios ROTO** - Problema más crítico, userId hardcodeado 2. **Autenticación Incompleta** - Password recovery/change son fake 3. **Inconsistencia de Datos** - IDs mezclados entre auth.users y profiles 4. **Seguridad Vulnerada** - Endpoints de profesor sin validación de roles ### Recomendación **Prioridad INMEDIATA (P0):** Corregir 7 problemas críticos antes de cualquier deploy **Prioridad ALTA (P1):** Corregir 6 problemas mayores en siguiente sprint ### Siguiente Fase Proceder a **FASE 2: PLANEACIÓN** con plan detallado de correcciones. --- **Análisis generado:** 2025-11-28 **Tiempo de análisis:** ~45 minutos (5 agentes en paralelo) **Archivos analizados:** 50+ **Líneas de código revisadas:** ~15,000