--- id: "RF-EDU-001" title: "Catalogo de Cursos" 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-001: Catálogo de Cursos **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 catálogo completo de cursos educativos sobre trading e inversiones, con capacidades avanzadas de filtrado, búsqueda y categorización que permitan a los usuarios descubrir contenido relevante según su nivel de experiencia y áreas de interés. --- ## Requisitos Funcionales ### RF-EDU-001.1: Listado de Cursos El sistema debe: - Mostrar todos los cursos activos en formato de tarjetas (cards) - Incluir para cada curso: título, descripción breve, imagen, nivel, duración, módulos, progreso - Mostrar badge de "Nuevo" para cursos publicados en últimos 30 días - Mostrar badge de "En curso" para cursos iniciados por el usuario - Mostrar badge de "Completado" con porcentaje para cursos en progreso - Implementar paginación (12 cursos por página) ### RF-EDU-001.2: Categorías El sistema debe soportar las siguientes categorías: | Categoría | Slug | Descripción | |-----------|------|-------------| | Fundamentos | fundamentals | Conceptos básicos de trading | | Análisis Técnico | technical-analysis | Indicadores y patrones | | Análisis Fundamental | fundamental-analysis | Valoración de activos | | Gestión de Riesgo | risk-management | Money management | | Psicología del Trading | trading-psychology | Control emocional | | Estrategias Avanzadas | advanced-strategies | Sistemas complejos | | Criptomonedas | crypto | Trading de cripto | | IA y Trading | ai-trading | Machine Learning aplicado | ### RF-EDU-001.3: Niveles de Dificultad El sistema debe clasificar cursos en: - **Principiante:** Sin conocimientos previos requeridos - **Intermedio:** Requiere conocimientos básicos - **Avanzado:** Para traders experimentados - **Experto:** Contenido especializado ### RF-EDU-001.4: Filtros El sistema debe permitir filtrar por: - Categoría (múltiple selección) - Nivel de dificultad (múltiple selección) - Duración (rangos: <2h, 2-5h, 5-10h, >10h) - Estado: Nuevos, En curso, Completados, No iniciados - Instructor - Gratuitos vs Premium ### RF-EDU-001.5: Búsqueda El sistema debe: - Implementar barra de búsqueda en tiempo real - Buscar en: título, descripción, tags, nombre de instructor - Mostrar resultados mientras el usuario escribe (debounce 300ms) - Resaltar términos coincidentes en resultados - Mostrar sugerencias de búsqueda basadas en términos populares - Guardar historial de búsquedas del usuario ### RF-EDU-001.6: Ordenamiento El sistema debe permitir ordenar por: - Más recientes - Más populares (por número de estudiantes) - Mejor valorados (rating) - Duración (ascendente/descendente) - Alfabético (A-Z, Z-A) - Progreso del usuario (para cursos iniciados) ### RF-EDU-001.7: Recomendaciones El sistema debe: - Mostrar sección "Recomendado para ti" basado en: - Cursos en progreso del usuario - Nivel de experiencia del perfil - Cursos completados previamente - Categorías de interés - Mostrar sección "Continuar aprendiendo" con cursos incompletos - Mostrar "Cursos relacionados" al ver detalle de curso --- ## Datos de Entrada | Campo | Tipo | Descripción | |-------|------|-------------| | page | number | Número de página (default: 1) | | limit | number | Elementos por página (default: 12, max: 50) | | category | string[] | IDs de categorías a filtrar | | level | string[] | Niveles de dificultad | | search | string | Término de búsqueda | | sortBy | string | Campo de ordenamiento | | sortOrder | asc/desc | Dirección del ordenamiento | --- ## Datos de Salida ```typescript interface Course { id: string; title: string; slug: string; description: string; shortDescription: string; thumbnail: string; category: { id: string; name: string; slug: string; icon: string; }; level: 'beginner' | 'intermediate' | 'advanced' | 'expert'; duration: number; // minutos moduleCount: number; lessonCount: number; studentCount: number; rating: number; // 0-5 reviewCount: number; instructor: { id: string; name: string; avatar: string; title: string; }; tags: string[]; isPremium: boolean; publishedAt: string; userProgress?: { enrolledAt: string; progressPercent: number; lastAccessedAt: string; isCompleted: boolean; }; } interface CatalogResponse { courses: Course[]; pagination: { page: number; limit: number; total: number; totalPages: number; }; filters: { categories: Category[]; levels: string[]; }; } ``` --- ## Reglas de Negocio 1. **Cursos activos:** Solo mostrar cursos con status 'published' 2. **Acceso Premium:** Cursos premium requieren suscripción activa 3. **Visibilidad:** Cursos draft solo visibles para instructores y admins 4. **Límite de paginación:** Máximo 50 cursos por página 5. **Caché:** Catálogo se cachea por 5 minutos 6. **Búsqueda mínima:** Al menos 2 caracteres para búsqueda 7. **Recomendaciones:** Máximo 6 cursos en sección recomendados 8. **Orden por defecto:** Más recientes primero para usuarios nuevos --- ## Criterios de Aceptación ```gherkin Escenario: Usuario visualiza catálogo de cursos DADO que el usuario está autenticado Y está en la página de educación CUANDO accede a /education/courses ENTONCES se muestra un listado de cursos Y se muestran 12 cursos por página Y cada curso muestra: título, imagen, nivel, duración, rating Y se muestran filtros en sidebar izquierdo Y se muestra barra de búsqueda en header Escenario: Usuario filtra por categoría DADO que el usuario está en el catálogo CUANDO selecciona la categoría "Análisis Técnico" ENTONCES se muestran solo cursos de esa categoría Y el filtro se marca como activo Y la URL se actualiza con ?category=technical-analysis Y se mantienen otros filtros activos Escenario: Usuario busca curso DADO que el usuario está en el catálogo CUANDO escribe "fibonacci" en la búsqueda ENTONCES se muestran resultados en tiempo real Y se resalta el término "fibonacci" en resultados Y se muestra contador "X resultados para 'fibonacci'" Escenario: Usuario sin resultados DADO que el usuario busca "xyz123" Y no hay cursos que coincidan ENTONCES se muestra mensaje "No se encontraron cursos" Y se sugieren búsquedas alternativas Y se muestran cursos populares como alternativa Escenario: Ver cursos recomendados DADO que el usuario tiene cursos en progreso CUANDO accede al catálogo ENTONCES se muestra sección "Recomendado para ti" Y aparecen máximo 6 cursos relacionados Y se muestra sección "Continuar aprendiendo" ``` --- ## Dependencias - Education API para datos de cursos - PostgreSQL schema education - Redis para caché de catálogo - Elasticsearch para búsqueda (opcional, mejora performance) --- ## Notas Técnicas - Implementar virtual scrolling para listas largas - Usar React Query para caché de frontend - Implementar skeleton loading durante carga - Optimizar imágenes con lazy loading - Considerar SSR para mejor SEO - Implementar analytics de búsquedas para mejorar recomendaciones --- ## Referencias - Schema database: `/backend/src/database/schemas/education.sql` - API endpoints: `/backend/src/modules/courses/courses.routes.ts` - Frontend: `/frontend/src/pages/Courses.tsx` --- ## Tareas Técnicas **Database:** - [ ] Verificar índices en education.courses (title, category_id, level, published_at) - [ ] Crear vista courses_catalog con joins pre-calculados - [ ] Implementar full-text search en PostgreSQL **Backend:** - [ ] Endpoint GET /education/courses con paginación y filtros - [ ] Endpoint GET /education/categories - [ ] Implementar CourseService.getCatalog() - [ ] Implementar sistema de recomendaciones básico - [ ] Agregar rate limiting a búsqueda - [ ] Implementar caché Redis para catálogo **Frontend:** - [ ] Crear página CoursesPage.tsx - [ ] Crear componente CourseCard.tsx - [ ] Crear componente CourseFilters.tsx - [ ] Crear componente SearchBar.tsx - [ ] Implementar coursesStore (Zustand) - [ ] Implementar infinite scroll opcional - [ ] Agregar analytics de búsqueda **Tests:** - [ ] Test unitario CourseService - [ ] Test integración GET /courses con filtros - [ ] Test E2E navegación y búsqueda --- **Creado por:** Requirements-Analyst **Fecha:** 2025-12-05 **Última actualización:** 2025-12-05