Structure: - control-plane/: Registries, SIMCO directives, CI/CD templates - projects/: Gamilit, ERP-Suite, Trading-Platform, Betting-Analytics - shared/: Libs catalog, knowledge-base Key features: - Centralized port, domain, database, and service registries - 23 SIMCO directives + 6 fundamental principles - NEXUS agent profiles with delegation rules - Validation scripts for workspace integrity - Dockerfiles for all services - Path aliases for quick reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
34 KiB
Trazas de Tareas - Backend
Última actualización: 2025-11-29 (BE-137: Implementación M4-M5 - Sistema de Revisión Manual)
BE-137: Implementación M4-M5 - Sistema de Revisión Manual ✅
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Agent Fecha: 2025-11-29 Módulos: Educational, Progress, Teacher
Resumen
Implementación completa de los módulos 4 (Lectura Digital) y 5 (Producción Lectora) con sistema de carga de medios (audio/video) y revisión manual por docentes.
Problema Resuelto
Los módulos M4 y M5 requieren ejercicios creativos donde los estudiantes generan contenido multimedia (videos, audios, textos) que debe ser evaluado manualmente por docentes. No existía infraestructura para:
- Subir archivos multimedia desde ejercicios
- Almacenar y gestionar archivos adjuntos
- Sistema de revisión manual con rúbricas
- Workflow de envío → revisión → calificación
Archivos Creados
Entities (3 archivos)
| Archivo | Descripción |
|---|---|
modules/educational/entities/media-attachment.entity.ts |
Entity para archivos multimedia adjuntos |
modules/progress/entities/manual-review.entity.ts |
Entity para revisiones manuales con rúbricas |
Services (3 archivos)
| Archivo | Descripción |
|---|---|
modules/educational/services/media-storage.service.ts |
Gestión de subida y almacenamiento de archivos |
modules/teacher/services/manual-review.service.ts |
Lógica de revisión manual con rúbricas |
Controllers (2 archivos)
| Archivo | Descripción |
|---|---|
modules/educational/controllers/media-upload.controller.ts |
Endpoint POST /educational/media/upload |
modules/teacher/controllers/manual-review.controller.ts |
CRUD de revisiones manuales |
DTOs (3 archivos)
| Archivo | Descripción |
|---|---|
modules/educational/dto/upload-media.dto.ts |
Validación de subida de archivos |
modules/teacher/dto/create-review.dto.ts |
Validación de creación de revisiones |
modules/teacher/dto/shop/ |
DTOs para sistema de tienda |
Archivos Modificados
| Archivo | Cambios |
|---|---|
modules/educational/educational.module.ts |
Agregado MediaStorageService y MediaUploadController |
modules/educational/entities/index.ts |
Export de MediaAttachment |
modules/teacher/teacher.module.ts |
Agregado ManualReviewService y Controller |
Endpoints Implementados
1. POST /api/v1/educational/media/upload
- Descripción: Subir archivo multimedia para ejercicio
- Body:
multipart/form-datacon file, exerciseId, userId - Response: MediaAttachmentDto con URL del archivo
- Validaciones:
- Tipos permitidos: audio/, video/, image/*
- Tamaño máximo: 50MB para video, 10MB para audio/imagen
- Ejercicio debe existir
2. GET /api/v1/teacher/manual-reviews
- Descripción: Lista de envíos pendientes de revisión
- Query: classroomId, moduleId, status
- Response: ManualReviewDto[] con datos del estudiante y ejercicio
3. POST /api/v1/teacher/manual-reviews
- Descripción: Crear revisión manual para un envío
- Body: CreateReviewDto (submissionId, score, feedback, rubricScores)
- Response: ManualReviewDto
4. PUT /api/v1/teacher/manual-reviews/:id
- Descripción: Actualizar revisión existente
- Body: UpdateReviewDto
- Response: ManualReviewDto
Ejercicios Activados
Módulo 4 - Lectura Digital (5 ejercicios)
verificador_fake_news- Verificación de noticias falsasinfografia_interactiva- Creación de infografíasquiz_tiktok- Quiz estilo TikToknavegacion_hipertextual- Navegación en hipertextosanalisis_memes- Análisis crítico de memes
Módulo 5 - Producción Lectora (3 ejercicios)
diario_multimedia- Diario con texto/audio/videocomic_digital- Creación de cómics digitalesvideo_carta- Carta en formato video
Características Técnicas
Almacenamiento de Archivos:
- ✅ Directorio:
apps/backend/uploads/media/ - ✅ Nomenclatura:
{timestamp}-{userId}-{originalName} - ✅ Validación de tipos MIME
- ✅ Límites de tamaño por tipo
Sistema de Revisión:
- ✅ Estados: pending, in_review, approved, rejected, needs_revision
- ✅ Rúbricas con criterios y puntajes
- ✅ Feedback textual del docente
- ✅ Historial de revisiones
Seguridad:
- ✅ JWT Auth requerido
- ✅ RLS: Docente solo ve sus classrooms
- ✅ Validación de ownership en archivos
- ✅ Sanitización de nombres de archivo
Validación
- ✅ TypeScript Build: Sin errores
- ✅ Lint: 0 errores
- ✅ Directiva Recreación Limpia: CUMPLE (solo nuevas tablas)
- ✅ Backend compila:
npm run buildexitoso
Base de Datos
Tablas creadas (ver DB-137):
educational_content.media_attachmentsprogress_tracking.manual_reviews
Impacto
Antes:
- M4 y M5: NO disponibles
- 0 ejercicios creativos funcionales
- Sin sistema de revisión manual
Después:
- M4 y M5: Totalmente funcionales
- 8 ejercicios creativos activos
- Sistema completo de revisión manual con rúbricas
Próximos Pasos
Recomendaciones:
- Implementar notificaciones push para docentes (envío pendiente)
- Agregar analytics de tiempos de revisión
- Implementar sistema de apelaciones
- Agregar soporte para más formatos (PDF, documentos)
- Implementar compresión automática de videos
Referencias
- Database: DB-137 (tablas media_attachments, manual_reviews)
- Frontend: FE-137 (componentes MediaUploader, RubricEvaluator)
- Script VAPID:
apps/backend/scripts/generate-vapid-keys.js
BE-136: Achievement Auto-Detection after Exercise Completion ✅
Estado: COMPLETADA Prioridad: P1 ALTA Asignado: Backend-Agent (orquestado por Architecture-Analyst) Fecha: 2025-11-29 Análisis ID: STUDENT-PORTAL-FIX-004
BE-136: Achievement Auto-Detection en ExerciseAttemptService ✅
Estado: COMPLETADA Prioridad: P1 ALTA Asignado: Backend-Agent (orquestado por Architecture-Analyst) Fecha: 2025-11-29 Análisis ID: STUDENT-PORTAL-FIX-004
Resumen
Integración del sistema de logros (achievements) al flujo de completación de ejercicios. Después de otorgar recompensas (XP/ML Coins), el sistema ahora detecta y otorga automáticamente los logros que el usuario haya desbloqueado.
Problema Identificado
Los logros en el portal Student no tenían funcionalidad porque:
- AchievementsService existía con método
detectAndGrantEarned() - ExerciseAttemptService NO llamaba a AchievementsService después de otorgar recompensas
- Los logros se definían en BD pero nunca se otorgaban automáticamente
Archivos Modificados
| Archivo | Descripción |
|---|---|
modules/progress/services/exercise-attempt.service.ts |
Inyección de AchievementsService y llamada post-rewards |
Cambios Implementados
1. Import agregado (línea superior):
import { AchievementsService } from '../../gamification/services/achievements.service';
2. Constructor - Inyección de dependencia:
constructor(
// ... otros servicios
private readonly achievementsService: AchievementsService,
) {}
3. Método submitAttempt() - Detección de logros post-rewards:
// After awardRewards() call
if (isCorrect && (attempt.xp_earned > 0 || attempt.ml_coins_earned > 0)) {
try {
const earnedAchievements = await this.achievementsService.detectAndGrantEarned(attempt.user_id);
if (earnedAchievements.length > 0) {
this.logger.log(
`Granted ${earnedAchievements.length} achievement(s) to user ${attempt.user_id}`,
);
}
} catch (error) {
this.logger.error(
`Error detecting achievements for user ${attempt.user_id}: ${error instanceof Error ? error.message : String(error)}`,
);
}
}
Flujo de Ejecución
- Estudiante completa ejercicio
submitAttempt()valida respuestas- Si es correcto:
awardRewards()otorga XP y ML Coins - NUEVO:
detectAndGrantEarned()verifica condiciones de logros - Logros desbloqueados se insertan en
user_achievements - Log de confirmación en consola
Dependencias
| Servicio | Rol |
|---|---|
AchievementsService |
Detecta y otorga logros basado en condiciones |
UserStatsService |
Provee estadísticas actuales del usuario |
RanksService |
Verificación de rangos para logros de rango |
Validación
- ✅ TypeScript compila sin errores
- ✅ Backend build exitoso
- ✅ AchievementsService ya exportado en gamification.module.ts
- ✅ Error handling implementado (no bloquea flujo principal)
Impacto
- Portal Student: Logros ahora funcionales
- Gamificación: Sistema de achievements completamente integrado
- UX: Usuarios reciben logros automáticamente al cumplir condiciones
BE-135: Uso de xp_reward configurado en exercise-attempt.service.ts ✅
Estado: COMPLETADA Prioridad: P1 ALTA Asignado: Backend-Agent (orquestado por Architecture-Analyst) Fecha: 2025-11-28 Análisis ID: MODULO2-GAMIFICATION-FIX-001
Resumen
Modificación de calculateXpReward() y calculateCoinsReward() para usar los valores configurados en el ejercicio (xp_reward, ml_coins_reward) en lugar de calcular solo basado en porcentaje de score.
Archivos Modificados
| Archivo | Descripción |
|---|---|
modules/progress/services/exercise-attempt.service.ts |
Líneas 174-181, 273-303 modificadas |
Cambios Implementados
1. Método submitAttempt() (líneas 174-181):
- Agregado: Obtención del ejercicio con
exerciseRepo.findOne() - Modificado: Paso de
exerciseXpRewardyexerciseMlCoinsRewarda funciones de cálculo
2. Método calculateXpReward() (líneas 273-283):
- Antes:
Math.floor(scorePercentage) - Después:
Math.floor(exerciseXpReward * scoreMultiplier)con penalización por hints
3. Método calculateCoinsReward() (líneas 293-303):
- Antes:
Math.floor(scorePercentage / 5) - Después:
Math.floor(exerciseMlCoinsReward * scoreMultiplier)con penalización por comodines
Validación
- ✅ TypeScript compila sin errores
- ✅ Backend build exitoso
- ✅ Lógica de fallback implementada (100 XP / 20 ML Coins si ejercicio no encontrado)
BE-134: Uso de xp_reward configurado en exercise-submission.service.ts ✅
Estado: COMPLETADA Prioridad: P1 ALTA Asignado: Backend-Agent (orquestado por Architecture-Analyst) Fecha: 2025-11-28 Análisis ID: MODULO2-GAMIFICATION-FIX-001
Resumen
Modificación del método claimRewards() para usar los valores xp_reward y ml_coins_reward configurados en el ejercicio en lugar de calcular basado solo en porcentaje de score.
Archivos Modificados
| Archivo | Descripción |
|---|---|
modules/progress/services/exercise-submission.service.ts |
Líneas 854-862 modificadas |
Cambios Implementados
Método claimRewards() (líneas 854-862):
// Obtener exercise para usar su xp_reward configurado
const exercise = await this.exerciseRepo.findOne({ where: { id: submission.exercise_id } });
const baseXpReward = exercise?.xp_reward || 100;
const baseMlCoinsReward = exercise?.ml_coins_reward || 20;
// Calcular rewards basado en score y rewards configurados del ejercicio
const scoreMultiplier = submission.score / submission.max_score;
let xpEarned = Math.floor(baseXpReward * scoreMultiplier);
let mlCoinsEarned = Math.floor(baseMlCoinsReward * scoreMultiplier);
Impacto
- Módulo 1: Sigue usando 100 XP / 20 ML Coins (sin cambio)
- Módulo 2: Ahora usa 150 XP / 30 ML Coins (nuevo)
- Módulo 3+: Usa valores configurados en cada ejercicio
Validación
- ✅ TypeScript compila sin errores
- ✅ Backend build exitoso
- ✅ Lógica proporcional al score implementada
BE-133: Exercise Responses Service (TEACHER-PORTAL-001) ✅
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Agent (orquestado por Architecture-Analyst) Fecha: 2025-11-24 Análisis ID: TEACHER-PORTAL-001
Resumen
Implementación del servicio y controlador para visualizar respuestas de ejercicios de estudiantes en el Portal Teacher. Parte del desarrollo completo del Teacher Portal.
Archivos Creados
| Archivo | Descripción |
|---|---|
modules/teacher/services/exercise-responses.service.ts |
Servicio con lógica de negocio y RLS |
modules/teacher/controllers/exercise-responses.controller.ts |
4 endpoints REST con Swagger |
modules/teacher/dto/exercise-responses.dto.ts |
DTOs tipados para request/response |
Endpoints Implementados
| Método | Ruta | Descripción |
|---|---|---|
| GET | /teacher/attempts |
Listado con filtros y paginación |
| GET | /teacher/attempts/:id |
Detalle de un intento específico |
| GET | /teacher/attempts/student/:studentId |
Intentos por estudiante |
| GET | /teacher/exercises/:exerciseId/responses |
Respuestas por ejercicio |
Funcionalidades
- ✅ Consulta de exercise_attempts con filtros (classroom, student, module, dates, correctness)
- ✅ Paginación con offset/limit
- ✅ Ordenamiento por fecha, score, tiempo
- ✅ Detalle de intento con datos del ejercicio (JOIN con exercises)
- ✅ RLS validado (teacher solo ve students de sus classrooms)
- ✅ Swagger documentation completa
Validación
- ✅ TypeScript compila sin errores
- ✅ Integrado en TeacherModule
- ✅ DTOs con class-validator
Documentación
- Análisis:
orchestration/agentes/architecture-analyst/teacher-portal-development-2025-11-24/ANALISIS-FASE-1-TEACHER-PORTAL.md - Plan:
orchestration/agentes/architecture-analyst/teacher-portal-development-2025-11-24/PLAN-DESARROLLO-FASE-2.md - Resumen:
orchestration/agentes/architecture-analyst/teacher-portal-development-2025-11-24/RESUMEN-FINAL-DESARROLLO-TEACHER-PORTAL.md
BE-132: Student-Teacher Integration (ARCH-INT-003) ✅
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Architecture-Analyst Fecha: 2025-11-24 Análisis ID: ARCH-INT-003
Resumen
Corrección de 5 GAPs identificados en la integración entre el Portal de Estudiantes y el Portal de Maestros, permitiendo que TeacherGamification consuma datos reales del backend.
GAPs Resueltos
| ID | Severidad | Descripción | Archivo |
|---|---|---|---|
| GAP-ST-001 | BLOCKER | Query usa score_percentage (no existe) |
teacher-classrooms-crud.service.ts:855,883 |
| GAP-ST-002 | DEGRADED | Falta current_module, current_exercise |
classroom-response.dto.ts |
| GAP-ST-003 | DEGRADED | Falta time_spent_minutes |
classroom-response.dto.ts |
| GAP-ST-004 | DEGRADED | Falta total_ml_coins, current_rank, achievements_count |
classroom-response.dto.ts |
| GAP-ST-005 | BLOCKER | Endpoint /teacher/analytics/economy no existe |
analytics.service.ts, teacher.controller.ts |
Implementaciones
Backend (6 archivos):
teacher-classrooms-crud.service.ts- Fixscore_percentage→average_scoreclassroom-response.dto.ts- +8 campos en StudentInClassroomDtoanalytics.dto.ts- +EconomyAnalyticsDto y DTOs relacionadosanalytics.service.ts- +métodogetEconomyAnalytics()teacher.controller.ts- +endpoint GET/analytics/economyroutes.constants.ts- +rutaANALYTICS_ECONOMY
Frontend (5 archivos):
api.config.ts- +endpointeconomyAnalyticsanalyticsApi.ts- +tipos e métodogetEconomyAnalytics()useEconomyAnalytics.ts- Nuevo hook Reacthooks/index.ts- Export del hookTeacherGamification.tsx- Integración con API real
Validación
- TypeScript Backend: ✅ Compila sin errores
- TypeScript Frontend: Errores pre-existentes, sin errores nuevos
Documentación
- Principal:
docs/90-transversal/INTEGRACION-STUDENT-TEACHER-PORTAL-2025-11-24.md - Inventario:
docs/90-transversal/inventarios/BACKEND_INVENTORY.yml(sección student_teacher_integration_2025_11_24)
BE-131: Teacher Portal Integration Fix (ARCH-INT-002) ✅
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Agents (4 paralelos, orquestados por Architecture-Analyst) Fecha: 2025-11-24 Análisis ID: ARCH-INT-002
Contexto
Análisis e implementación de correcciones para la integración del Teacher Portal, siguiendo las 3 fases obligatorias del protocolo de Architecture-Analyst.
Fases Ejecutadas
FASE 1: Análisis
- 178 endpoints inventariados (59 Teacher + 119 Admin)
- CORS correctamente configurado
- Puertos correctos (3005/3006)
- Identificados: tipos duplicados, routes.constants.ts desactualizado
FASE 2: Planeación
- 6 tareas definidas en 2 rondas paralelas
- Validación pre-implementación realizada
- Conflicto de Alert types identificado y resuelto
FASE 3: Ejecución
- Ronda 1: 4 agentes paralelos (Backend)
- Ronda 2: 2 agentes paralelos (Frontend)
Cambios Implementados
1. routes.constants.ts - Actualizado (+139 endpoints)
- Antes: 26 endpoints
- Después: 165 endpoints (57 Teacher + 108 Admin)
- Incremento: +534%
2. intervention-alerts.types.ts - Creado
- Ubicación:
apps/backend/src/shared/types/intervention-alerts.types.ts - Contenido: 3 enums + 1 interface
- Duplicación eliminada: ~45 líneas
3. MessageTypeEnum - Centralizado
- Agregado a
apps/backend/src/shared/constants/enums.constants.ts - Referencias actualizadas: 11 archivos
4. Imports actualizados (4 archivos)
modules/teacher/dto/intervention-alerts.dto.tsmodules/teacher/dto/teacher-messages.dto.tsmodules/teacher/entities/student-intervention-alert.entity.tsmodules/teacher/services/teacher-messages.service.ts
Archivos
| Archivo | Cambio | Estado |
|---|---|---|
shared/constants/routes.constants.ts |
+139 endpoints | ✅ |
shared/types/intervention-alerts.types.ts |
Creado | ✅ |
shared/types/index.ts |
Export agregado | ✅ |
shared/constants/enums.constants.ts |
MessageTypeEnum | ✅ |
modules/teacher/dto/intervention-alerts.dto.ts |
Imports actualizados | ✅ |
modules/teacher/dto/teacher-messages.dto.ts |
Imports actualizados | ✅ |
modules/teacher/entities/student-intervention-alert.entity.ts |
Imports actualizados | ✅ |
modules/teacher/services/teacher-messages.service.ts |
Imports actualizados | ✅ |
Validación
- ✅ TypeScript Build: Exitoso (npx tsc --noEmit)
- ✅ localhost:3000 check: 0 resultados
- ✅ Breaking changes: 0
Beneficios
- SSOT: Rutas API centralizadas
- Type Safety: Tipos centralizados sin duplicación
- Mantenibilidad: Cambios en un solo lugar
- Documentación: JSDoc completo
Documentación
- Reporte principal:
docs/90-transversal/INTEGRACION-TEACHER-PORTAL-APIs-2025-11-24.md - FASE 1:
orchestration/agentes/architecture-analyst/analisis-integracion-teacher-portal-2025-11-24/REPORTE-FASE1-ANALISIS.md - FASE 2:
orchestration/agentes/architecture-analyst/analisis-integracion-teacher-portal-2025-11-24/PLAN-FASE2-EJECUCION.md - Validación:
orchestration/agentes/architecture-analyst/analisis-integracion-teacher-portal-2025-11-24/VALIDACION-PRE-IMPLEMENTACION.md - Final:
orchestration/agentes/architecture-analyst/analisis-integracion-teacher-portal-2025-11-24/REPORTE-FINAL-IMPLEMENTACION.md
Pendientes Opcionales
- ⏳ Refactorizar 23 controllers para usar API_ROUTES constantes
- ⏳ Eliminar clave duplicada "classroomTeachers" en api.config.ts
BE-130: Admin Portal Integration Fix (ARCH-INT-001) ✅
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Agents (2 paralelos, orquestados por Architecture-Analyst) Fecha: 2025-11-24 Análisis ID: ARCH-INT-001
Problemas Resueltos
-
BE-INT-001: Puertos incorrectos 3000 → 3006
- 11 archivos tenían puerto 3000 hardcodeado cuando backend usa 3006
- Swagger, health checks, scripts de testing afectados
-
BE-INT-002: AuditLog Entity faltante en módulo admin
- Entity TypeORM para audit_logging.audit_logs no disponible en admin
- Implementado via re-export pattern desde módulo audit (DRY)
Archivos Modificados (12 total)
Puertos corregidos:
apps/backend/src/config/swagger.config.tsapps/backend/src/shared/middleware/cors.config.tsapps/backend/src/modules/mail/mail.service.ts(3000 → 3005)apps/backend/src/modules/health/README.md(4 referencias)apps/backend/scripts/test-monitoring-endpoints.shapps/backend/scripts/test-alerts-endpoints.shapps/backend/scripts/test-grant-bonus.shapps/backend/scripts/test-analytics-endpoints.shapps/backend/scripts/test-progress-endpoints.shapps/backend/test-teacher-content-endpoints.sh
Entity re-exported:
apps/backend/src/modules/admin/entities/index.ts- AuditLog, ActorType, Severity, Status desde audit module
Validación
- ✅ Backend Build: Exitoso (tsc)
- ✅ TypeScript errors: 0
- ✅ Breaking changes: 0
Documentación
- Reporte principal:
docs/90-transversal/CORRECCION-INTEGRACION-ADMIN-API-2025-11-24.md - Traza arquitectónica:
orchestration/trazas/TRAZA-ANALISIS-ARQUITECTURA.md (ARCH-INT-001) - Inventario actualizado:
docs/90-transversal/inventarios/BACKEND_INVENTORY.yml
BE-129: Implementar endpoints CRUD completos de Classrooms para Portal Teacher (2025-11-24)
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Agent Fecha: 2025-11-24 GAP Resuelto: GAP-TEACHER-001
Contexto
El portal de teacher presentaba error 404 (Not Found) al intentar cargar classrooms:
GET http://localhost:3006/api/v1/teacher/classrooms 404 (Not Found)
Impacto: El dashboard de teacher NO podía cargar classrooms, haciendo el portal NO FUNCIONAL para la gestión de aulas.
Causa raíz: Frontend implementado con 8 métodos en classroomsApi.ts pero backend SIN endpoints correspondientes.
Especificación de Endpoints Implementados
1. GET /api/v1/teacher/classrooms
- Descripción: Lista todos los classrooms del teacher autenticado
- Query params: page, limit, search, status, grade_level, subject
- Response: PaginatedClassroomsResponseDto
- Validaciones:
- Teacher debe existir
- Filtra por teacher_id (RLS)
- Respeta tenant_id (multi-tenant)
2. GET /api/v1/teacher/classrooms/:id
- Descripción: Obtiene classroom específico por ID
- Response: ClassroomDetailResponseDto
- Validaciones:
- Classroom debe existir
- Teacher debe tener acceso al classroom
- Incluye información completa (settings, metadata, co_teachers)
3. POST /api/v1/teacher/classrooms
- Descripción: Crea nuevo classroom
- Body: CreateClassroomDto
- Response: ClassroomResponseDto
- Validaciones:
- Asigna automáticamente teacher_id del usuario autenticado
- Asigna automáticamente tenant_id del profile del teacher
- Valida que código (code) sea único si se proporciona
- Crea relación teacher-classroom con rol 'owner'
4. PUT /api/v1/teacher/classrooms/:id
- Descripción: Actualiza classroom existente
- Body: UpdateClassroomDto (parcial)
- Response: ClassroomResponseDto
- Validaciones:
- Classroom debe existir
- Teacher debe tener acceso
- Código único si se modifica
5. DELETE /api/v1/teacher/classrooms/:id
- Descripción: Elimina (soft delete) classroom
- Response: { success: boolean, message: string }
- Validaciones:
- Solo el owner puede eliminar
- No puede tener estudiantes activos
- Marca como archived e inactive
6. GET /api/v1/teacher/classrooms/:id/students
- Descripción: Lista estudiantes del classroom
- Query params: page, limit, status, search, sort_by, sort_order
- Response: PaginatedStudentsResponseDto
- Incluye: user_id, full_name, email, avatar, enrollment_date, status, progress_percentage, score_average, last_activity
7. GET /api/v1/teacher/classrooms/:id/stats
- Descripción: Estadísticas del classroom
- Response: ClassroomStatsDto
- Incluye: total_students, active_students, avg_progress, completion_rate, avg_score, avg_attendance
8. GET /api/v1/teacher/classrooms/:classroomId/teachers
- Descripción: Lista teachers asignados al classroom
- Response: TeacherInClassroomDto[]
- Incluye: user_id, full_name, email, role (owner/teacher/assistant), assigned_at
Archivos Creados
DTOs (2 archivos):
-
/apps/backend/src/modules/teacher/dto/classroom.dto.ts(317 líneas)- CreateClassroomDto: 20 campos con validaciones class-validator
- UpdateClassroomDto: Partial de CreateClassroomDto + is_active/is_archived
- GetClassroomsQueryDto: Paginación y filtros
- GetClassroomStudentsQueryDto: Paginación y ordenamiento
-
/apps/backend/src/modules/teacher/dto/classroom-response.dto.ts(229 líneas)- ClassroomResponseDto: 18 campos básicos
- ClassroomDetailResponseDto: Extiende basic + settings/metadata
- StudentInClassroomDto: 11 campos con datos de progreso
- ClassroomStatsDto: 10 métricas agregadas
- TeacherInClassroomDto: 5 campos con rol
- PaginatedClassroomsResponseDto
- PaginatedStudentsResponseDto
Services (1 archivo):
/apps/backend/src/modules/teacher/services/teacher-classrooms-crud.service.ts(796 líneas)- 8 métodos públicos (CRUD completo)
- 6 métodos helper privados
- Validaciones de permisos (RLS)
- Queries optimizadas con TypeORM
- Soft delete implementado
- Multi-tenant support
Archivos Modificados
Controller (1 archivo):
/apps/backend/src/modules/teacher/controllers/teacher-classrooms.controller.ts- Agregados 8 endpoints CRUD (líneas 81-434)
- Endpoints existentes de student management preservados (líneas 435+)
- Guards: JwtAuthGuard + TeacherGuard
- Swagger completo en todos los endpoints
Module (1 archivo):
/apps/backend/src/modules/teacher/teacher.module.ts- Agregado TeacherClassroomsCrudService a providers
- Agregado a exports
Índices (2 archivos):
-
/apps/backend/src/modules/teacher/dto/index.ts- Exportados classroom.dto y classroom-response.dto
-
/apps/backend/src/modules/teacher/services/index.ts- Exportado teacher-classrooms-crud.service
Características Técnicas Implementadas
Seguridad y Validaciones:
- ✅ Row Level Security (RLS): Solo acceso a classrooms del teacher
- ✅ Multi-tenant: Respeta tenant_id del teacher
- ✅ Ownership validation: Solo owner puede eliminar classrooms
- ✅ Business rules: No eliminar classroom con estudiantes activos
- ✅ JWT required: @UseGuards(JwtAuthGuard, TeacherGuard)
DTOs y Validaciones:
- ✅ class-validator en todos los DTOs de entrada
- ✅ Swagger decorators completos (@ApiProperty, @ApiOperation, @ApiResponse)
- ✅ JSDoc en todos los métodos públicos
Queries Optimizadas:
- ✅ Paginación en todos los listados
- ✅ Búsqueda por múltiples criterios
- ✅ Ordenamiento personalizable
- ✅ Joins eficientes para datos relacionados
- ✅ Cálculo de estadísticas con agregaciones SQL
Mapeo de Entities:
- ✅ Classroom (social_features.classrooms)
- ✅ TeacherClassroom (social_features.teacher_classrooms)
- ✅ ClassroomMember (social_features.classroom_members)
- ✅ Profile (auth_management.profiles)
- ✅ User (auth_management.users)
- ✅ ModuleProgress (learning_progress.module_progress)
Validación
Build TypeScript:
cd apps/backend
npx tsc --noEmit
✅ Sin errores de tipos
Build completo:
npm run build
✅ Exitoso
Endpoints disponibles en Swagger:
- http://localhost:3006/api/docs
- Tag: "Teacher - Classrooms"
- 8 endpoints CRUD + 4 endpoints student management
Comparación Frontend ↔ Backend
Frontend: apps/frontend/src/services/api/teacher/classroomsApi.ts
| Método Frontend | Endpoint | Backend Status |
|---|---|---|
getClassrooms() |
GET /teacher/classrooms | ✅ Implementado |
getClassroomById(id) |
GET /teacher/classrooms/:id | ✅ Implementado |
getClassroomStudents(id) |
GET /teacher/classrooms/:id/students | ✅ Implementado |
getClassroomStats(id) |
GET /teacher/classrooms/:id/stats | ✅ Implementado |
createClassroom(data) |
POST /teacher/classrooms | ✅ Implementado |
updateClassroom(id, data) |
PUT /teacher/classrooms/:id | ✅ Implementado |
deleteClassroom(id) |
DELETE /teacher/classrooms/:id | ✅ Implementado |
getClassroomTeachers(id) |
GET /teacher/classrooms/:id/teachers | ✅ Implementado |
Coherencia Frontend ↔ Backend: 100% ✅
Impacto
Antes:
- Portal teacher: NO FUNCIONAL
- Dashboard: Error 404 al cargar classrooms
- Funcionalidades bloqueadas: gestión de aulas, visualización de estudiantes, estadísticas
- Gap: GAP-TEACHER-001 (CRÍTICO)
Después:
- Portal teacher: FUNCIONAL
- Dashboard: Carga classrooms correctamente
- Funcionalidades desbloqueadas: CRUD completo de aulas
- Gap resuelto: GAP-TEACHER-001 ✅
Próximos Pasos
Recomendaciones:
- Implementar tests E2E para los nuevos endpoints
- Implementar GAP-TEACHER-002: Assignments CRUD endpoints
- Implementar GAP-TEACHER-003: Grades endpoints
- Agregar paginación mejorada con cursors para listas grandes
- Implementar caché para estadísticas de classroom (Redis)
Referencias
Análisis arquitectónico:
orchestration/agentes/architecture-analyst/gap-analysis-teacher-portal-2025-11-24/GAP-TEACHER-PORTAL-ENDPOINTS-ANALYSIS.md
Frontend de referencia:
apps/frontend/src/services/api/teacher/classroomsApi.ts(líneas 82-352)
Routes constants:
apps/backend/src/shared/constants/routes.constants.ts(líneas 378-381)
Entities:
apps/backend/src/modules/social/entities/classroom.entity.tsapps/backend/src/modules/social/entities/teacher-classroom.entity.tsapps/backend/src/modules/social/entities/classroom-member.entity.ts
BE-128: Corregir 4 DTOs incompatibles Backend↔Frontend (2025-11-24)
Estado: COMPLETADA Prioridad: P0 CRÍTICO Asignado: Backend-Developer Fecha: 2025-11-24
Contexto
Auditoría de coherencia Backend↔Frontend identificó 4 DTOs incompatibles que causaban datos incorrectos en AdminDashboardPage y AdminGamificationPage.
Gaps Resueltos
GAP-FE-001: RecentActionDto Incompatible (P0 CRÍTICO)
- Archivo:
apps/backend/src/modules/admin/dto/dashboard/recent-actions.dto.ts - Problema: Backend tenía 5 campos, frontend esperaba 9 campos
- Coherencia anterior: 40%
- Coherencia actual: 100%
- Cambios:
- DTO actualizado con 9 campos completos: id, action, actionType, adminId, adminName, targetType, targetId, details, timestamp, success
- Service actualizado con query enriquecido (JOINs con auth.users, metadata completa)
GAP-FE-002: UserActivityDto Incompatible (P0 CRÍTICO)
- Archivo:
apps/backend/src/modules/admin/dto/dashboard/user-activity.dto.ts - Problema: Backend retornaba solo labels/data, frontend esperaba también tableData con métricas detalladas
- Coherencia anterior: 0% (estructuras incompatibles)
- Coherencia actual: 100%
- Cambios:
- Nuevo DTO: UserActivityDataPointDto con 5 campos (date, activeUsers, newRegistrations, totalSessions, avgSessionDuration)
- UserActivityDto ahora retorna labels, data Y tableData
- Service actualizado con query CTE complejo (user_logins, new_users, activity_sessions)
GAP-FE-003: AlertDto Enums Incompatibles (P1)
- Archivo:
apps/backend/src/modules/admin/dto/dashboard/alerts.dto.ts - Problema: Enums diferentes, faltaban campos title/details
- Coherencia anterior: 50%
- Coherencia actual: 100%
- Cambios:
- Enum type cambiado a: 'error' | 'warning' | 'info' | 'security'
- Agregados campos: title, details (opcional)
- Campo acknowledged renombrado a dismissed
- Service actualizado con 5 tipos de alertas (contenido pendiente, usuarios inactivos, email sin verificar, baja participación, contenido reportado)
GAP-FE-004: MayaRankDto Minimal (P0 CRÍTICO)
- Archivo:
apps/backend/src/modules/admin/dto/gamification-config/maya-rank-response.dto.ts - Problema: Backend tenía 4 campos, frontend esperaba 13 campos
- Coherencia anterior: 23%
- Coherencia actual: 100%
- Cambios:
- DTO actualizado con 13 campos: id, name, level, minXp, maxXp, multiplierXp, multiplierMlCoins, bonusMlCoins, color, icon, description, perks, isActive, order
- Service actualizado para query directo a tabla gamification_system.maya_ranks
- Parsing de JSONB perks a array
Archivos Modificados
DTOs (4 archivos):
/apps/backend/src/modules/admin/dto/dashboard/recent-actions.dto.ts/apps/backend/src/modules/admin/dto/dashboard/user-activity.dto.ts/apps/backend/src/modules/admin/dto/dashboard/alerts.dto.ts/apps/backend/src/modules/admin/dto/gamification-config/maya-rank-response.dto.ts
Services (2 archivos):
/apps/backend/src/modules/admin/services/admin-dashboard.service.ts- getRecentActions() - Líneas 535-606
- getAlerts() - Líneas 621-755
- getUserActivity() - Líneas 735-857
/apps/backend/src/modules/admin/services/gamification-config.service.ts- getMayaRanks() - Líneas 753-815
Tests (1 archivo):
/apps/backend/src/modules/admin/__tests__/admin-gamification-config-us-ae-005.controller.spec.ts- Actualizado mock de MayaRanksResponseDto (líneas 275-378)
Validación
Compilación TypeScript:
npm run build
✅ Sin errores relacionados con los cambios (errores pre-existentes en otros módulos)
Endpoints Afectados:
GET /api/admin/dashboard/actions/recent- RecentActionDtoGET /api/admin/dashboard/alerts- AlertDtoGET /api/admin/dashboard/analytics/user-activity- UserActivityDtoGET /api/admin/gamification-config/maya-ranks- MayaRankDto
Impacto en Coherencia
Antes:
- Coherencia Backend↔Frontend: 82%
- 4 DTOs incompatibles
- AdminDashboardPage: 3 secciones con datos incorrectos
- AdminGamificationPage: metadata de ranks incompleta
Después:
- Coherencia Backend↔Frontend: 95% ✅
- 0 DTOs incompatibles
- AdminDashboardPage: Todas las secciones con datos correctos
- AdminGamificationPage: metadata de ranks completa
Referencias
- Reporte de coherencia:
orchestration/reportes/REPORTE-COHERENCIA-BACKEND-FRONTEND-2025-11-24.md - Ticket original: Issue #128 - Coherencia Backend↔Frontend
- Database completada: DB-127 (gaps database resueltos por Database-Agent)
Notas
- Query getMayaRanks() ahora accede directamente a tabla gamification_system.maya_ranks
- Query getUserActivity() usa CTE complejo con generate_series para cubrir todos los períodos
- Query getRecentActions() combina auth.users y auth.tenants con LEFT JOINs
- Todos los cambios son backward-compatible con frontend existente