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>
370 lines
12 KiB
Markdown
370 lines
12 KiB
Markdown
---
|
|
id: "US-EDU-004"
|
|
title: "Ver Video de 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-004: Ver Video de Lección
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | US-EDU-004 |
|
|
| **É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 inscrito viendo una lección de video,
|
|
**quiero** reproducir el video con controles completos y funcionalidades avanzadas,
|
|
**para** consumir el contenido educativo de manera cómoda y eficiente.
|
|
|
|
## Descripción Detallada
|
|
|
|
El usuario debe poder reproducir videos educativos con un reproductor profesional que incluya controles estándar (play/pause, volumen, pantalla completa), funcionalidades avanzadas (velocidad de reproducción, subtítulos, picture-in-picture), navegación temporal, y auto-guardado de progreso. El sistema debe recordar la posición de reproducción y permitir saltos rápidos.
|
|
|
|
## Mockups/Wireframes
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Lección 2.1: Niveles principales de Fibonacci │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ │ │
|
|
│ │ │ │
|
|
│ │ [VIDEO REPRODUCIÉNDOSE] │ │
|
|
│ │ │ │
|
|
│ │ Carlos explicando │ │
|
|
│ │ niveles de Fibonacci │ │
|
|
│ │ │ │
|
|
│ │ │ │
|
|
│ │ ━━━━━━━━━━●━━━━━━━━━━━━━━━━━━━━━━━━━━ 05:30 / 12:15 │ │
|
|
│ │ ⏮ ⏸ ⏭ 🔊──────● ⚙ 1.25x [CC] [PIP] ⛶ │ │
|
|
│ │ │ │
|
|
│ │ Capítulos: │ │
|
|
│ │ • 0:00 - Introducción │ │
|
|
│ │ • 2:15 - Nivel 38.2% │ │
|
|
│ │ • 5:30 - Nivel 50% ← Actual │ │
|
|
│ │ • 8:45 - Nivel 61.8% │ │
|
|
│ │ • 11:00 - Conclusión │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ CONTROLES: │
|
|
│ • Espacio: Play/Pause │
|
|
│ • →: Adelantar 10s │
|
|
│ • ←: Retroceder 10s │
|
|
│ • F: Pantalla completa │
|
|
│ • M: Silenciar │
|
|
│ • 0-9: Saltar a ese % del video │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
[MENÚ DE VELOCIDAD]
|
|
┌──────────────┐
|
|
│ Velocidad │
|
|
│ ○ 0.5x │
|
|
│ ○ 0.75x │
|
|
│ ● 1x │ ← Seleccionado
|
|
│ ○ 1.25x │
|
|
│ ○ 1.5x │
|
|
│ ○ 2x │
|
|
└──────────────┘
|
|
|
|
[MENÚ DE CALIDAD]
|
|
┌──────────────┐
|
|
│ Calidad │
|
|
│ ● Auto │ ← Adaptativa
|
|
│ ○ 1080p │
|
|
│ ○ 720p │
|
|
│ ○ 480p │
|
|
│ ○ 360p │
|
|
└──────────────┘
|
|
|
|
[SUBTÍTULOS]
|
|
┌──────────────┐
|
|
│ Subtítulos │
|
|
│ ● Desactivado│
|
|
│ ○ Español │
|
|
│ ○ English │
|
|
└──────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Criterios de Aceptación
|
|
|
|
**Escenario 1: Reproducir video**
|
|
```gherkin
|
|
DADO que el usuario accedió a una lección de video
|
|
CUANDO el reproductor carga
|
|
ENTONCES se muestra el video con controles
|
|
Y el video está pausado inicialmente
|
|
Y se muestra duración total
|
|
Y se carga en la última posición guardada (si existe)
|
|
Y se muestra toast "Continuando desde X:XX"
|
|
```
|
|
|
|
**Escenario 2: Controles básicos funcionan**
|
|
```gherkin
|
|
DADO que el video está cargado
|
|
CUANDO el usuario hace click en Play
|
|
ENTONCES el video se reproduce
|
|
Y el botón cambia a Pause ⏸
|
|
Y la barra de progreso avanza
|
|
Y el tiempo actual se actualiza cada segundo
|
|
```
|
|
|
|
**Escenario 3: Cambiar velocidad de reproducción**
|
|
```gherkin
|
|
DADO que el video se está reproduciendo a 1x
|
|
CUANDO el usuario selecciona velocidad 1.5x
|
|
ENTONCES el video se reproduce 50% más rápido
|
|
Y el audio se ajusta automáticamente (sin distorsión)
|
|
Y se muestra indicador "1.5x" en el reproductor
|
|
Y la configuración se guarda para próximos videos
|
|
```
|
|
|
|
**Escenario 4: Activar subtítulos**
|
|
```gherkin
|
|
DADO que el video tiene subtítulos en español
|
|
CUANDO el usuario activa subtítulos
|
|
ENTONCES aparecen subtítulos sincronizados con el audio
|
|
Y se pueden personalizar tamaño y posición
|
|
Y la preferencia se guarda para próximos videos
|
|
```
|
|
|
|
**Escenario 5: Saltar a posición específica**
|
|
```gherkin
|
|
DADO que el video se está reproduciendo
|
|
CUANDO el usuario hace click en la barra de progreso
|
|
ENTONCES el video salta a esa posición
|
|
Y se muestra preview al hacer hover sobre la barra
|
|
Y la nueva posición se guarda automáticamente
|
|
```
|
|
|
|
**Escenario 6: Auto-guardado de progreso**
|
|
```gherkin
|
|
DADO que el usuario está viendo un video
|
|
Y el video alcanza la posición 7:30
|
|
CUANDO pasan 10 segundos
|
|
ENTONCES se guarda la posición en backend
|
|
Y si el usuario cierra la página y vuelve
|
|
ENTONCES el video se carga en 7:30
|
|
```
|
|
|
|
**Escenario 7: Atajos de teclado**
|
|
```gherkin
|
|
DADO que el usuario está viendo un video
|
|
CUANDO presiona la tecla →
|
|
ENTONCES el video avanza 10 segundos
|
|
Y se muestra indicador "+10s"
|
|
|
|
CUANDO presiona la tecla ←
|
|
ENTONCES el video retrocede 10 segundos
|
|
Y se muestra indicador "-10s"
|
|
|
|
CUANDO presiona Espacio
|
|
ENTONCES el video pausa/reanuda
|
|
|
|
CUANDO presiona F
|
|
ENTONCES entra/sale de pantalla completa
|
|
```
|
|
|
|
**Escenario 8: Picture-in-Picture**
|
|
```gherkin
|
|
DADO que el video se está reproduciendo
|
|
CUANDO el usuario hace click en botón PIP
|
|
ENTONCES el video se minimiza en una ventana flotante
|
|
Y puede navegar a otras páginas mientras ve el video
|
|
Y los controles básicos están disponibles en PIP
|
|
Y al cerrar PIP, vuelve al reproductor normal
|
|
```
|
|
|
|
**Escenario 9: Capítulos del video**
|
|
```gherkin
|
|
DADO que el video tiene capítulos definidos
|
|
CUANDO el usuario hace click en un capítulo
|
|
ENTONCES el video salta a ese timestamp
|
|
Y se muestra marcador de capítulo en la barra de progreso
|
|
Y al hacer hover en la barra, muestra nombre del capítulo
|
|
```
|
|
|
|
**Escenario 10: Completar video automáticamente**
|
|
```gherkin
|
|
DADO que el usuario está viendo un video
|
|
CUANDO el video alcanza el 90% de reproducción
|
|
ENTONCES la lección se marca automáticamente como completada
|
|
Y se muestra toast "Lección completada +10 XP"
|
|
Y se actualiza el progreso del curso
|
|
Y se desbloquea siguiente lección (si es secuencial)
|
|
```
|
|
|
|
## Criterios Adicionales
|
|
|
|
- [ ] Calidad adaptativa según ancho de banda
|
|
- [ ] Buffer progresivo para evitar cortes
|
|
- [ ] Indicador de buffering cuando carga
|
|
- [ ] Manejo de errores (video no disponible, error de red)
|
|
- [ ] Analytics: pausas, rewinds, abandonos
|
|
- [ ] Thumbnail preview al hover sobre barra de progreso
|
|
- [ ] Continuar reproduciendo al cambiar de pestaña (background play)
|
|
|
|
---
|
|
|
|
## Tareas Técnicas
|
|
|
|
**Database:**
|
|
- [ ] DB-EDU-010: Tabla video_chapters (video_id, time, title)
|
|
- [ ] DB-EDU-011: Actualizar user_lesson_progress.last_position cada 10s
|
|
|
|
**Backend:**
|
|
- [ ] BE-EDU-022: Endpoint POST /education/lessons/:id/progress
|
|
- [ ] BE-EDU-023: Endpoint GET /education/videos/:id/chapters
|
|
- [ ] BE-EDU-024: Generar signed URLs para Vimeo/S3
|
|
- [ ] BE-EDU-025: Implementar validación de acceso a video
|
|
- [ ] BE-EDU-026: Webhook de Vimeo para confirmar encoding completado
|
|
- [ ] BE-EDU-027: Rate limiting en auto-save (máx cada 5s)
|
|
|
|
**Frontend:**
|
|
- [ ] FE-EDU-026: Implementar VideoPlayer.tsx con React Player
|
|
- [ ] FE-EDU-027: Custom controls overlay
|
|
- [ ] FE-EDU-028: Speed control menu
|
|
- [ ] FE-EDU-029: Subtitles toggle y customización
|
|
- [ ] FE-EDU-030: Keyboard shortcuts (arrow keys, space, f, m)
|
|
- [ ] FE-EDU-031: Picture-in-Picture implementation
|
|
- [ ] FE-EDU-032: Progress bar con preview thumbnail
|
|
- [ ] FE-EDU-033: Chapters navigation
|
|
- [ ] FE-EDU-034: Auto-save de posición cada 10s
|
|
- [ ] FE-EDU-035: Restore position on load
|
|
- [ ] FE-EDU-036: Analytics tracking (play, pause, seek, complete)
|
|
- [ ] FE-EDU-037: Loading spinner y error states
|
|
|
|
**Tests:**
|
|
- [ ] TEST-EDU-011: Test auto-save de progreso
|
|
- [ ] TEST-EDU-012: Test restaurar posición guardada
|
|
- [ ] TEST-EDU-013: Test marcar completado al 90%
|
|
- [ ] TEST-EDU-014: Test E2E reproducir video completo
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
**Depende de:**
|
|
- [ ] US-EDU-003: Iniciar lección - Estado: Pendiente
|
|
- [ ] Video CDN: Vimeo Pro o AWS S3 + CloudFront
|
|
|
|
**Bloquea:**
|
|
- [ ] US-EDU-005: Completar lección
|
|
- [ ] US-EDU-007: Ver progreso
|
|
|
|
---
|
|
|
|
## Notas Técnicas
|
|
|
|
**CDN de Videos:**
|
|
- Opción 1: Vimeo Pro (recomendado para MVP)
|
|
- API robusta
|
|
- Encoding automático
|
|
- Streaming adaptativo HLS
|
|
- Subtítulos integrados
|
|
- Analytics incluido
|
|
- Opción 2: AWS S3 + CloudFront + MediaConvert
|
|
- Más control
|
|
- Más setup inicial
|
|
- Costos variables
|
|
|
|
**Librerías recomendadas:**
|
|
- React Player: Wrapper para múltiples providers
|
|
- Video.js: Player HTML5 completo y customizable
|
|
- Plyr: Alternativa moderna y ligera
|
|
|
|
**Auto-save strategy:**
|
|
```javascript
|
|
// Guardar posición cada 10s mientras reproduce
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
if (isPlaying) {
|
|
saveProgress(currentTime);
|
|
}
|
|
}, 10000);
|
|
return () => clearInterval(interval);
|
|
}, [isPlaying, currentTime]);
|
|
|
|
// Guardar al pausar
|
|
const handlePause = () => {
|
|
saveProgress(currentTime);
|
|
};
|
|
|
|
// Guardar antes de salir
|
|
useEffect(() => {
|
|
return () => {
|
|
saveProgress(currentTime);
|
|
};
|
|
}, []);
|
|
```
|
|
|
|
**Analytics events:**
|
|
- `video_started`: Primera reproducción
|
|
- `video_played`: Cada vez que presiona play
|
|
- `video_paused`: Cada pausa
|
|
- `video_seeked`: Salto manual
|
|
- `video_completed`: Alcanza 90%
|
|
- `video_speed_changed`: Cambia velocidad
|
|
- `video_quality_changed`: Cambia calidad
|
|
|
|
**Entidades/Tablas:**
|
|
- `education.lessons` (campo videoUrl)
|
|
- `education.video_chapters`
|
|
- `education.user_lesson_progress` (campo last_position)
|
|
|
|
---
|
|
|
|
## 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
|