---
id: "US-EDU-005"
title: "Completar Leccion"
type: "User Story"
status: "Done"
priority: "Alta"
epic: "OQI-002"
story_points: 3
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# US-EDU-005: Completar Lección

## Metadata

| Campo | Valor |
|-------|-------|
| **ID** | US-EDU-005 |
| **Épica** | OQI-002 - Módulo Educativo |
| **Módulo** | education |
| **Prioridad** | P0 |
| **Story Points** | 3 |
| **Sprint** | Sprint 3 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |

---

## Historia de Usuario

**Como** usuario viendo una lección,
**quiero** marcar la lección como completada y ganar recompensas,
**para** registrar mi progreso, desbloquear siguiente contenido y acumular XP.

## Descripción Detallada

El usuario debe poder completar lecciones de forma automática (al ver 90% del video o llegar al final de un artículo) o manual (checkbox "marcar como completada"). Al completar, el sistema debe registrar el progreso, otorgar XP, actualizar estadísticas del usuario, desbloquear la siguiente lección si el curso es secuencial, mostrar celebración visual, y sugerir el siguiente paso.

## Mockups/Wireframes

```
[VIDEO AL 90%]
┌─────────────────────────────────────────────────────────────────┐
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━●  11:00 / 12:15            │
└─────────────────────────────────────────────────────────────────┘

[ANIMACIÓN DE CELEBRACIÓN]
┌─────────────────────────────────────────────────────────────────┐
│                        ✨ ✨ ✨                                  │
│                                                                  │
│                   ✓ ¡LECCIÓN COMPLETADA!                        │
│                                                                  │
│              Niveles principales de Fibonacci                   │
│                                                                  │
│                     +10 XP ganados                              │
│                                                                  │
│                   Progreso del curso: 50%                       │
│                  ████████████░░░░░░░░                           │
│                                                                  │
│           ┌────────────────────────────────────┐                │
│           │  [Siguiente lección →]             │                │
│           │  Cómo dibujar Fibonacci            │                │
│           └────────────────────────────────────┘                │
│                                                                  │
│                   [Volver al curso]                             │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[ARTÍCULO - CHECKBOX AL FINAL]
┌─────────────────────────────────────────────────────────────────┐
│  ... contenido del artículo ...                                 │
│                                                                  │
│  Conclusión                                                      │
│  En esta lección aprendiste los fundamentos de...               │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │  ☐ Marcar como completada                                  │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  [← Anterior]                      [Siguiente lección →]        │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[SIDEBAR ACTUALIZADO]
┌────────────────────────┐
│ TEMARIO                │
│ ✓ Módulo 1 (4/4) ✓     │
│ ▼ Módulo 2 (2/4)       │
│   ✓ 1. Niveles princ.  │ ← Completada
│   ● 2. Dibujar Fib.    │ ← Desbloqueada
│   🔒 3. Práctica        │
│   🔒 4. Quiz            │
│ 🔒 Módulo 3            │
└────────────────────────┘
```

---

## Criterios de Aceptación

**Escenario 1: Completar video automáticamente**
```gherkin
DADO que el usuario está viendo un video
CUANDO el video alcanza el 90% de reproducción (10:48 de 12:00)
ENTONCES la lección se marca automáticamente como completada
Y se registra completed_at en backend
Y se muestra modal de celebración con confeti
Y se muestra "+10 XP ganados"
Y se actualiza barra de progreso del curso
Y se actualiza sidebar con checkmark ✓
Y si curso es secuencial, se desbloquea siguiente lección
```

**Escenario 2: Completar artículo manualmente**
```gherkin
DADO que el usuario está leyendo un artículo
Y scrolleó hasta el final
CUANDO hace click en checkbox "Marcar como completada"
ENTONCES se marca la lección como completada
Y se registra en backend
Y se muestra toast "+15 XP ganados"
Y se habilita botón "Siguiente lección"
Y checkbox cambia a checked ✓
```

**Escenario 3: Ganar XP por completar**
```gherkin
DADO que el usuario completa una lección de video
ENTONCES se otorgan 10 XP
Y se actualiza totalXP del usuario
Y se verifica si sube de nivel
Y si sube de nivel, se muestra animación adicional
Y se actualiza badge de nivel en UI
```

**Escenario 4: Desbloquear siguiente lección**
```gherkin
DADO que el curso es secuencial
Y el usuario completa lección 3 del módulo 2
ENTONCES la lección 4 del módulo 2 se desbloquea
Y el candado 🔒 se remueve del sidebar
Y el usuario puede acceder a esa lección
Y si intenta saltarse a lección 5, sigue bloqueada
```

**Escenario 5: Completar módulo completo**
```gherkin
DADO que el usuario completa la última lección de un módulo
CUANDO se marca la lección como completada
ENTONCES también se completa el módulo
Y se otorgan +50 XP adicionales por módulo
Y se muestra "¡Módulo completado!"
Y se desbloquea el siguiente módulo (si es secuencial)
Y se actualiza contador "Módulo 2 (4/4) ✓"
```

**Escenario 6: Completar curso completo**
```gherkin
DADO que el usuario completa la última lección del último módulo
CUANDO se marca como completada
ENTONCES se completa el curso
Y se otorgan +200 XP adicionales por curso
Y se muestra modal "¡CURSO COMPLETADO!"
Y se genera certificado automáticamente
Y se muestra botón "Descargar certificado"
Y se envía email de felicitación
```

**Escenario 7: Sugerir siguiente paso**
```gherkin
DADO que el usuario completó una lección
CUANDO se muestra el modal de celebración
ENTONCES se sugiere la siguiente lección
Y se muestra título y duración de la siguiente
Y botón "Siguiente lección" navega directamente
Y también hay opción "Volver al curso"
Y si no hay siguiente lección, sugiere otro curso
```

**Escenario 8: Re-marcar como incompleta**
```gherkin
DADO que el usuario marcó una lección como completada
Y quiere revisarla de nuevo
CUANDO desmarca el checkbox
ENTONCES la lección vuelve a estado incompleto
Y el progreso del curso se actualiza (disminuye)
Y NO se quita el XP ya ganado
Y la lección puede volver a marcarse como completada
```

**Escenario 9: Actualizar racha diaria**
```gherkin
DADO que es el primer día del usuario en la plataforma
CUANDO completa su primera lección
ENTONCES se inicia racha de 1 día
Y se muestra toast "¡Racha iniciada! 🔥 1 día"

DADO que el usuario tiene racha de 5 días
Y completa su primera lección del día
ENTONCES la racha aumenta a 6 días
Y se muestra "¡Racha de 6 días! 🔥"
```

**Escenario 10: Primera lección del día bonus**
```gherkin
DADO que el usuario NO completó lecciones hoy
CUANDO completa su primera lección del día
ENTONCES recibe +5 XP adicionales de bonus
Y se muestra "+10 XP + 5 XP (bonus diario)"
```

## Criterios Adicionales

- [ ] Animación de confeti al completar
- [ ] Sonido de celebración (opcional, con toggle)
- [ ] Compartir logro en redes sociales
- [ ] Badges especiales por milestones (10, 50, 100 lecciones)
- [ ] Actualizar calendario de actividad
- [ ] Notificación push si está habilitado

---

## Tareas Técnicas

**Database:**
- [ ] DB-EDU-012: Campo completed_at en user_lesson_progress
- [ ] DB-EDU-013: Tabla user_xp_transactions (log de XP ganado)
- [ ] DB-EDU-014: Campo current_streak en users

**Backend:**
- [ ] BE-EDU-028: Endpoint POST /education/lessons/:id/complete
- [ ] BE-EDU-029: Implementar LessonService.markAsCompleted()
- [ ] BE-EDU-030: Verificar si es primera del día (bonus XP)
- [ ] BE-EDU-031: Otorgar XP según tipo de lección
- [ ] BE-EDU-032: Verificar si completa módulo
- [ ] BE-EDU-033: Verificar si completa curso
- [ ] BE-EDU-034: Desbloquear siguiente lección/módulo
- [ ] BE-EDU-035: Actualizar racha diaria
- [ ] BE-EDU-036: Verificar si sube de nivel
- [ ] BE-EDU-037: Event handler para generar certificado
- [ ] BE-EDU-038: Enviar email de curso completado

**Frontend:**
- [ ] FE-EDU-038: Componente LessonCompleteModal.tsx
- [ ] FE-EDU-039: Animación de confeti con react-confetti
- [ ] FE-EDU-040: Actualizar sidebar en tiempo real
- [ ] FE-EDU-041: Actualizar barra de progreso
- [ ] FE-EDU-042: Toast notification de XP ganado
- [ ] FE-EDU-043: Modal de curso completado
- [ ] FE-EDU-044: Checkbox para artículos
- [ ] FE-EDU-045: Auto-complete al 90% en videos
- [ ] FE-EDU-046: Botón "Siguiente lección"
- [ ] FE-EDU-047: Integrar con progressStore

**Tests:**
- [ ] TEST-EDU-015: Test completar lección otorga XP
- [ ] TEST-EDU-016: Test desbloquear siguiente lección
- [ ] TEST-EDU-017: Test completar módulo otorga bonus
- [ ] TEST-EDU-018: Test completar curso genera certificado
- [ ] TEST-EDU-019: Test actualizar racha diaria
- [ ] TEST-EDU-020: Test E2E completar lección end-to-end

---

## Dependencias

**Depende de:**
- [ ] US-EDU-003: Iniciar lección - Estado: Pendiente
- [ ] US-EDU-004: Ver video - Estado: Pendiente
- [ ] RF-EDU-003: Sistema de progreso

**Bloquea:**
- [ ] US-EDU-007: Ver progreso
- [ ] US-EDU-008: Obtener certificado

---

## Notas Técnicas

**Endpoint POST /lessons/:id/complete:**
```typescript
// Request
POST /education/lessons/lesson-uuid-123/complete
{
  completedAt: "2025-12-05T15:30:00Z",
  timeSpent: 720, // segundos que pasó en la lección
  finalPosition: 12.15 // para videos
}

// Response
{
  success: true,
  lesson: {
    id: "lesson-uuid-123",
    isCompleted: true,
    completedAt: "2025-12-05T15:30:00Z"
  },
  rewards: {
    xpEarned: 10,
    bonusXP: 5, // Si es primera del día
    totalXP: 15,
    newLevel: null, // Si subió de nivel, info del nuevo nivel
    badges: [] // Nuevos badges ganados
  },
  progress: {
    course: {
      progressPercent: 50,
      lessonsCompleted: 12,
      totalLessons: 23
    },
    module: {
      isCompleted: false,
      lessonsCompleted: 2,
      totalLessons: 4
    }
  },
  nextLesson: {
    id: "lesson-uuid-124",
    title: "Cómo dibujar Fibonacci",
    slug: "como-dibujar-fibonacci",
    isUnlocked: true
  },
  streak: {
    current: 6,
    isNewDay: true
  },
  courseCompleted: false
}
```

**Reglas de XP:**
- Lección de video: 10 XP
- Lección de artículo: 15 XP
- Completar módulo: +50 XP
- Completar curso: +200 XP
- Primera lección del día: +5 XP
- Aprobar quiz primera vez: +30 XP (ver US-EDU-006)

**Lógica de completitud:**
```javascript
// Video: 90% de duración
isVideoComplete = currentTime >= (duration * 0.9);

// Artículo: Manual con checkbox
// Quiz: Aprobar con score >= passingScore
```

**Entidades/Tablas:**
- `education.user_lesson_progress` (completed_at)
- `gamification.user_xp_transactions`
- `gamification.user_stats` (current_streak, total_xp, level)

---

## Definition of Ready (DoR)

- [x] Historia claramente escrita
- [x] Criterios de aceptación definidos
- [x] Story points estimados
- [x] Dependencias identificadas
- [x] Sin bloqueadores
- [x] Diseño/mockup disponible
- [x] API spec disponible

## Definition of Done (DoD)

- [ ] Código implementado según criterios
- [ ] Tests unitarios escritos y pasando
- [ ] Tests de integración pasando
- [ ] Code review aprobado
- [ ] Documentación actualizada
- [ ] QA aprobado
- [ ] Desplegado en ambiente de pruebas

---

## Historial de Cambios

| Fecha | Cambio | Autor |
|-------|--------|-------|
| 2025-12-05 | Creación | Requirements-Analyst |

---

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