trading-platform/docs/02-definicion-modulos/OQI-002-education/historias-usuario/US-EDU-008-obtener-certificado.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
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>
2026-01-07 05:33:35 -06:00

18 KiB

id title type status priority epic story_points created_date updated_date
US-EDU-008 Obtener Certificado User Story Done Media OQI-002 3 2025-12-05 2026-01-04

US-EDU-008: Obtener Certificado

Metadata

Campo Valor
ID US-EDU-008
Épica OQI-002 - Módulo Educativo
Módulo education
Prioridad P2
Story Points 3
Sprint Sprint 5
Estado Pendiente
Asignado a Por asignar

Historia de Usuario

Como usuario que completó un curso, quiero obtener un certificado digital verificable, para validar mi logro, agregarlo a mi perfil profesional y compartirlo en redes sociales.

Descripción Detallada

El usuario debe recibir automáticamente un certificado digital en formato PDF al completar el 100% de un curso. El certificado debe tener diseño profesional con logo de OrbiQuant, nombre del usuario, título del curso, fecha de finalización, ID único de verificación, y QR code. El usuario debe poder descargar el PDF, compartir en LinkedIn, y el certificado debe ser verificable públicamente.

Mockups/Wireframes

[MODAL DE CURSO COMPLETADO]
┌─────────────────────────────────────────────────────────────────┐
│                        ✨ 🎓 ✨                                  │
│                                                                  │
│              ¡FELICIDADES! CURSO COMPLETADO                     │
│                                                                  │
│            Fibonacci Retracement Básico                         │
│                                                                  │
│                     +200 XP ganados                             │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │                                                            │ │
│  │            [PREVIEW DEL CERTIFICADO]                       │ │
│  │                                                            │ │
│  │  ┌──────────────────────────────────────┐                 │ │
│  │  │  [LOGO ORBIQUANT]                    │                 │ │
│  │  │  CERTIFICADO DE FINALIZACIÓN         │                 │ │
│  │  │                                      │                 │ │
│  │  │  Se certifica que                    │                 │ │
│  │  │  JUAN PÉREZ                          │                 │ │
│  │  │  Ha completado exitosamente          │                 │ │
│  │  │  "Fibonacci Retracement Básico"      │                 │ │
│  │  │                                      │                 │ │
│  │  │  05/12/2025                          │                 │ │
│  │  │  OQI-EDU-A3F8D291                    │                 │ │
│  │  │                                      │                 │ │
│  │  │  [Firma Instructor] [Firma OQI]      │                 │ │
│  │  │         [QR CODE]                    │                 │ │
│  │  └──────────────────────────────────────┘                 │ │
│  │                                                            │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  [📥 Descargar PDF]  [💼 Compartir en LinkedIn]  [✕ Cerrar]   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[PÁGINA DE CERTIFICADOS]
┌─────────────────────────────────────────────────────────────────┐
│  MIS CERTIFICADOS                                       [🔍]     │
│                                                                  │
│  Has obtenido 12 certificados                                   │
│                                                                  │
│  Filtros: [Todos ▼] [Más recientes ▼]                          │
│                                                                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │ [THUMBNAIL] │  │ [THUMBNAIL] │  │ [THUMBNAIL] │            │
│  │             │  │             │  │             │            │
│  │ Fibonacci   │  │ Day Trading │  │ Candlestick │            │
│  │ Básico      │  │ Pro         │  │ Patterns    │            │
│  │             │  │             │  │             │            │
│  │ 05/12/2025  │  │ 28/11/2025  │  │ 15/11/2025  │            │
│  │ OQI-...-291 │  │ OQI-...-8F2 │  │ OQI-...-4A1 │            │
│  │             │  │             │  │             │            │
│  │ [Ver] [📥]  │  │ [Ver] [📥]  │  │ [Ver] [📥]  │            │
│  │ [💼 LinkedIn]│  │ [💼 LinkedIn]│  │ [💼 LinkedIn]│            │
│  └─────────────┘  └─────────────┘  └─────────────┘            │
│                                                                  │
│  [1] 2 3 4                                                      │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

[PÁGINA DE VERIFICACIÓN PÚBLICA]
┌─────────────────────────────────────────────────────────────────┐
│  [LOGO] OrbiQuant IA                                            │
│                                                                  │
│            VERIFICACIÓN DE CERTIFICADO                          │
│                                                                  │
│  Certificado: OQI-EDU-A3F8D291                                  │
│                                                                  │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │                   ✓ CERTIFICADO VÁLIDO                      │ │
│  │                                                             │ │
│  │  Otorgado a: Juan Pérez                                    │ │
│  │  Curso: Fibonacci Retracement Básico                       │ │
│  │  Categoría: Análisis Técnico                               │ │
│  │  Fecha de finalización: 05/12/2025                         │ │
│  │  Duración del curso: 2.5 horas                             │ │
│  │  Módulos: 5 | Lecciones: 23                                │ │
│  │                                                             │ │
│  │  Instructor: Carlos Mendoza                                │ │
│  │  Institución: OrbiQuant IA                                 │ │
│  │                                                             │ │
│  │  Estado: ✅ Activo                                          │ │
│  │  Emitido: 05/12/2025 15:45:00 UTC                          │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  Este certificado puede ser verificado en cualquier momento en: │
│  orbiquant.com/verify/OQI-EDU-A3F8D291                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Criterios de Aceptación

Escenario 1: Completar curso genera certificado

DADO que el usuario completó todas las lecciones de un curso
Y aprobó todos los quizzes obligatorios
CUANDO se marca la última lección como completada
ENTONCES se genera automáticamente un certificado
Y se registra en backend con ID único (OQI-EDU-XXXXXXXX)
Y se genera PDF con diseño profesional
Y se almacena PDF en S3 o CDN
Y se muestra modal de felicitación
Y se envía email con certificado adjunto

Escenario 2: Ver certificado en modal

DADO que se generó el certificado
CUANDO se muestra el modal de curso completado
ENTONCES se muestra preview del certificado
Y se muestra botón "Descargar PDF"
Y se muestra botón "Compartir en LinkedIn"
Y se muestra "Ver todos mis certificados"

Escenario 3: Descargar certificado en PDF

DADO que el usuario tiene un certificado
CUANDO hace click en "Descargar PDF"
ENTONCES se descarga archivo PDF
Y el PDF contiene:
  - Logo de OrbiQuant IA
  - Título "Certificado de Finalización"
  - Nombre completo del usuario
  - Título del curso
  - Fecha de finalización
  - ID único del certificado
  - Firmas digitales (instructor + plataforma)
  - QR code para verificación
  - Footer con URL de verificación

Escenario 4: Compartir en LinkedIn

DADO que el usuario quiere compartir su certificado
CUANDO hace click en "Compartir en LinkedIn"
ENTONCES se abre nueva pestaña de LinkedIn
Y el formulario de certificación está pre-llenado con:
  - Nombre: "Fibonacci Retracement Básico"
  - Organización: "OrbiQuant IA"
  - Fecha de emisión: "Diciembre 2025"
  - ID de certificado: "OQI-EDU-A3F8D291"
  - URL de verificación: "orbiquant.com/verify/..."

Escenario 5: Ver galería de certificados

DADO que el usuario tiene 12 certificados
CUANDO accede a /education/certificates
ENTONCES se muestra galería de todos los certificados
Y cada certificado muestra: thumbnail, título del curso, fecha
Y se muestra contador "Has obtenido 12 certificados"
Y se pueden filtrar por: categoría, fecha
Y se pueden ordenar por: más reciente, alfabético

Escenario 6: Verificar certificado públicamente

DADO que alguien tiene el ID de un certificado
CUANDO accede a orbiquant.com/verify/OQI-EDU-A3F8D291
ENTONCES se muestra página de verificación pública
Y NO requiere login
Y se muestra:
  - Estado: ✅ Válido
  - Nombre del usuario
  - Título del curso
  - Fecha de finalización
  - Detalles del curso
Y se confirma autenticidad del certificado

Escenario 7: Verificar certificado inválido

DADO que alguien accede con ID inválido
CUANDO accede a /verify/INVALID-ID-123
ENTONCES se muestra "Certificado no encontrado"
Y se muestra sugerencia "Verifica el ID ingresado"
Y se muestra link "¿Cómo verificar un certificado?"

Escenario 8: Email de certificado

DADO que se generó un certificado
CUANDO se envía el email
ENTONCES el email contiene:
  - Asunto: "¡Felicidades! Certificado de [Curso]"
  - Mensaje de felicitación personalizado
  - Estadísticas: duración, lecciones completadas
  - PDF adjunto del certificado
  - Botones: Ver certificado, Compartir en LinkedIn
  - Sugerencias de próximos cursos relacionados

Escenario 9: Curso sin certificado disponible

DADO que un curso está marcado como "no certifiable"
CUANDO el usuario completa el curso
ENTONCES NO se genera certificado
Y se muestra "Curso completado" sin opción de certificado
Y se explica "Este curso no otorga certificado"

Escenario 10: Certificado con requisitos adicionales

DADO que un curso requiere quiz final aprobado
Y el usuario completó todas las lecciones
PERO no aprobó el quiz final
CUANDO intenta obtener certificado
ENTONCES se muestra "Debes aprobar el quiz final"
Y se muestra score actual del quiz
Y se muestra "Intentos restantes: X"
Y el certificado NO se genera hasta aprobar

Criterios Adicionales

  • Watermark en PDF para evitar falsificación
  • Blockchain verification (opcional, fase 2)
  • Traducción del certificado a inglés
  • Certificado físico por correo (premium)
  • Badge de LinkedIn auto-agregado via API
  • Opción de hacer certificado público/privado
  • Perfil público con todos los certificados del usuario

Tareas Técnicas

Database:

  • DB-EDU-022: Tabla education.certificates
  • DB-EDU-023: Campos: id, certificate_number, user_id, course_id, issued_at, pdf_url, status
  • DB-EDU-024: Tabla certificate_verifications (log de verificaciones)
  • DB-EDU-025: Índice único en certificate_number

Backend:

  • BE-EDU-057: Endpoint POST /education/certificates/generate
  • BE-EDU-058: Endpoint GET /education/certificates (del usuario)
  • BE-EDU-059: Endpoint GET /education/certificates/:id
  • BE-EDU-060: Endpoint GET /api/public/certificates/verify/:number
  • BE-EDU-061: Implementar CertificateService.generate()
  • BE-EDU-062: Generar PDF con Puppeteer o PDFKit
  • BE-EDU-063: Generar QR code con qrcode library
  • BE-EDU-064: Upload de PDF a S3 con signed URL
  • BE-EDU-065: Event handler en course completion
  • BE-EDU-066: Email service para enviar certificado
  • BE-EDU-067: Rate limiting en verificación (100/hora por IP)

Frontend:

  • FE-EDU-070: Modal CourseCompletedModal.tsx con preview
  • FE-EDU-071: Crear CertificatesPage.tsx
  • FE-EDU-072: Crear componente CertificateCard.tsx
  • FE-EDU-073: Crear VerifyCertificatePage.tsx (pública)
  • FE-EDU-074: Botón "Compartir en LinkedIn" con pre-fill
  • FE-EDU-075: Preview de PDF en modal
  • FE-EDU-076: Galería con filtros y búsqueda
  • FE-EDU-077: Implementar certificatesStore

Tests:

  • TEST-EDU-030: Test generación de certificado
  • TEST-EDU-031: Test validación de certificado válido
  • TEST-EDU-032: Test verificación de certificado inválido
  • TEST-EDU-033: Test E2E completar curso y obtener certificado

Dependencias

Depende de:

  • US-EDU-005: Completar lección - Estado: Pendiente
  • RF-EDU-005: Sistema de certificados
  • PDF generation library (Puppeteer/PDFKit)
  • S3 bucket para almacenar PDFs
  • Email service

Bloquea:

  • Ninguna (es funcionalidad final)

Notas Técnicas

Generación del certificado:

// Triggered on course completion
async function onCourseCompleted(userId, courseId) {
  // 1. Validar requisitos
  const isEligible = await validateCertificateEligibility(userId, courseId);
  if (!isEligible) return;

  // 2. Generar ID único
  const certificateNumber = generateCertificateId(); // OQI-EDU-A3F8D291

  // 3. Generar PDF
  const pdfBuffer = await generateCertificatePDF({
    userName,
    courseName,
    completedDate,
    certificateNumber
  });

  // 4. Upload a S3
  const pdfUrl = await uploadToS3(pdfBuffer, certificateNumber);

  // 5. Guardar en DB
  await saveCertificate({
    userId,
    courseId,
    certificateNumber,
    pdfUrl
  });

  // 6. Enviar email
  await sendCertificateEmail(userId, pdfUrl);

  // 7. Otorgar XP bonus
  await awardXP(userId, 100, 'certificate_earned');
}

Endpoint GET /api/public/certificates/verify/:number:

// Response para certificado válido
{
  valid: true,
  certificate: {
    certificateNumber: "OQI-EDU-A3F8D291",
    recipientName: "Juan Pérez",
    courseTitle: "Fibonacci Retracement Básico",
    courseCategory: "Análisis Técnico",
    completedAt: "2025-12-05T15:45:00Z",
    issuedAt: "2025-12-05T15:45:00Z",
    courseDuration: 150, // minutos
    moduleCount: 5,
    lessonCount: 23,
    instructor: "Carlos Mendoza",
    status: "active"
  }
}

// Response para certificado inválido
{
  valid: false,
  error: "Certificate not found"
}

Template del PDF:

  • Usar HTML + CSS para diseño
  • Puppeteer para generar PDF desde HTML
  • Incluir logo en base64 para evitar carga externa
  • QR code generado con library qrcode.js
  • Firmas como imágenes PNG embebidas

LinkedIn pre-fill URL:

const linkedInUrl = `https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${encodeURIComponent(courseTitle)}&organizationName=OrbiQuant%20IA&issueYear=${year}&issueMonth=${month}&certUrl=${encodeURIComponent(verifyUrl)}&certId=${certificateNumber}`;

Seguridad:

  • Rate limiting en endpoint de verificación
  • Signed URLs de S3 con expiración de 1 hora para descargas
  • No exponer lista de todos los certificados (solo del usuario logueado)
  • Validar que usuario solo puede descargar sus propios certificados

Entidades/Tablas:

  • education.certificates
  • education.certificate_verifications (log)

Definition of Ready (DoR)

  • Historia claramente escrita
  • Criterios de aceptación definidos
  • Story points estimados
  • Dependencias identificadas
  • Sin bloqueadores
  • Diseño/mockup disponible
  • 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