- 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>
943 lines
34 KiB
Markdown
943 lines
34 KiB
Markdown
# 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-data` con 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)
|
|
1. `verificador_fake_news` - Verificación de noticias falsas
|
|
2. `infografia_interactiva` - Creación de infografías
|
|
3. `quiz_tiktok` - Quiz estilo TikTok
|
|
4. `navegacion_hipertextual` - Navegación en hipertextos
|
|
5. `analisis_memes` - Análisis crítico de memes
|
|
|
|
#### Módulo 5 - Producción Lectora (3 ejercicios)
|
|
1. `diario_multimedia` - Diario con texto/audio/video
|
|
2. `comic_digital` - Creación de cómics digitales
|
|
3. `video_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 build` exitoso
|
|
|
|
### Base de Datos
|
|
|
|
Tablas creadas (ver DB-137):
|
|
- `educational_content.media_attachments`
|
|
- `progress_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:**
|
|
1. Implementar notificaciones push para docentes (envío pendiente)
|
|
2. Agregar analytics de tiempos de revisión
|
|
3. Implementar sistema de apelaciones
|
|
4. Agregar soporte para más formatos (PDF, documentos)
|
|
5. 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):**
|
|
```typescript
|
|
import { AchievementsService } from '../../gamification/services/achievements.service';
|
|
```
|
|
|
|
**2. Constructor - Inyección de dependencia:**
|
|
```typescript
|
|
constructor(
|
|
// ... otros servicios
|
|
private readonly achievementsService: AchievementsService,
|
|
) {}
|
|
```
|
|
|
|
**3. Método submitAttempt() - Detección de logros post-rewards:**
|
|
```typescript
|
|
// 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
|
|
|
|
1. Estudiante completa ejercicio
|
|
2. `submitAttempt()` valida respuestas
|
|
3. Si es correcto: `awardRewards()` otorga XP y ML Coins
|
|
4. **NUEVO:** `detectAndGrantEarned()` verifica condiciones de logros
|
|
5. Logros desbloqueados se insertan en `user_achievements`
|
|
6. 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 `exerciseXpReward` y `exerciseMlCoinsReward` a 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):**
|
|
```typescript
|
|
// 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):**
|
|
1. `teacher-classrooms-crud.service.ts` - Fix `score_percentage` → `average_score`
|
|
2. `classroom-response.dto.ts` - +8 campos en StudentInClassroomDto
|
|
3. `analytics.dto.ts` - +EconomyAnalyticsDto y DTOs relacionados
|
|
4. `analytics.service.ts` - +método `getEconomyAnalytics()`
|
|
5. `teacher.controller.ts` - +endpoint GET `/analytics/economy`
|
|
6. `routes.constants.ts` - +ruta `ANALYTICS_ECONOMY`
|
|
|
|
**Frontend (5 archivos):**
|
|
1. `api.config.ts` - +endpoint `economyAnalytics`
|
|
2. `analyticsApi.ts` - +tipos e método `getEconomyAnalytics()`
|
|
3. `useEconomyAnalytics.ts` - Nuevo hook React
|
|
4. `hooks/index.ts` - Export del hook
|
|
5. `TeacherGamification.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.ts`
|
|
- `modules/teacher/dto/teacher-messages.dto.ts`
|
|
- `modules/teacher/entities/student-intervention-alert.entity.ts`
|
|
- `modules/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
|
|
|
|
1. **SSOT:** Rutas API centralizadas
|
|
2. **Type Safety:** Tipos centralizados sin duplicación
|
|
3. **Mantenibilidad:** Cambios en un solo lugar
|
|
4. **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
|
|
|
|
1. ⏳ Refactorizar 23 controllers para usar API_ROUTES constantes
|
|
2. ⏳ 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
|
|
|
|
1. **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
|
|
|
|
2. **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.ts`
|
|
- `apps/backend/src/shared/middleware/cors.config.ts`
|
|
- `apps/backend/src/modules/mail/mail.service.ts` (3000 → 3005)
|
|
- `apps/backend/src/modules/health/README.md` (4 referencias)
|
|
- `apps/backend/scripts/test-monitoring-endpoints.sh`
|
|
- `apps/backend/scripts/test-alerts-endpoints.sh`
|
|
- `apps/backend/scripts/test-grant-bonus.sh`
|
|
- `apps/backend/scripts/test-analytics-endpoints.sh`
|
|
- `apps/backend/scripts/test-progress-endpoints.sh`
|
|
- `apps/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:**
|
|
```bash
|
|
cd apps/backend
|
|
npx tsc --noEmit
|
|
```
|
|
✅ Sin errores de tipos
|
|
|
|
**Build completo:**
|
|
```bash
|
|
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:**
|
|
1. Implementar tests E2E para los nuevos endpoints
|
|
2. Implementar GAP-TEACHER-002: Assignments CRUD endpoints
|
|
3. Implementar GAP-TEACHER-003: Grades endpoints
|
|
4. Agregar paginación mejorada con cursors para listas grandes
|
|
5. 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.ts`
|
|
- `apps/backend/src/modules/social/entities/teacher-classroom.entity.ts`
|
|
- `apps/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:**
|
|
```bash
|
|
npm run build
|
|
```
|
|
✅ Sin errores relacionados con los cambios (errores pre-existentes en otros módulos)
|
|
|
|
**Endpoints Afectados:**
|
|
- `GET /api/admin/dashboard/actions/recent` - RecentActionDto
|
|
- `GET /api/admin/dashboard/alerts` - AlertDto
|
|
- `GET /api/admin/dashboard/analytics/user-activity` - UserActivityDto
|
|
- `GET /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
|