--- id: "RF-EDU-002" title: "Sistema de Lecciones" 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-002: Sistema de Lecciones **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 reproductor multimedia completo que permita a los usuarios consumir contenido educativo en múltiples formatos (video, texto, código interactivo, quizzes) con controles de navegación, seguimiento de progreso y experiencia de aprendizaje optimizada. --- ## Requisitos Funcionales ### RF-EDU-002.1: Tipos de Lecciones El sistema debe soportar: | Tipo | Descripción | Características | |------|-------------|-----------------| | **Video** | Contenido en video | Reproductor, subtítulos, velocidad | | **Artículo** | Contenido de texto | Markdown, imágenes, código | | **Quiz** | Evaluación interactiva | Preguntas, feedback inmediato | | **Código** | Ejercicio práctico | Editor, ejecución, validación | | **Recursos** | Descargables | PDFs, hojas de cálculo, código | ### RF-EDU-002.2: Reproductor de Video El sistema debe: - Reproducir videos desde CDN (Vimeo/YouTube/S3) - Controles: play/pause, volumen, pantalla completa - Velocidades: 0.5x, 0.75x, 1x, 1.25x, 1.5x, 2x - Subtítulos en español e inglés (opcional) - Recordar posición de reproducción - Saltar 10s adelante/atrás con teclas de flecha - Atajos de teclado (espacio=play/pause, f=fullscreen, m=mute) - Barra de progreso con preview al hover - Marcadores de secciones importantes - Calidad adaptativa según ancho de banda ### RF-EDU-002.3: Lecciones de Artículo El sistema debe: - Renderizar Markdown con syntax highlighting - Soportar: headers, listas, tablas, imágenes, videos embebidos - Mostrar tabla de contenidos (TOC) para artículos largos - Estimación de tiempo de lectura - Resaltar código con Prism.js o similar - Copiar código con un click - Modo oscuro/claro para lectura - Marcar artículo como completado con checkbox al final ### RF-EDU-002.4: Navegación entre Lecciones El sistema debe: - Mostrar sidebar con estructura del curso (módulos > lecciones) - Indicar lección actual destacada - Mostrar checkmarks en lecciones completadas - Mostrar progreso en módulos (X/Y lecciones) - Botones "Anterior" y "Siguiente" lección - Bloquear lecciones futuras si curso es secuencial - Permitir saltar libremente si curso es no-secuencial - Collapse/expand de módulos en sidebar ### RF-EDU-002.5: Recursos Descargables El sistema debe: - Listar recursos disponibles para la lección - Mostrar: nombre, tipo de archivo, tamaño - Permitir descargar con un click - Trackear descargas para analytics - Validar acceso antes de descargar - Soportar: PDF, XLSX, CSV, ZIP, código fuente ### RF-EDU-002.6: Notas del Usuario El sistema debe: - Permitir tomar notas durante lección - Editor de texto enriquecido (bold, italic, listas) - Guardar automáticamente (debounce 2s) - Timestamp de la nota (para videos) - Listar todas las notas del curso - Buscar en notas - Exportar notas a PDF/Markdown ### RF-EDU-002.7: Marcadores y Favoritos El sistema debe: - Permitir marcar timestamp en videos - Agregar comentario al marcador - Listar marcadores en sidebar - Saltar a marcador con click - Exportar marcadores --- ## Datos de Entrada | Campo | Tipo | Descripción | |-------|------|-------------| | courseId | string | UUID del curso | | lessonId | string | UUID de la lección | | timestamp | number | Posición en video (segundos) | --- ## Datos de Salida ```typescript interface Lesson { id: string; moduleId: string; title: string; slug: string; description: string; type: 'video' | 'article' | 'quiz' | 'code' | 'resource'; order: number; duration: number; // minutos isFree: boolean; isCompleted: boolean; // Video específico videoUrl?: string; videoProvider?: 'vimeo' | 'youtube' | 's3'; videoId?: string; subtitles?: { language: string; url: string; }[]; // Artículo específico content?: string; // Markdown readingTime?: number; // minutos // Quiz específico quizId?: string; questionsCount?: number; passingScore?: number; // Recursos resources?: { id: string; name: string; type: string; url: string; size: number; }[]; // Progreso del usuario userProgress?: { startedAt: string; completedAt?: string; lastPosition: number; // Para videos timeSpent: number; // segundos notes?: string; }; } interface LessonNavigation { currentLesson: Lesson; previousLesson?: { id: string; title: string; slug: string; }; nextLesson?: { id: string; title: string; slug: string; }; module: { id: string; title: string; lessons: { id: string; title: string; isCompleted: boolean; isLocked: boolean; }[]; }; } ``` --- ## Reglas de Negocio 1. **Orden secuencial:** Si curso requiere orden, solo lección actual y anteriores están desbloqueadas 2. **Completar lección:** Video: ver 90%, Artículo: scroll al final, Quiz: aprobar 3. **Acceso Premium:** Lecciones no-free requieren suscripción activa 4. **Auto-save progreso:** Guardar posición cada 10 segundos 5. **Marcado manual:** Usuario puede marcar completado manualmente 6. **Recursos solo para enrollados:** No se pueden descargar recursos sin estar inscrito 7. **Notas privadas:** Solo visibles para el usuario que las creó 8. **Tiempo mínimo:** Video debe reproducirse al menos 30s para contar progreso --- ## Criterios de Aceptación ```gherkin Escenario: Usuario visualiza lección de video DADO que el usuario está inscrito en curso Y está en /education/courses/:slug/lessons/:lessonSlug CUANDO la lección es tipo video ENTONCES se muestra reproductor de video Y se muestran controles de reproducción Y se muestra sidebar con estructura del curso Y se carga la posición guardada anteriormente Escenario: Usuario completa lección de video DADO que el usuario está viendo un video CUANDO el video alcanza el 90% de reproducción ENTONCES la lección se marca como completada Y se muestra checkmark en sidebar Y se actualiza barra de progreso del curso Y se habilita siguiente lección si estaba bloqueada Escenario: Usuario lee artículo DADO que la lección es tipo artículo CUANDO el usuario accede a la lección ENTONCES se muestra contenido renderizado desde Markdown Y se muestra tabla de contenidos si artículo >500 palabras Y se muestra tiempo estimado de lectura Y se muestra checkbox "Marcar como completado" Escenario: Usuario toma notas DADO que el usuario está en una lección CUANDO hace click en pestaña "Mis notas" ENTONCES se muestra editor de texto Y puede escribir notas Y las notas se guardan automáticamente Y para videos se guarda timestamp actual Escenario: Navegación entre lecciones DADO que el usuario completó una lección CUANDO hace click en "Siguiente lección" ENTONCES navega a la siguiente lección Y se carga el contenido correspondiente Y se actualiza sidebar destacando nueva lección Escenario: Descargar recursos DADO que la lección tiene recursos descargables CUANDO el usuario hace click en "Descargar" ENTONCES se descarga el archivo Y se registra la descarga en analytics ``` --- ## Dependencias - Video CDN (Vimeo/YouTube/AWS S3 + CloudFront) - PostgreSQL para metadata de lecciones - Redis para caché de progreso - S3 para archivos descargables --- ## Notas Técnicas - Usar React Player o Video.js para reproductor - Implementar PIP (Picture-in-Picture) para videos - Considerar HLS para streaming adaptativo - Implementar lazy loading de módulos en sidebar - Guardar progreso en IndexedDB local como backup - Usar Web Workers para procesamiento de Markdown pesado - Implementar analytics de engagement (pausas, rewinds, abandono) --- ## Referencias - Schema: `/backend/src/database/schemas/education.sql` - API: `/backend/src/modules/courses/lessons.routes.ts` - Frontend: `/frontend/src/pages/LessonPlayer.tsx` --- ## Tareas Técnicas **Database:** - [ ] Verificar schema education.lessons - [ ] Tabla user_lesson_progress con campos: started_at, completed_at, last_position - [ ] Tabla user_notes con FK a lesson - [ ] Tabla user_bookmarks para marcadores **Backend:** - [ ] Endpoint GET /education/courses/:id/lessons/:lessonId - [ ] Endpoint POST /education/lessons/:id/progress (guardar posición) - [ ] Endpoint POST /education/lessons/:id/complete - [ ] Endpoint GET/POST/PUT/DELETE /education/lessons/:id/notes - [ ] Endpoint GET /education/lessons/:id/resources/:resourceId/download - [ ] Implementar signed URLs para videos privados - [ ] Rate limiting en download de recursos **Frontend:** - [ ] Crear LessonPlayerPage.tsx - [ ] Crear componente VideoPlayer.tsx - [ ] Crear componente ArticleViewer.tsx - [ ] Crear componente LessonSidebar.tsx - [ ] Crear componente NotesEditor.tsx - [ ] Crear componente ResourcesList.tsx - [ ] Implementar lessonStore para progreso - [ ] Auto-save de posición cada 10s - [ ] Atajos de teclado para navegación **Tests:** - [ ] Test unitario LessonService - [ ] Test integración actualización de progreso - [ ] Test E2E completar lección y desbloquear siguiente --- **Creado por:** Requirements-Analyst **Fecha:** 2025-12-05 **Última actualización:** 2025-12-05