---
id: "US-EDU-006"
title: "Realizar Quiz"
type: "User Story"
status: "Done"
priority: "Alta"
epic: "OQI-002"
story_points: 5
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# US-EDU-006: Realizar Quiz

## Metadata

| Campo | Valor |
|-------|-------|
| **ID** | US-EDU-006 |
| **Épica** | OQI-002 - Módulo Educativo |
| **Módulo** | education |
| **Prioridad** | P1 |
| **Story Points** | 5 |
| **Sprint** | Sprint 4 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |

---

## Historia de Usuario

**Como** usuario inscrito en un curso,
**quiero** realizar quizzes interactivos al final de cada módulo,
**para** validar mi conocimiento, recibir feedback y aprobar las evaluaciones requeridas.

## Descripción Detallada

El usuario debe poder acceder a quizzes que evalúan el conocimiento adquirido en las lecciones. Debe poder responder preguntas de múltiple opción, navegar entre preguntas, revisar sus respuestas antes de enviar, recibir calificación inmediata, ver explicaciones de respuestas correctas/incorrectas, y reintentar si no aprobó (según intentos permitidos).

## Mockups/Wireframes

```
[PANTALLA DE INTRODUCCIÓN AL QUIZ]
┌─────────────────────────────────────────────────────────────────┐
│  ← Volver al curso                                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│                    📝 QUIZ: FUNDAMENTOS DE FIBONACCI             │
│                                                                  │
│  Módulo 1: Introducción a Fibonacci                             │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │  📊 Información del Quiz                                    │ │
│  │                                                             │ │
│  │  Preguntas: 10                                              │ │
│  │  Tiempo límite: 15 minutos                                  │ │
│  │  Puntuación para aprobar: 70%                               │ │
│  │  Intentos disponibles: 2 de 3                               │ │
│  │  Tipo: Evaluación                                           │ │
│  │                                                             │ │
│  │  ✓ Las preguntas están en orden aleatorio                  │ │
│  │  ✓ Verás tus respuestas al finalizar                       │ │
│  │  ✓ Puedes navegar libremente entre preguntas               │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│              [🚀 Comenzar Quiz]                                 │
│                                                                  │
│  Intentos anteriores:                                           │
│  • Intento 1: 65% - Reprobado (hace 2 días)                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[PANTALLA DE PREGUNTA]
┌─────────────────────────────────────────────────────────────────┐
│  Quiz: Fundamentos de Fibonacci           ⏱ 12:45 restantes    │
│  Pregunta 3 de 10                     ████████░░░░░░ 30%        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ¿Cuál es el nivel de retroceso de Fibonacci más utilizado?    │
│                                                                  │
│  ○ 23.6%                                                        │
│  ○ 38.2%                                                        │
│  ● 61.8%  ← Seleccionado                                        │
│  ○ 78.6%                                                        │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ [← Anterior]           [🚩 Marcar]          [Siguiente →]  │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  NAVEGADOR:                                                     │
│  [●1] [●2] [●3] [○4] [○5] [○6] [○7] [○8] [🚩9] [○10]         │
│   ↑    ↑    ↑   Sin  Sin  Sin  Sin  Sin  Marca Sin             │
│  Resp Resp Actual resp resp resp resp resp  da   resp          │
│                                                                  │
│                         [Finalizar Quiz]                        │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[CONFIRMACIÓN DE ENVÍO]
┌─────────────────────────────────────────────────────────────────┐
│                   ⚠ ¿Estás seguro?                              │
│                                                                  │
│  Estás a punto de enviar tu quiz.                               │
│                                                                  │
│  Resumen:                                                        │
│  • Preguntas respondidas: 9 de 10                               │
│  • Preguntas sin responder: 1                                   │
│  • Preguntas marcadas para revisar: 1                           │
│                                                                  │
│  ⚠ Una vez enviado, no podrás cambiar tus respuestas.          │
│                                                                  │
│  [Cancelar]                            [Enviar Quiz]            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[RESULTADO - APROBADO]
┌─────────────────────────────────────────────────────────────────┐
│                        ✨ ✨ ✨                                  │
│                                                                  │
│                   ✅ ¡QUIZ APROBADO!                            │
│                                                                  │
│                      Puntuación: 85%                            │
│                     Preguntas correctas: 8.5/10                 │
│                                                                  │
│                     +30 XP ganados                              │
│                                                                  │
│  🎯 Desglose:                                                   │
│  • Preguntas correctas: 8                                       │
│  • Preguntas incorrectas: 2                                     │
│  • Puntuación requerida: 70%                                    │
│                                                                  │
│  Tiempo invertido: 10:32 de 15:00                              │
│  Intento: 2 de 3                                                │
│                                                                  │
│  [Ver respuestas y explicaciones]                               │
│  [Continuar al siguiente contenido →]                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

---

## Criterios de Aceptación

**Escenario 1: Ver introducción del quiz**
```gherkin
DADO que el usuario está inscrito en el curso
CUANDO accede a una lección tipo quiz
ENTONCES se muestra pantalla de introducción
Y se muestra: número de preguntas, tiempo límite, puntuación para aprobar
Y se muestran intentos disponibles
Y se muestra historial de intentos anteriores (si existen)
Y se muestra botón "Comenzar Quiz"
```

**Escenario 2: Comenzar quiz**
```gherkin
DADO que el usuario está en la introducción del quiz
CUANDO hace click en "Comenzar Quiz"
ENTONCES se registra el inicio del intento en backend
Y se navega a la primera pregunta
Y se inicia el timer countdown
Y se carga el navegador de preguntas
Y se registra timestamp de inicio
```

**Escenario 3: Responder pregunta de opción múltiple**
```gherkin
DADO que el usuario está en una pregunta
CUANDO selecciona una opción
ENTONCES la opción se marca visualmente
Y la pregunta se marca como "respondida" en el navegador
Y puede cambiar su respuesta antes de enviar
Y la respuesta se guarda temporalmente en el estado
```

**Escenario 4: Navegar entre preguntas**
```gherkin
DADO que el usuario respondió la pregunta 3
CUANDO hace click en "Siguiente"
ENTONCES navega a la pregunta 4
Y su respuesta anterior se mantiene guardada
Y puede volver a pregunta 3 con "Anterior"
Y puede saltar a cualquier pregunta desde el navegador
```

**Escenario 5: Marcar pregunta para revisión**
```gherkin
DADO que el usuario está en una pregunta
Y tiene dudas sobre su respuesta
CUANDO hace click en "🚩 Marcar"
ENTONCES la pregunta se marca con bandera en el navegador
Y puede volver fácilmente a revisarla antes de enviar
Y puede desmarcarla con otro click
```

**Escenario 6: Quiz con tiempo límite expira**
```gherkin
DADO que el quiz tiene límite de 15 minutos
Y el usuario está respondiendo
CUANDO el timer llega a 0:00
ENTONCES el quiz se envía automáticamente
Y se muestra "Tiempo agotado"
Y se califica con las respuestas hasta el momento
Y preguntas sin responder cuentan como incorrectas
```

**Escenario 7: Enviar quiz manualmente**
```gherkin
DADO que el usuario respondió todas las preguntas
CUANDO hace click en "Finalizar Quiz"
ENTONCES se muestra modal de confirmación
Y muestra resumen: respondidas, sin responder, marcadas
Y al confirmar, se envía al backend
Y se calcula la puntuación
Y se muestra pantalla de resultados
```

**Escenario 8: Aprobar quiz**
```gherkin
DADO que el usuario envió el quiz
Y obtuvo 85% de puntuación
Y la puntuación mínima es 70%
ENTONCES se muestra "¡QUIZ APROBADO!"
Y se otorgan +30 XP
Y se marca la lección quiz como completada
Y se desbloquea siguiente contenido
Y se actualiza progreso del curso
```

**Escenario 9: Reprobar quiz con intentos disponibles**
```gherkin
DADO que el usuario obtuvo 65% (no aprobó)
Y quedan 2 intentos disponibles
ENTONCES se muestra "Quiz Reprobado"
Y se muestra puntuación obtenida
Y se muestra "Intentos restantes: 2"
Y se muestra botón "Reintentar"
Y NO se desbloquea siguiente contenido
Y NO se otorga XP
```

**Escenario 10: Reprobar quiz sin intentos**
```gherkin
DADO que el usuario agotó todos los intentos
Y no aprobó el quiz
ENTONCES se muestra mensaje "Sin intentos disponibles"
Y se sugiere "Repasa las lecciones y contacta a soporte"
Y el siguiente contenido permanece bloqueado
Y se registra el bloqueo para seguimiento
```

**Escenario 11: Ver explicaciones de respuestas**
```gherkin
DADO que el usuario completó el quiz
CUANDO hace click en "Ver respuestas y explicaciones"
ENTONCES se muestran todas las preguntas
Y se destacan respuestas correctas en verde
Y se destacan respuestas incorrectas en rojo
Y se muestra la respuesta correcta
Y se muestra explicación detallada de cada respuesta
Y se sugieren lecciones relacionadas para repasar
```

**Escenario 12: Reintentar quiz**
```gherkin
DADO que el usuario reprobó el quiz
Y tiene intentos disponibles
CUANDO hace click en "Reintentar"
ENTONCES se inicia un nuevo intento
Y las preguntas pueden estar en diferente orden
Y las opciones pueden estar en diferente orden
Y sus respuestas anteriores NO están pre-seleccionadas
Y el contador de intentos se decrementa
```

## Criterios Adicionales

- [ ] Auto-save de respuestas cada 30s (protección contra pérdida)
- [ ] Advertencia antes de salir de la página sin enviar
- [ ] Modo revisión: ver quiz aprobado sin poder cambiar respuestas
- [ ] Estadísticas del quiz: % de aprobación, tiempo promedio
- [ ] Preguntas con imágenes embebidas
- [ ] Tipo de pregunta: multiple select (varias correctas)
- [ ] Puntuación parcial en multiple select

---

## Tareas Técnicas

**Database:**
- [ ] DB-EDU-015: Tabla education.quizzes
- [ ] DB-EDU-016: Tabla education.questions (FK a quiz)
- [ ] DB-EDU-017: Tabla education.question_options
- [ ] DB-EDU-018: Tabla education.quiz_attempts
- [ ] DB-EDU-019: Tabla education.quiz_answers (respuestas del usuario)

**Backend:**
- [ ] BE-EDU-039: Endpoint GET /education/quizzes/:id
- [ ] BE-EDU-040: Endpoint POST /education/quizzes/:id/start
- [ ] BE-EDU-041: Endpoint POST /education/quizzes/:id/submit
- [ ] BE-EDU-042: Endpoint GET /education/quizzes/:id/attempts
- [ ] BE-EDU-043: Endpoint GET /education/quizzes/:id/results/:attemptId
- [ ] BE-EDU-044: Implementar QuizService.gradeAttempt()
- [ ] BE-EDU-045: Implementar shuffle de preguntas y opciones
- [ ] BE-EDU-046: Validar intentos disponibles
- [ ] BE-EDU-047: Implementar timer y auto-submit
- [ ] BE-EDU-048: NO devolver respuestas correctas en GET (seguridad)

**Frontend:**
- [ ] FE-EDU-048: Crear QuizIntroPage.tsx
- [ ] FE-EDU-049: Crear QuizPlayerPage.tsx
- [ ] FE-EDU-050: Crear componente QuestionRenderer.tsx
- [ ] FE-EDU-051: Crear componente QuizNavigator.tsx (minimap)
- [ ] FE-EDU-052: Crear componente QuizTimer.tsx
- [ ] FE-EDU-053: Crear QuizResultsPage.tsx
- [ ] FE-EDU-054: Crear componente AnswerExplanation.tsx
- [ ] FE-EDU-055: Modal de confirmación de envío
- [ ] FE-EDU-056: Auto-save de respuestas cada 30s
- [ ] FE-EDU-057: Advertencia antes de salir (window.onbeforeunload)
- [ ] FE-EDU-058: Implementar quizStore (Zustand)
- [ ] FE-EDU-059: Animación de celebración al aprobar

**Tests:**
- [ ] TEST-EDU-021: Test calificación de quiz
- [ ] TEST-EDU-022: Test aprobar quiz otorga XP
- [ ] TEST-EDU-023: Test auto-submit cuando expira tiempo
- [ ] TEST-EDU-024: Test límite de intentos
- [ ] TEST-EDU-025: Test E2E realizar quiz completo

---

## Dependencias

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

**Bloquea:**
- [ ] US-EDU-005: Completar lección
- [ ] US-EDU-007: Ver progreso

---

## Notas Técnicas

**Endpoint GET /quizzes/:id (SIN respuestas correctas):**
```typescript
{
  quiz: {
    id: "quiz-1",
    title: "Fundamentos de Fibonacci",
    description: "Evalúa tu conocimiento...",
    timeLimit: 15, // minutos
    passingScore: 70, // 0-100
    maxAttempts: 3,
    questionCount: 10,
    totalPoints: 10,
    shuffleQuestions: true,
    shuffleOptions: true,
    mode: "assessment",

    questions: [
      {
        id: "q-1",
        question: "¿Cuál es el nivel más utilizado?",
        type: "multiple_choice",
        points: 1,
        options: [
          { id: "opt-1", text: "23.6%" },
          { id: "opt-2", text: "38.2%" },
          { id: "opt-3", text: "61.8%" },
          { id: "opt-4", text: "78.6%" }
        ]
        // NO incluir isCorrect en GET
      }
    ],

    userAttempts: [
      {
        attemptNumber: 1,
        score: 65,
        passed: false,
        submittedAt: "2025-12-03T10:30:00Z"
      }
    ],
    attemptsRemaining: 2
  }
}
```

**Endpoint POST /quizzes/:id/submit:**
```typescript
// Request
{
  answers: {
    "q-1": "opt-3",
    "q-2": "opt-1",
    "q-3": ["opt-2", "opt-4"], // Multiple select
    // ...
  },
  timeSpent: 632 // segundos
}

// Response
{
  attempt: {
    id: "attempt-uuid",
    quizId: "quiz-1",
    attemptNumber: 2,
    score: 85,
    passed: true,
    pointsEarned: 8.5,
    totalPoints: 10,
    submittedAt: "2025-12-05T16:45:00Z"
  },
  rewards: {
    xpEarned: 30,
    bonusXP: 20, // Si es 100%
    totalXP: 50
  },
  answers: [
    {
      questionId: "q-1",
      userAnswer: "opt-3",
      correctAnswer: "opt-3",
      isCorrect: true,
      pointsEarned: 1,
      explanation: "61.8% es el nivel dorado..."
    }
    // ...
  ],
  attemptsRemaining: 1,
  canRetake: true
}
```

**Reglas de calificación:**
- Multiple choice: 1 punto si es correcta, 0 si no
- Multiple select: puntos parciales (0.5 si acierta 2 de 4)
- True/False: 1 punto si es correcta
- Sin responder: 0 puntos

**Entidades/Tablas:**
- `education.quizzes`
- `education.questions`
- `education.question_options`
- `education.quiz_attempts`
- `education.quiz_answers`

---

## 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
