Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
335 lines
9.3 KiB
Markdown
335 lines
9.3 KiB
Markdown
---
|
|
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
|