---
id: "RF-EDU-003"
title: "Tracking de Progreso"
type: "Requirement"
status: "Done"
priority: "Alta"
module: "education"
epic: "OQI-002"
version: "1.0"
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# RF-EDU-003: Tracking de Progreso

**Versión:** 1.0.0
**Fecha:** 2025-12-05
**Épica:** OQI-002 - Módulo Educativo
**Prioridad:** P0
**Story Points:** 8

---

## Descripción

El sistema debe proporcionar un sistema completo de seguimiento y visualización del progreso educativo del usuario, incluyendo métricas de avance, estadísticas de aprendizaje, historial de actividades y reportes de rendimiento para mantener la motivación y permitir evaluación del desempeño.

---

## Requisitos Funcionales

### RF-EDU-003.1: Dashboard de Progreso

El sistema debe mostrar:
- Resumen general de aprendizaje del usuario
- Total de cursos: En progreso, Completados, Guardados
- Total de lecciones completadas
- Total de horas de aprendizaje
- Racha actual (días consecutivos de actividad)
- Racha más larga histórica
- XP total acumulado
- Nivel actual del usuario
- Gráfico de actividad semanal/mensual

### RF-EDU-003.2: Progreso por Curso

El sistema debe mostrar para cada curso:
- Porcentaje de completitud (0-100%)
- Lecciones completadas / Total de lecciones
- Módulos completados / Total de módulos
- Tiempo invertido en el curso
- Última vez que accedió al curso
- Fecha de inscripción
- Fecha de finalización (si completó)
- Próxima lección sugerida
- Barra de progreso visual

### RF-EDU-003.3: Historial de Actividad

El sistema debe registrar:
- Timeline de actividades del usuario
- Eventos: inscripción, lección completada, quiz aprobado, certificado obtenido
- Fecha y hora de cada evento
- Filtros por tipo de evento y rango de fechas
- Exportar historial a CSV

Tipos de eventos:
```typescript
enum ActivityType {
  COURSE_ENROLLED = 'course_enrolled',
  LESSON_STARTED = 'lesson_started',
  LESSON_COMPLETED = 'lesson_completed',
  MODULE_COMPLETED = 'module_completed',
  COURSE_COMPLETED = 'course_completed',
  QUIZ_PASSED = 'quiz_passed',
  QUIZ_FAILED = 'quiz_failed',
  CERTIFICATE_EARNED = 'certificate_earned',
  NOTE_CREATED = 'note_created',
  RESOURCE_DOWNLOADED = 'resource_downloaded',
}
```

### RF-EDU-003.4: Estadísticas de Aprendizaje

El sistema debe calcular y mostrar:
- **Tiempo promedio por lección:** Total minutos / lecciones completadas
- **Cursos por mes:** Cursos completados en último mes
- **Tasa de completitud:** % de cursos iniciados que fueron completados
- **Días activos:** Días con al menos 1 lección completada
- **Mejor día de la semana:** Día con más actividad
- **Hora preferida:** Franja horaria con más actividad
- **Categoría favorita:** Categoría con más cursos completados
- **Velocidad de aprendizaje:** Comparación con promedio de usuarios

### RF-EDU-003.5: Racha de Aprendizaje (Streak)

El sistema debe:
- Calcular racha actual: días consecutivos con actividad
- Definir actividad como: completar al menos 1 lección
- Resetear racha si pasa 1 día sin actividad
- Guardar racha más larga histórica
- Mostrar calendario de actividad (estilo GitHub contributions)
- Enviar notificación si racha está en riesgo (no actividad hoy)
- Otorgar badges especiales por rachas: 7, 30, 100, 365 días

### RF-EDU-003.6: Sistema de Niveles

El sistema debe:
- Asignar nivel al usuario basado en XP acumulado
- XP se gana por:
  - Completar lección: 10 XP
  - Completar módulo: 50 XP
  - Completar curso: 200 XP
  - Aprobar quiz primera vez: 30 XP
  - Obtener certificado: 100 XP
  - Racha de 7 días: 100 XP
- Niveles del 1 al 50
- XP requerido por nivel aumenta progresivamente

Fórmula XP por nivel:
```
XP_needed(level) = 100 * level * (level + 1) / 2
```

| Nivel | XP Requerido | XP Acumulado |
|-------|--------------|--------------|
| 1 | 0 | 0 |
| 2 | 100 | 100 |
| 3 | 200 | 300 |
| 5 | 400 | 1000 |
| 10 | 900 | 5500 |
| 20 | 1900 | 21000 |
| 50 | 4900 | 127500 |

### RF-EDU-003.7: Reportes de Progreso

El sistema debe generar:
- Reporte semanal por email (opcional)
- Reporte mensual con estadísticas
- Exportar progreso a PDF
- Comparación mes a mes
- Metas vs realidad

### RF-EDU-003.8: Metas de Aprendizaje

El sistema debe permitir:
- Establecer meta de lecciones por semana
- Establecer meta de cursos por mes
- Establecer meta de minutos de estudio por día
- Visualizar progreso hacia metas
- Notificaciones si está rezagado
- Celebración al cumplir meta

---

## Datos de Salida

```typescript
interface UserProgress {
  userId: string;
  overview: {
    coursesInProgress: number;
    coursesCompleted: number;
    coursesSaved: number;
    lessonsCompleted: number;
    totalLearningTime: number; // minutos
    currentStreak: number;
    longestStreak: number;
    totalXP: number;
    currentLevel: number;
    xpToNextLevel: number;
  };

  courses: {
    courseId: string;
    courseTitle: string;
    thumbnail: string;
    progress: {
      percent: number;
      lessonsCompleted: number;
      totalLessons: number;
      modulesCompleted: number;
      totalModules: number;
      timeSpent: number;
      enrolledAt: string;
      completedAt?: string;
      lastAccessedAt: string;
      nextLesson?: {
        id: string;
        title: string;
      };
    };
  }[];

  stats: {
    avgTimePerLesson: number;
    coursesThisMonth: number;
    completionRate: number; // 0-100
    activeDays: number;
    favoriteCategory: string;
    bestDayOfWeek: string;
    preferredTimeOfDay: string;
  };

  recentActivity: {
    type: ActivityType;
    title: string;
    description: string;
    timestamp: string;
    metadata?: any;
  }[];

  calendar: {
    date: string; // YYYY-MM-DD
    lessonsCompleted: number;
    minutesLearned: number;
  }[];
}

interface LevelInfo {
  currentLevel: number;
  currentXP: number;
  xpForCurrentLevel: number;
  xpForNextLevel: number;
  progressToNextLevel: number; // 0-100
  title: string; // "Novice Trader", "Advanced Analyst", etc.
}
```

---

## Reglas de Negocio

1. **Actividad mínima:** 1 lección completada para contar como día activo
2. **Racha:** Se resetea si pasan >24h sin actividad
3. **XP no se pierde:** Una vez ganado, el XP es permanente
4. **Nivel no baja:** Los niveles solo suben, nunca bajan
5. **Tiempo de aprendizaje:** Solo cuenta tiempo activo (reproducción de video, scroll en artículo)
6. **Caché de stats:** Estadísticas se calculan cada hora, no en tiempo real
7. **Zona horaria:** Racha se calcula según timezone del usuario
8. **Reporte semanal:** Se envía lunes a las 8am hora local
9. **Completitud de curso:** 100% cuando todas las lecciones están completas

---

## Criterios de Aceptación

```gherkin
Escenario: Usuario visualiza dashboard de progreso
  DADO que el usuario está autenticado
  CUANDO accede a /education/progress
  ENTONCES se muestra resumen general de aprendizaje
  Y se muestran estadísticas: cursos, lecciones, horas
  Y se muestra racha actual y más larga
  Y se muestra nivel y XP
  Y se muestra gráfico de actividad reciente

Escenario: Usuario visualiza progreso de curso
  DADO que el usuario está inscrito en un curso
  CUANDO ve la tarjeta del curso en el dashboard
  ENTONCES se muestra barra de progreso con porcentaje
  Y se muestra "X/Y lecciones completadas"
  Y se muestra tiempo invertido
  Y se muestra botón "Continuar" que lleva a próxima lección

Escenario: Usuario mantiene racha activa
  DADO que el usuario tiene racha de 5 días
  CUANDO completa 1 lección hoy
  ENTONCES la racha aumenta a 6 días
  Y se muestra animación de celebración
  Y se actualiza calendario de actividad

Escenario: Usuario rompe racha
  DADO que el usuario tiene racha de 10 días
  Y no completó lecciones ayer
  CUANDO accede hoy
  ENTONCES la racha se resetea a 0 o 1 (según actividad de hoy)
  Y se muestra mensaje "Racha reiniciada"
  Y se guarda racha anterior como "mejor racha"

Escenario: Usuario sube de nivel
  DADO que el usuario tiene 950 XP (nivel 9)
  CUANDO completa un curso y gana 200 XP
  ENTONCES sube a nivel 10
  Y se muestra animación "¡Subiste de nivel!"
  Y se desbloquea nuevo badge
  Y se envía notificación

Escenario: Ver historial de actividad
  DADO que el usuario accede a historial
  CUANDO filtra por "últimos 7 días"
  ENTONCES se muestran todas las actividades de la semana
  Y se agrupan por día
  Y se muestra timeline visual
```

---

## Dependencias

- PostgreSQL para almacenar progreso
- Redis para caché de estadísticas
- Cron jobs para calcular stats diarias
- Email service para reportes semanales
- Analytics para tracking de eventos

---

## Notas Técnicas

- Calcular estadísticas agregadas en background jobs (no en request)
- Usar materialized views para queries pesadas
- Implementar cache warming para stats de usuarios activos
- Considerar Event Sourcing para historial de actividades
- Optimizar queries con índices en user_id + timestamp
- Implementar rate limiting en export de reportes

---

## Referencias

- Schema: `/backend/src/database/schemas/education.sql`
- API: `/backend/src/modules/courses/progress.routes.ts`
- Frontend: `/frontend/src/pages/EducationDashboard.tsx`

---

## Tareas Técnicas

**Database:**
- [ ] Tabla user_course_progress: percent, lessons_completed, time_spent
- [ ] Tabla user_activity_log: tipo, timestamp, metadata
- [ ] Tabla user_stats: nivel, xp, racha, cache de stats
- [ ] Tabla user_goals: meta, progreso, fecha
- [ ] Índices en user_id + timestamp para queries rápidas
- [ ] Materialized view para stats agregadas

**Backend:**
- [ ] Endpoint GET /education/progress (dashboard completo)
- [ ] Endpoint GET /education/progress/stats
- [ ] Endpoint GET /education/progress/activity (historial)
- [ ] Endpoint POST /education/goals (crear meta)
- [ ] Implementar ProgressService.calculateLevel()
- [ ] Implementar ProgressService.updateStreak() (cron daily)
- [ ] Job para generar reportes semanales
- [ ] Event handlers para actualizar XP en actividades

**Frontend:**
- [ ] Crear EducationDashboardPage.tsx
- [ ] Crear componente ProgressOverview.tsx
- [ ] Crear componente CourseProgressCard.tsx
- [ ] Crear componente ActivityCalendar.tsx (estilo GitHub)
- [ ] Crear componente LevelProgress.tsx
- [ ] Crear componente ActivityTimeline.tsx
- [ ] Crear componente StatsCharts.tsx
- [ ] Animaciones para level up y racha
- [ ] Implementar progressStore

**Tests:**
- [ ] Test cálculo de nivel según XP
- [ ] Test cálculo de racha con diferentes escenarios
- [ ] Test E2E completar lección y ver progreso actualizado

---

**Creado por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05
