- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
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
- Guardado de Ejercicios - Auto-save NO funciona (userId hardcodeado)
- Autenticación - Password recovery/change NO implementados
- Base de Datos - Inconsistencia crítica de IDs (auth.users vs profiles)
- 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:
// 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() reqpara 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:
// 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 ejercicioprovideFeedback()- Dar feedbackfindPendingReview()- Ver entregas pendientes
Problema:
// ❌ 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:
// 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:
// 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:
// 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:
// 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:
// 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:
// 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_attemptstiene triggers que actualizanmodule_progressexercise_submissionsNO 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:
// 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:
// 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:
// Búsqueda inconsistente de classroomId
const userClassroomId = (user as any)?.classroomId ||
(user as any)?.classroom_id ||
undefined;
Impacto:
- Casting a
anyviola 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:
// 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
-
docs/student-portal/README.md
- Agregar sección de nuevos GAPs identificados
- Actualizar estado de features
-
docs/student-portal/dependencies/DEPENDENCY-MATRIX.md
- Agregar nuevas dependencias identificadas
- Actualizar matriz de acoplamiento
-
docs/frontend/api-architecture.md
- Documentar flujo de auto-save
- Documentar estructura de respuestas de ejercicios
Documentos Nuevos Requeridos
- STUDENT-GAP-009-autosave-exercises.md - P0
- STUDENT-GAP-010-password-recovery.md - P0
- STUDENT-GAP-011-permissions-validation.md - P0
- STUDENT-GAP-012-database-ids-consistency.md - P0
- STUDENT-GAP-013-exercise-validation.md - P0
✅ CONCLUSIÓN DE FASE 1
Hallazgos Clave
- Guardado de Ejercicios ROTO - Problema más crítico, userId hardcodeado
- Autenticación Incompleta - Password recovery/change son fake
- Inconsistencia de Datos - IDs mezclados entre auth.users y profiles
- 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