trading-platform/docs/02-definicion-modulos/OQI-002-education/requerimientos/RF-EDU-005-certificados.md
rckrdmrd c1b5081208 feat(ml): Complete FASE 11 - BTCUSD update and comprehensive documentation alignment
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>
2026-01-07 09:31:29 -06:00

337 lines
11 KiB
Markdown

---
id: "RF-EDU-005"
title: "Sistema de Certificados"
type: "Requirement"
status: "Done"
priority: "Media"
module: "education"
epic: "OQI-002"
version: "1.0"
created_date: "2025-12-05"
updated_date: "2026-01-04"
---
# RF-EDU-005: Sistema de Certificados
**Versión:** 1.0.0
**Fecha:** 2025-12-05
**Épica:** OQI-002 - Módulo Educativo
**Prioridad:** P2
**Story Points:** 5
---
## Descripción
El sistema debe proporcionar certificados digitales verificables que se otorgan automáticamente al completar cursos, validando el conocimiento adquirido y permitiendo a los usuarios compartir sus logros profesionales en redes sociales y plataformas de empleo.
---
## Requisitos Funcionales
### RF-EDU-005.1: Generación de Certificados
El sistema debe:
- Generar certificado automáticamente al completar 100% de un curso
- Validar que todos los quizzes obligatorios estén aprobados
- Validar que todas las lecciones estén marcadas como completadas
- Asignar ID único de certificado (formato: OQI-EDU-XXXXXXXX)
- Generar PDF con diseño profesional
- Almacenar PDF en S3 o similar
- Registrar en blockchain para verificación (opcional, fase 2)
### RF-EDU-005.2: Contenido del Certificado
Cada certificado debe incluir:
- Logo de Trading Platform
- Título: "Certificado de Finalización"
- Nombre completo del usuario
- Título del curso completado
- Fecha de finalización
- ID único del certificado
- Firma digital del instructor (imagen)
- Firma digital de la plataforma
- QR code para verificación online
- Footer: "Verifica este certificado en trading.com/verify/{certificateId}"
Template:
```
┌─────────────────────────────────────────────────────────┐
│ │
│ [LOGO ORBIQUANT] │
│ │
│ CERTIFICADO DE FINALIZACIÓN │
│ │
│ Se certifica que │
│ │
│ [NOMBRE USUARIO] │
│ │
│ Ha completado exitosamente el curso │
│ │
│ "[TÍTULO DEL CURSO]" │
│ │
│ Fecha: [DD/MM/YYYY] │
│ Certificado: OQI-EDU-XXXXXXXX │
│ │
│ ___________________ ___________________ │
│ [Firma Instructor] [Firma Plataforma] │
│ │
│ [QR CODE] │
│ Verifica en trading.com/verify/XXXX │
│ │
└─────────────────────────────────────────────────────────┘
```
### RF-EDU-005.3: Verificación de Certificados
El sistema debe:
- Proveer página pública /verify/:certificateId
- Mostrar información del certificado sin login
- Validar que el ID existe en base de datos
- Mostrar: nombre, curso, fecha, estado (válido/revocado)
- Proteger contra scraping (rate limiting, captcha)
- API pública GET /api/certificates/verify/:id
- Responder en JSON para integraciones
### RF-EDU-005.4: Galería de Certificados del Usuario
El sistema debe:
- Página /education/certificates con todos los certificados del usuario
- Mostrar: thumbnail, título del curso, fecha
- Filtrar por: fecha, curso, categoría
- Buscar por nombre de curso
- Ordenar por: más reciente, alfabético, categoría
- Vista de cuadrícula o lista
- Contador: "Has obtenido X certificados"
### RF-EDU-005.5: Descarga y Compartir
El sistema debe permitir:
- Descargar PDF del certificado
- Botón "Compartir en LinkedIn" (pre-rellenado)
- Botón "Compartir en Twitter/X"
- Botón "Copiar link de verificación"
- Generar imagen social (Open Graph) para compartir
- Agregar a perfil público del usuario (opcional)
Integración LinkedIn:
```javascript
// Pre-llenar certificación en LinkedIn
const linkedInUrl = `https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${encodeURIComponent(courseTitle)}&organizationName=Trading Platform&issueYear=${year}&issueMonth=${month}&certUrl=${verifyUrl}&certId=${certificateId}`;
```
### RF-EDU-005.6: Perfil Público de Certificados
El sistema debe:
- Permitir al usuario crear perfil público opcional
- URL: trading.com/u/:username/certificates
- Mostrar solo certificados que el usuario hizo públicos
- Galería visual de certificados
- Bio del usuario
- Enlaces a redes sociales
- No requiere login para ver
### RF-EDU-005.7: Revocación de Certificados
El sistema debe permitir (solo admins):
- Revocar certificado por fraude
- Agregar motivo de revocación
- Notificar al usuario por email
- Marcar certificado como "REVOKED" en verificación
- Mantener historial de revocaciones
### RF-EDU-005.8: Plantillas de Certificados
El sistema debe soportar:
- Múltiples plantillas (por categoría o nivel)
- Plantilla estándar para todos los cursos
- Plantilla especial para cursos premium
- Plantilla con colores de marca
- Editor de plantillas para admins (fase 2)
---
## Datos de Salida
```typescript
interface Certificate {
id: string;
certificateNumber: string; // OQI-EDU-XXXXXXXX
userId: string;
userName: string;
courseId: string;
courseTitle: string;
courseCategory: string;
completedAt: string;
issuedAt: string;
pdfUrl: string;
verifyUrl: string;
qrCodeUrl: string;
status: 'active' | 'revoked';
revocationReason?: string;
instructorSignature: string;
metadata: {
duration: number; // horas del curso
moduleCount: number;
lessonCount: number;
finalScore?: number; // Si hay quiz final
};
}
interface VerificationResult {
valid: boolean;
certificate?: {
certificateNumber: string;
recipientName: string;
courseTitle: string;
completedAt: string;
status: 'active' | 'revoked';
};
error?: string;
}
```
---
## Reglas de Negocio
1. **Requisitos para certificado:**
- 100% de lecciones completadas
- Todos los quizzes aprobados (si aplica)
- Curso debe estar marcado como "completable" (algunos cursos no otorgan certificado)
2. **ID único:** Formato OQI-EDU-{8 dígitos hex aleatorios}
3. **Nombre en certificado:** Se usa nombre completo del perfil del usuario
4. **Fecha:** Fecha de finalización del curso (última lección completada)
5. **PDF inmutable:** Una vez generado, el PDF no se regenera aunque el usuario cambie su nombre
6. **Caducidad:** Los certificados no caducan
7. **Límite de verificaciones:** 100 verificaciones por IP por hora
8. **Perfil público:** Opt-in, deshabilitado por default
---
## Criterios de Aceptación
```gherkin
Escenario: Usuario completa curso y obtiene 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 muestra modal de felicitación
Y se envía email con el certificado adjunto
Y se muestra botón "Ver certificado"
Escenario: Usuario descarga certificado
DADO que el usuario tiene un certificado
CUANDO accede a /education/certificates
Y hace click en "Descargar PDF"
ENTONCES se descarga archivo PDF con el certificado
Y el PDF contiene: nombre, curso, fecha, ID, firmas, QR
Escenario: Usuario comparte en LinkedIn
DADO que el usuario está viendo su certificado
CUANDO hace click en "Compartir en LinkedIn"
ENTONCES se abre LinkedIn en nueva pestaña
Y el formulario está pre-llenado con:
- Nombre del curso
- Organización: Trading Platform
- Fecha de emisión
- URL de verificación
- ID del certificado
Escenario: Tercero verifica certificado
DADO que alguien tiene el ID de un certificado
CUANDO accede a trading.com/verify/OQI-EDU-12345678
ENTONCES se muestra página de verificación
Y se muestra: nombre del usuario, curso, fecha
Y se muestra badge "✓ Certificado Válido"
Y NO requiere login para ver
Escenario: Verificar certificado inválido
DADO que alguien accede a /verify/INVALID-ID
CUANDO el ID no existe en la base de datos
ENTONCES se muestra "Certificado no encontrado"
Y se sugiere verificar el ID ingresado
Escenario: Ver certificado revocado
DADO que un certificado fue revocado por admin
CUANDO alguien intenta verificarlo
ENTONCES se muestra "Certificado Revocado"
Y se muestra motivo de revocación
Y se marca en rojo como inválido
```
---
## Dependencias
- PDF generation library (PDFKit, Puppeteer, o similar)
- S3 para almacenar PDFs
- QR code generator
- Email service para enviar certificados
- LinkedIn API para integración
---
## Notas Técnicas
- Usar Puppeteer para generar PDFs desde HTML template
- Almacenar PDFs con nombre: certificates/{userId}/{certificateId}.pdf
- Generar QR codes con librería qrcode.js
- Implementar caché de verificaciones (Redis) para reducir load
- Considerar watermark en PDFs para prevenir falsificación
- Usar signed URLs de S3 para descargas seguras
- Implementar rate limiting agresivo en endpoint de verificación
- Para blockchain: Guardar hash del certificado en Ethereum/Polygon
---
## Referencias
- Schema: `/backend/src/database/schemas/education.sql`
- API: `/backend/src/modules/courses/certificates.routes.ts`
- Frontend: `/frontend/src/pages/Certificates.tsx`
- Templates: `/backend/src/templates/certificate-template.html`
---
## Tareas Técnicas
**Database:**
- [ ] Tabla education.certificates
- [ ] Campos: id, certificate_number, user_id, course_id, issued_at, pdf_url, status
- [ ] Tabla certificate_verifications (log de verificaciones)
- [ ] Índice único en certificate_number
**Backend:**
- [ ] Endpoint POST /education/certificates/generate (triggered on course completion)
- [ ] Endpoint GET /education/certificates (listar del usuario)
- [ ] Endpoint GET /education/certificates/:id
- [ ] Endpoint GET /api/public/certificates/verify/:number (público)
- [ ] Endpoint POST /admin/certificates/:id/revoke (admin only)
- [ ] Implementar CertificateService.generatePDF()
- [ ] Implementar generación de QR code
- [ ] Event handler en course completion
- [ ] Rate limiting en verificación
**Frontend:**
- [ ] Crear CertificatesPage.tsx
- [ ] Crear componente CertificateCard.tsx
- [ ] Crear CertificateDetailPage.tsx
- [ ] Crear VerifyCertificatePage.tsx (pública)
- [ ] Crear modal de celebración al obtener certificado
- [ ] Botones de compartir social media
- [ ] Preview de PDF en modal
- [ ] Implementar certificatesStore
**Tests:**
- [ ] Test generación de PDF
- [ ] Test verificación de certificado válido/inválido
- [ ] Test E2E completar curso y obtener certificado
---
**Creado por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05