ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
544 lines
19 KiB
YAML
544 lines
19 KiB
YAML
# TRACEABILITY.yml - OQI-002 Módulo Educativo
|
|
# Mapeo de requerimientos a implementación
|
|
|
|
version: "1.1.0"
|
|
epic: OQI-002
|
|
name: "Módulo Educativo - Cursos de Trading"
|
|
updated: "2026-01-04"
|
|
status: in_progress
|
|
|
|
# Resumen de trazabilidad
|
|
summary:
|
|
total_requirements: 6
|
|
total_specs: 6
|
|
total_user_stories: 8
|
|
total_files_to_implement: 35
|
|
test_coverage: "TBD"
|
|
story_points: 45
|
|
|
|
# Mapeo de Requerimientos Funcionales
|
|
requirements:
|
|
RF-EDU-001:
|
|
name: "Catálogo de Cursos"
|
|
status: pending
|
|
specs:
|
|
- ET-EDU-001
|
|
- ET-EDU-002
|
|
- ET-EDU-003
|
|
user_stories:
|
|
- US-EDU-001
|
|
- US-EDU-002
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/course.service.ts
|
|
description: "Servicio de gestión de cursos"
|
|
methods:
|
|
- getCourses
|
|
- getCourseBySlug
|
|
- getCourseById
|
|
- searchCourses
|
|
- getCoursesbyCategory
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- listCourses
|
|
- getCourse
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "GET /education/courses"
|
|
- "GET /education/courses/:slug"
|
|
- "GET /education/categories"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/pages/Courses.tsx
|
|
description: "Página de catálogo de cursos"
|
|
- path: apps/frontend/src/modules/education/pages/CourseDetail.tsx
|
|
description: "Página de detalle de curso"
|
|
- path: apps/frontend/src/modules/education/components/CourseCard.tsx
|
|
description: "Tarjeta de curso"
|
|
- path: apps/frontend/src/modules/education/components/CourseFilters.tsx
|
|
description: "Filtros de búsqueda"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- courses
|
|
- course_categories
|
|
- course_tags
|
|
enums:
|
|
- course_level_enum
|
|
- course_status_enum
|
|
tests:
|
|
- path: apps/backend/tests/education/course.service.test.ts
|
|
status: pending
|
|
|
|
RF-EDU-002:
|
|
name: "Sistema de Lecciones"
|
|
status: implemented
|
|
implementation_notes:
|
|
- date: "2026-01-04"
|
|
changes:
|
|
- "Creado Lesson.tsx para visualización de lecciones con video player"
|
|
- "Soporte para contenido: video, article, text, quiz, exercise"
|
|
- "Navegación entre lecciones con sidebar de progreso"
|
|
- "Integrado en App.tsx con rutas /education/courses/:courseSlug/lesson/:lessonId"
|
|
specs:
|
|
- ET-EDU-001
|
|
- ET-EDU-004
|
|
user_stories:
|
|
- US-EDU-003
|
|
- US-EDU-004
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/lesson.service.ts
|
|
description: "Servicio de lecciones"
|
|
methods:
|
|
- getLessonsByCourse
|
|
- getLessonById
|
|
- getNextLesson
|
|
- getPreviousLesson
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- getLessons
|
|
- getLesson
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "GET /education/courses/:id/lessons"
|
|
- "GET /education/lessons/:id"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/pages/LessonViewer.tsx
|
|
description: "Visor de lecciones"
|
|
- path: apps/frontend/src/modules/education/components/LessonList.tsx
|
|
description: "Lista de lecciones del curso"
|
|
- path: apps/frontend/src/modules/education/components/LessonNavigation.tsx
|
|
description: "Navegación entre lecciones"
|
|
- path: apps/frontend/src/modules/education/components/VideoPlayer.tsx
|
|
description: "Reproductor de video"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- lessons
|
|
- lesson_resources
|
|
enums:
|
|
- lesson_type_enum
|
|
- resource_type_enum
|
|
tests:
|
|
- path: apps/backend/tests/education/lesson.service.test.ts
|
|
status: pending
|
|
|
|
RF-EDU-003:
|
|
name: "Tracking de Progreso"
|
|
status: pending
|
|
specs:
|
|
- ET-EDU-001
|
|
- ET-EDU-003
|
|
user_stories:
|
|
- US-EDU-005
|
|
- US-EDU-007
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/progress.service.ts
|
|
description: "Servicio de progreso"
|
|
methods:
|
|
- getProgress
|
|
- updateLessonProgress
|
|
- completeCourse
|
|
- getEnrolledCourses
|
|
- calculateCourseProgress
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- getMyProgress
|
|
- markLessonComplete
|
|
- enrollInCourse
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "POST /education/courses/:id/enroll"
|
|
- "GET /education/my-courses"
|
|
- "POST /education/lessons/:id/progress"
|
|
- "GET /education/courses/:id/progress"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/pages/MyLearning.tsx
|
|
description: "Página de mis cursos"
|
|
- path: apps/frontend/src/modules/education/components/ProgressBar.tsx
|
|
description: "Barra de progreso"
|
|
- path: apps/frontend/src/modules/education/components/ProgressSummary.tsx
|
|
description: "Resumen de progreso"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- enrollments
|
|
- lesson_progress
|
|
tests:
|
|
- path: apps/backend/tests/education/progress.service.test.ts
|
|
status: pending
|
|
|
|
RF-EDU-004:
|
|
name: "Sistema de Quizzes"
|
|
status: implemented
|
|
implementation_notes:
|
|
- date: "2026-01-04"
|
|
changes:
|
|
- "Creado Quiz.tsx con estados: intro, in_progress, submitted"
|
|
- "Timer de cuenta regresiva para quizzes con límite de tiempo"
|
|
- "Soporte para tipos: multiple_choice, true_false, multi_select"
|
|
- "Sistema de puntos y XP integrado"
|
|
- "Ruta: /education/courses/:courseSlug/lesson/:lessonId/quiz"
|
|
specs:
|
|
- ET-EDU-005
|
|
user_stories:
|
|
- US-EDU-006
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/quiz.service.ts
|
|
description: "Servicio de quizzes"
|
|
methods:
|
|
- getQuiz
|
|
- submitQuiz
|
|
- getQuizResults
|
|
- calculateScore
|
|
- getQuizAttempts
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- getQuiz
|
|
- submitQuizAnswers
|
|
- getQuizResults
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "GET /education/quizzes/:id"
|
|
- "POST /education/quizzes/:id/submit"
|
|
- "GET /education/quizzes/:id/results"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/pages/QuizPage.tsx
|
|
description: "Página de quiz"
|
|
- path: apps/frontend/src/modules/education/components/QuizForm.tsx
|
|
description: "Formulario de quiz"
|
|
- path: apps/frontend/src/modules/education/components/QuizResults.tsx
|
|
description: "Resultados de quiz"
|
|
- path: apps/frontend/src/modules/education/components/QuizQuestion.tsx
|
|
description: "Componente de pregunta"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- quizzes
|
|
- quiz_questions
|
|
- quiz_answers
|
|
- quiz_attempts
|
|
enums:
|
|
- question_type_enum
|
|
tests:
|
|
- path: apps/backend/tests/education/quiz.service.test.ts
|
|
status: pending
|
|
|
|
RF-EDU-005:
|
|
name: "Certificados"
|
|
status: pending
|
|
specs:
|
|
- ET-EDU-003
|
|
user_stories:
|
|
- US-EDU-008
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/certificate.service.ts
|
|
description: "Servicio de certificados"
|
|
methods:
|
|
- generateCertificate
|
|
- getCertificates
|
|
- verifyCertificate
|
|
- downloadCertificate
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- getMyCertificates
|
|
- downloadCertificate
|
|
- verifyCertificate
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "GET /education/certificates"
|
|
- "GET /education/certificates/:id/download"
|
|
- "GET /education/certificates/verify/:code"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/pages/Certificates.tsx
|
|
description: "Página de certificados"
|
|
- path: apps/frontend/src/modules/education/components/CertificateCard.tsx
|
|
description: "Tarjeta de certificado"
|
|
- path: apps/frontend/src/modules/education/components/CertificateModal.tsx
|
|
description: "Modal de certificado"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- certificates
|
|
tests:
|
|
- path: apps/backend/tests/education/certificate.service.test.ts
|
|
status: pending
|
|
|
|
RF-EDU-006:
|
|
name: "Gamificación"
|
|
status: pending
|
|
specs:
|
|
- ET-EDU-006
|
|
user_stories: []
|
|
implementation:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/services/gamification.service.ts
|
|
description: "Servicio de gamificación"
|
|
methods:
|
|
- awardPoints
|
|
- getLeaderboard
|
|
- getBadges
|
|
- checkAchievements
|
|
- getStreak
|
|
- path: apps/backend/src/modules/education/controllers/education.controller.ts
|
|
methods:
|
|
- getLeaderboard
|
|
- getMyAchievements
|
|
- getMyBadges
|
|
- path: apps/backend/src/modules/education/education.routes.ts
|
|
routes:
|
|
- "GET /education/leaderboard"
|
|
- "GET /education/achievements"
|
|
- "GET /education/badges"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/components/Leaderboard.tsx
|
|
description: "Tabla de clasificación"
|
|
- path: apps/frontend/src/modules/education/components/AchievementBadge.tsx
|
|
description: "Badge de logro"
|
|
- path: apps/frontend/src/modules/education/components/StreakCounter.tsx
|
|
description: "Contador de racha"
|
|
database:
|
|
- path: apps/database/schemas/02_education_schema.sql
|
|
tables:
|
|
- achievements
|
|
- user_achievements
|
|
- badges
|
|
- user_badges
|
|
- learning_streaks
|
|
tests:
|
|
- path: apps/backend/tests/education/gamification.service.test.ts
|
|
status: pending
|
|
|
|
# Mapeo de archivos de configuración
|
|
config_files:
|
|
backend:
|
|
- path: apps/backend/src/modules/education/education.module.ts
|
|
description: "Módulo de educación"
|
|
- path: apps/backend/src/modules/education/validators/education.validators.ts
|
|
description: "Validadores Zod"
|
|
- path: apps/backend/src/modules/education/types/education.types.ts
|
|
description: "Tipos TypeScript"
|
|
frontend:
|
|
- path: apps/frontend/src/modules/education/stores/education.store.ts
|
|
description: "Store de educación Zustand"
|
|
- path: apps/frontend/src/modules/education/hooks/useEducation.ts
|
|
description: "Hook principal de educación"
|
|
- path: apps/frontend/src/modules/education/services/education.api.ts
|
|
description: "Cliente API de educación"
|
|
|
|
# Dependencias externas
|
|
external_dependencies:
|
|
npm_backend:
|
|
- name: pdfkit
|
|
version: "^0.14.0"
|
|
usage: "Generación de certificados PDF"
|
|
- name: qrcode
|
|
version: "^1.5.3"
|
|
usage: "QR en certificados"
|
|
- name: sharp
|
|
version: "^0.33.0"
|
|
usage: "Procesamiento de imágenes"
|
|
npm_frontend:
|
|
- name: react-player
|
|
version: "^2.13.0"
|
|
usage: "Reproductor de video"
|
|
- name: "@tanstack/react-query"
|
|
version: "^5.0.0"
|
|
usage: "Data fetching"
|
|
services:
|
|
- name: Cloudflare Stream
|
|
purpose: "Video hosting y streaming"
|
|
alternative: "Vimeo OTT"
|
|
- name: AWS S3
|
|
purpose: "Almacenamiento de recursos"
|
|
|
|
# APIs de terceros
|
|
third_party_apis:
|
|
- name: Cloudflare Stream API
|
|
docs: https://developers.cloudflare.com/stream/
|
|
usage:
|
|
- Upload de videos
|
|
- Signed URLs
|
|
- Analytics de reproducciones
|
|
- name: AWS S3
|
|
docs: https://docs.aws.amazon.com/s3/
|
|
usage:
|
|
- Almacenamiento de recursos
|
|
- Certificados PDF
|
|
|
|
# Endpoints API
|
|
api_endpoints:
|
|
base_path: /api/v1/education
|
|
endpoints:
|
|
# Cursos
|
|
- method: GET
|
|
path: /courses
|
|
requirement: RF-EDU-001
|
|
auth: false
|
|
description: "Listar catálogo de cursos"
|
|
- method: GET
|
|
path: /courses/:slug
|
|
requirement: RF-EDU-001
|
|
auth: false
|
|
description: "Detalle de curso por slug"
|
|
- method: GET
|
|
path: /categories
|
|
requirement: RF-EDU-001
|
|
auth: false
|
|
description: "Listar categorías"
|
|
# Inscripción
|
|
- method: POST
|
|
path: /courses/:id/enroll
|
|
requirement: RF-EDU-003
|
|
auth: true
|
|
description: "Inscribirse a un curso"
|
|
- method: GET
|
|
path: /my-courses
|
|
requirement: RF-EDU-003
|
|
auth: true
|
|
description: "Mis cursos inscritos"
|
|
# Lecciones
|
|
- method: GET
|
|
path: /courses/:id/lessons
|
|
requirement: RF-EDU-002
|
|
auth: true
|
|
description: "Lecciones de un curso"
|
|
- method: GET
|
|
path: /lessons/:id
|
|
requirement: RF-EDU-002
|
|
auth: true
|
|
description: "Detalle de lección"
|
|
- method: POST
|
|
path: /lessons/:id/progress
|
|
requirement: RF-EDU-003
|
|
auth: true
|
|
description: "Actualizar progreso"
|
|
# Quizzes
|
|
- method: GET
|
|
path: /quizzes/:id
|
|
requirement: RF-EDU-004
|
|
auth: true
|
|
description: "Obtener quiz"
|
|
- method: POST
|
|
path: /quizzes/:id/submit
|
|
requirement: RF-EDU-004
|
|
auth: true
|
|
description: "Enviar respuestas"
|
|
- method: GET
|
|
path: /quizzes/:id/results
|
|
requirement: RF-EDU-004
|
|
auth: true
|
|
description: "Ver resultados"
|
|
# Certificados
|
|
- method: GET
|
|
path: /certificates
|
|
requirement: RF-EDU-005
|
|
auth: true
|
|
description: "Mis certificados"
|
|
- method: GET
|
|
path: /certificates/:id/download
|
|
requirement: RF-EDU-005
|
|
auth: true
|
|
description: "Descargar certificado"
|
|
- method: GET
|
|
path: /certificates/verify/:code
|
|
requirement: RF-EDU-005
|
|
auth: false
|
|
description: "Verificar certificado"
|
|
# Gamificación
|
|
- method: GET
|
|
path: /leaderboard
|
|
requirement: RF-EDU-006
|
|
auth: true
|
|
description: "Ver clasificación"
|
|
- method: GET
|
|
path: /achievements
|
|
requirement: RF-EDU-006
|
|
auth: true
|
|
description: "Mis logros"
|
|
|
|
# Dependencias de épicas
|
|
dependencies:
|
|
blocks: []
|
|
blocked_by:
|
|
- epic: OQI-001
|
|
reason: "Requiere autenticación de usuarios"
|
|
- epic: OQI-005
|
|
reason: "Compra de cursos requiere sistema de pagos"
|
|
type: partial
|
|
|
|
# Notas y decisiones
|
|
notes:
|
|
- "Videos almacenados en Cloudflare Stream con URLs firmadas"
|
|
- "Progreso guardado automáticamente cada 30 segundos"
|
|
- "Certificados con QR de verificación único"
|
|
- "Quizzes con intentos ilimitados pero score máximo registrado"
|
|
- "Sistema de puntos: 10 por lección, 50 por quiz aprobado, 100 por certificado"
|
|
|
|
# Implementación 2026-01-04
|
|
recent_changes:
|
|
- date: "2026-01-04"
|
|
developer: "Claude Code"
|
|
session: 1
|
|
changes:
|
|
- type: frontend
|
|
files:
|
|
- apps/frontend/src/modules/education/pages/Lesson.tsx
|
|
- apps/frontend/src/modules/education/pages/Quiz.tsx
|
|
- apps/frontend/src/App.tsx (rutas añadidas)
|
|
- apps/frontend/src/types/education.types.ts (props añadidas)
|
|
description: "Páginas de lección y quiz implementadas"
|
|
- type: database
|
|
files:
|
|
- apps/database/seeds/prod/education/01-education-courses.sql
|
|
description: "Seeds de cursos ICT/IPDA con 1 curso, 7 módulos, 28 lecciones, 5 quizzes"
|
|
issues_found:
|
|
- "DDL loader no carga 00-extensions.sql ni 01-enums.sql correctamente"
|
|
- "Script usa DB_NAME=trading pero Docker usa trading_trading/trading_platform"
|
|
|
|
- date: "2026-01-04"
|
|
developer: "Claude Code"
|
|
session: 2
|
|
changes:
|
|
- type: database_scripts
|
|
files:
|
|
- apps/database/scripts/create-database.sh
|
|
description: "Correcciones críticas al DDL loader"
|
|
fixes:
|
|
- "Agregada carga de 00-extensions.sql antes de enums"
|
|
- "Búsqueda de enums en 00-enums.sql y 01-enums.sql"
|
|
- "Defaults unificados: DB_NAME=trading_platform, DB_PORT=5433"
|
|
- "Credenciales: trading/trading_dev_2025"
|
|
- type: database_ddl
|
|
files:
|
|
- apps/database/ddl/schemas/auth/tables/01-users.sql
|
|
- apps/database/ddl/schemas/auth/tables/99-deferred-constraints.sql (nuevo)
|
|
description: "Resolución de dependencia circular en auth.users"
|
|
fixes:
|
|
- "Removido constraint password_or_oauth (PostgreSQL no soporta subqueries en CHECK)"
|
|
- "Documentado en 99-deferred-constraints.sql con alternativa de trigger"
|
|
- type: database_seeds
|
|
files:
|
|
- apps/database/seeds/prod/education/01-education-courses.sql
|
|
description: "Correcciones de columnas en seeds de educación"
|
|
fixes:
|
|
- "Lecciones: removido duration_minutes (28 filas corregidas)"
|
|
- "Quizzes: passing_score → passing_score_percentage"
|
|
- "Questions: single_choice → multiple_choice"
|
|
- "Questions: correct_answers removido (respuesta en options.isCorrect)"
|
|
- "Questions: formato options actualizado a [{id,text,isCorrect}]"
|
|
validation:
|
|
status: passed
|
|
database_recreated: true
|
|
counts:
|
|
categories: 5
|
|
courses: 1
|
|
modules: 7
|
|
lessons: 28
|
|
quizzes: 5
|
|
questions: 14
|
|
command: "DB_PORT=5433 ./drop-and-recreate-database.sh"
|