# EXT-007: LTI Integration > **⚠️ BACKLOG - FUERA DEL MVP** > > Esta épica está **parcialmente implementada (40%)** y **NO forma parte del MVP actual**. > Razón: Depende de contratos enterprise. > Ver: [Fase 4: Backlog](../../04-fase-backlog/README.md) **Versión:** 1.0 **Fecha de creación:** 2025-11-07 **Prioridad:** P2 (Promovida desde P3) **Story Points:** 40 SP **Presupuesto:** $6,000 USD **Timeline:** v1.3 (Sprints 17-24) **Estado:** ⏳ BACKLOG (40% implementado) --- ## 📋 Descripción Integración completa con Learning Management Systems (LMS) mediante el estándar **LTI 1.3** (Learning Tools Interoperability) de IMS Global, permitiendo que GAMILIT Platform funcione como una herramienta educativa embebida dentro de Canvas, Moodle, Blackboard y Google Classroom. ## 🎯 Objetivos de Negocio ### Problema a Resolver Las instituciones educativas ya utilizan LMS (Canvas, Moodle, etc.) como plataforma central. Requieren integración nativa para: - Single Sign-On (SSO) automático de estudiantes y profesores - Sincronización automática de calificaciones (grade passback) - Deep linking para seleccionar contenido específico - Gestión centralizada desde el LMS institucional ### Valor Esperado - **B2B Adoption:** +60% (instituciones con LMS requieren integración) - **Ahorro tiempo profesores:** 3h/semana (no gestionar usuarios/calificaciones manualmente) - **ARR incremental:** +$30,000/año - **ROI:** 850% en año 1 - **Churn reduction:** -20% (menos fricción = mayor retención) ### Métricas de Éxito - **Adopción:** >40% instituciones usando LTI en 6 meses - **Grade passback success rate:** >98% - **SSO login time:** <3 segundos - **NPS profesores:** +15 puntos - **Support tickets:** -30% (menos problemas de acceso) --- ## 🏗️ Arquitectura Técnica ### Estándar LTI 1.3 **Componentes principales:** 1. **OIDC Login Flow** (OpenID Connect) - Autenticación segura vía LMS - JWT token validation (RSA-256) - State y nonce para CSRF/replay protection 2. **Grade Passback** (AGS - Assignment & Grades Services) - Envío automático de calificaciones al LMS - Sincronización bidireccional - Mapeo de scoring (0-100 GAMILIT→ escala LMS) 3. **Deep Linking** (Content Selection) - Profesores seleccionan ejercicios/módulos específicos - Configuración de actividades desde LMS - Preview de contenido 4. **Platform Configuration** - Registro de plataformas LMS - Key management (public/private keys) - Multi-tenant isolation ### Stack Tecnológico **Backend:** - **Framework:** NestJS + TypeScript - **Biblioteca:** `@nest-edu/lti` (wrapper de `ltijs`) - **Database:** PostgreSQL (schema `lti_integration`, 5 tablas) - **Seguridad:** RSA-256, JWT validation, HTTPS only **Frontend:** - **UI:** Página de configuración LTI en Admin Portal - **Testing:** Herramienta de validación de integración **Plataformas soportadas:** - Canvas (12h) - Prioridad 1 - Moodle (10h) - Prioridad 2 - Blackboard (10h) - Prioridad 3 - Google Classroom (8h) - Prioridad 4 --- ## 👥 User Stories ### Core Stories (4 historias - 40h total) | ID | Historia | Esfuerzo | Prioridad | |----|----------|----------|-----------| | [US-LTI-001](./historias/US-LTI-001-oidc-login.md) | OIDC Login Flow | 12h | P0 | | [US-LTI-002](./historias/US-LTI-002-grade-passback.md) | Grade Passback (AGS) | 10h | P1 | | [US-LTI-003](./historias/US-LTI-003-deep-linking.md) | Deep Linking | 10h | P2 | | [US-LTI-004](./historias/US-LTI-004-platform-config.md) | Platform Configuration UI | 8h | P1 | **Total:** 40 horas ($6,000 USD) --- ## 🗄️ Modelo de Datos ### Schema: `lti_integration` ```sql CREATE SCHEMA IF NOT EXISTS lti_integration; -- Tabla 1: Plataformas LMS registradas CREATE TABLE lti_integration.lti_platforms ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth_management.tenants(id), platform_name VARCHAR(100) NOT NULL, -- "Canvas Universidad X" issuer VARCHAR(255) NOT NULL, -- URL del LMS client_id VARCHAR(255) NOT NULL, auth_login_url TEXT NOT NULL, auth_token_url TEXT NOT NULL, key_set_url TEXT NOT NULL, -- JWKS endpoint deployment_id VARCHAR(255) NOT NULL, public_key TEXT, -- Clave pública para validar JWTs is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Tabla 2: Contextos LTI (cursos/clases) CREATE TABLE lti_integration.lti_contexts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), platform_id UUID NOT NULL REFERENCES lti_integration.lti_platforms(id), lms_context_id VARCHAR(255) NOT NULL, -- ID del curso en LMS context_title VARCHAR(255), -- "Comprensión Lectora 101" context_label VARCHAR(100), -- "CL101" created_at TIMESTAMPTZ DEFAULT NOW() ); -- Tabla 3: Lanzamientos LTI (cada vez que usuario accede) CREATE TABLE lti_integration.lti_launches ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), platform_id UUID NOT NULL REFERENCES lti_integration.lti_platforms(id), context_id UUID REFERENCES lti_integration.lti_contexts(id), user_id UUID REFERENCES auth_management.users(id), lms_user_id VARCHAR(255), -- ID del usuario en LMS launch_type VARCHAR(50), -- 'login', 'deep_linking', 'grade_passback' id_token TEXT, -- JWT token del LMS launched_at TIMESTAMPTZ DEFAULT NOW() ); -- Tabla 4: Recursos LTI (ejercicios/módulos enlazados) CREATE TABLE lti_integration.lti_resources ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), platform_id UUID NOT NULL REFERENCES lti_integration.lti_platforms(id), context_id UUID NOT NULL REFERENCES lti_integration.lti_contexts(id), exercise_id UUID REFERENCES educational_content.exercises(id), module_id UUID REFERENCES educational_content.modules(id), line_item_url TEXT, -- URL para grade passback resource_title VARCHAR(255), max_score DECIMAL(5,2) DEFAULT 100, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Tabla 5: Grade Passback Log CREATE TABLE lti_integration.lti_grade_passback_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), resource_id UUID NOT NULL REFERENCES lti_integration.lti_resources(id), user_id UUID NOT NULL REFERENCES auth_management.users(id), score_given DECIMAL(5,2), score_maximum DECIMAL(5,2), activity_progress VARCHAR(50), -- 'Initialized', 'Started', 'InProgress', 'Completed' grading_progress VARCHAR(50), -- 'FullyGraded', 'Pending', 'NotReady' passback_status VARCHAR(20), -- 'success', 'failed' error_message TEXT, attempted_at TIMESTAMPTZ DEFAULT NOW() ); -- Índices CREATE INDEX idx_lti_platforms_tenant ON lti_integration.lti_platforms(tenant_id); CREATE INDEX idx_lti_contexts_platform ON lti_integration.lti_contexts(platform_id); CREATE INDEX idx_lti_launches_user ON lti_integration.lti_launches(user_id); CREATE INDEX idx_lti_resources_exercise ON lti_integration.lti_resources(exercise_id); CREATE INDEX idx_lti_grade_log_user ON lti_integration.lti_grade_passback_log(user_id); ``` --- ## 🔗 Dependencias ### Bloqueado por - **EAI-001:** Sistema de autenticación base debe estar completo - **EAI-002:** Mecánicas educativas y ejercicios funcionando - **P0/P1 fixes:** Seguridad y funcionalidad crítica resueltos ### Bloquea - **EXT-002:** Admin Extendido (gestión de tenants con LTI) - **EXT-005:** Reportes Avanzados (métricas de integración LTI) --- ## 🚀 Plan de Implementación ### Sprint 17 (Semanas 17-18) - 20h - **US-LTI-001:** OIDC Login Flow completo (12h) - **US-LTI-004:** Platform Configuration UI básica (8h) ### Sprint 18 (Semanas 19-20) - 20h - **US-LTI-002:** Grade Passback (AGS) (10h) - **US-LTI-003:** Deep Linking (10h) **Testing y Validación:** 8h adicionales (distribuidas en ambos sprints) --- ## 🧪 Testing ### Test Cases Críticos 1. **OIDC Login:** - Usuario LMS puede acceder a GAMILITsin credenciales adicionales - Sesión LMS expirada redirige a login LMS - JWT inválido/expirado es rechazado 2. **Grade Passback:** - Score 100% en GAMILIT→ 100% en LMS - Múltiples intentos envían el score más alto - Errores de red reintentam automáticamente 3. **Deep Linking:** - Profesor selecciona ejercicio → aparece en LMS - Estudiante hace clic → abre ejercicio correcto - Cambios en GAMILITactualizan título en LMS 4. **Multi-tenant Isolation:** - Tenant A no puede acceder a configuración LTI de Tenant B - LMS de Tenant A solo ve contextos de Tenant A ### Herramientas de Testing - **LTI Advantage Validator:** Herramienta oficial IMS Global - **Canvas Free for Teachers:** Ambiente de pruebas Canvas - **Moodle Sandbox:** Instalación de prueba Moodle --- ## 📊 KPIs de la Épica ### Durante Desarrollo - **Code coverage:** >80% - **Security scan:** 0 vulnerabilidades críticas/altas - **Performance:** Login LTI <3 segundos ### Post-Lanzamiento (3 meses) - **Instituciones usando LTI:** >15 (de ~40 total) - **Grade passback success rate:** >98% - **Support tickets LTI:** <5% total tickets - **NPS profesores (LTI):** >60 --- ## 🔐 Consideraciones de Seguridad ### Implementadas - ✅ RSA-256 para firma de JWT - ✅ State y nonce para CSRF/replay protection - ✅ HTTPS only (no HTTP) - ✅ Token expiration validation - ✅ Multi-tenant isolation estricta - ✅ Audit logging de todas las operaciones LTI ### Riesgos Mitigados - **Token theft:** httpOnly cookies, short expiration - **MITM attacks:** HTTPS only, certificate pinning - **Unauthorized grade changes:** Ownership validation, audit trail - **Data leakage:** RLS policies, tenant isolation --- ## 📚 Referencias ### Documentación Técnica - [IMS Global LTI 1.3 Specification](https://www.imsglobal.org/spec/lti/v1p3/) - [LTI Advantage Overview](https://www.imsglobal.org/lti-advantage-overview) - [Canvas LTI Documentation](https://canvas.instructure.com/doc/api/file.lti_dev_key_config.html) - [Moodle LTI Integration](https://docs.moodle.org/en/LTI_and_Moodle) ### Documentación Interna - [ANALISIS-FEATURES-P3-ESTRATEGICAS.md](../../features/ANALISIS-FEATURES-P3-ESTRATEGICAS.md) - Especificación completa - [FEATURES-PENDIENTES.md](../../features/FEATURES-PENDIENTES.md) - F-P2-019: LTI Integration - [RESUMEN-EJECUTIVO-DECISIONES-P3.md](../../features/RESUMEN-EJECUTIVO-DECISIONES-P3.md) - Business case --- **Creado:** 2025-11-07 **Última actualización:** 2025-11-07 **Responsable:** Tech Lead + Backend Team **Revisor:** Product Owner + Security Team