# RF-EDU-001: Mecánicas de Ejercicios ## 📋 Metadata | Campo | Valor | |-------|-------| | **ID** | RF-EDU-001 | | **Módulo** | 03 - Contenido Educativo | | **Título** | Mecánicas de Ejercicios | | **Prioridad** | Crítica | | **Estado** | ✅ Implementado | | **Versión** | 2.0 | | **Fecha Creación** | 2025-11-07 | | **Última Actualización** | 2025-11-11 | | **Autor** | Database Team, Pedagogical Team | | **Stakeholders** | Product Owner, Content Team, UX Team, Backend Team, Frontend Team | --- ## 🔗 Referencias ### Implementación DDL 🗄️ **ENUM Canónico:** - **Ubicación:** `apps/database/ddl/00-prerequisites.sql:~85-120` - **Tipo:** `educational_content.exercise_type` - **Valores:** 35 mecánicas específicas GAMILIT - **Agrupación:** 5 módulos educativos (1-5) + 10 auxiliares 🗄️ **Clasificación Pedagógica:** - **Tabla:** `educational_content.exercise_mechanic_mapping` - **Categorías:** 7 categorías universales (Vocabulario, Gramática, Lectura, Escritura, Audio, Pronunciación, Cultura) - **Subcategorías:** 31 mecánicas pedagógicas genéricas - **Propósito:** Mapear exercise_type a clasificación pedagógica estándar 🗄️ **Tablas Relacionadas:** 1. **`educational_content.exercises`** - **Ubicación:** `apps/database/ddl/schemas/educational_content/tables/02-exercises.sql` - **Columnas clave:** - `exercise_type` (ENUM exercise_type) - Implementación GAMILIT - `difficulty` (ENUM difficulty_level) - `content` (JSONB, estructura variable según tipo) - `answer_key` (JSONB) - `hints` (JSONB array) 2. **`educational_content.exercise_mechanic_mapping`** (NUEVA en v2.0) - **Ubicación:** `apps/database/ddl/schemas/educational_content/tables/21-exercise_mechanic_mapping.sql` - **Columnas clave:** - `mechanic_category` (VARCHAR) - Categoría pedagógica - `mechanic_subcategory` (VARCHAR) - Subcategoría pedagógica - `exercise_type` (ENUM exercise_type) - Mapeo a implementación - `bloom_level` (VARCHAR) - Nivel de taxonomía de Bloom - `cefr_level` (difficulty_level[]) - Niveles CEFR aplicables - `pedagogical_purpose` (TEXT) - Propósito pedagógico - `learning_objectives` (TEXT[]) - Objetivos de aprendizaje ### Especificación Técnica 📘 **Documento ET Relacionado:** - [ET-EDU-001: Implementación de Mecánicas de Ejercicios](../../02-especificaciones-tecnicas/03-contenido-educativo/ET-EDU-001-mecanicas-ejercicios.md) ### Documentos Relacionados - [RF-EDU-002: Niveles de Dificultad](./RF-EDU-002-niveles-dificultad.md) - 8 niveles de dificultad - [RF-EDU-003: Taxonomía de Bloom](./RF-EDU-003-taxonomia-bloom.md) - Clasificación cognitiva - [RF-PRG-001: Tracking de Progreso](../04-progreso-seguimiento/RF-PRG-001-tracking-progreso.md) - Intentos de ejercicios - [RF-GAM-002: Sistema de Comodines](../02-gamificacion/RF-GAM-002-comodines.md) - Comodines en ejercicios - [MAPEO: Requerimientos → Implementación](../../03-desarrollo/base-de-datos/MAPEO-REQUERIMIENTOS-IMPLEMENTACION.md#módulo-3-contenido-educativo) --- ## 📖 Descripción General ### Propósito El **Sistema de Mecánicas de Ejercicios** define 35 implementaciones específicas GAMILIT de ejercicios interactivos que cubren diversos aspectos del aprendizaje del idioma maya yucateco. Cada implementación: - Tiene una estructura de contenido específica (JSONB) - Requiere un tipo de interacción diferente - Valida respuestas con lógica única - Proporciona feedback adaptado - Se adapta a diferentes niveles de dificultad (CEFR) - Se mapea a categorías pedagógicas universales ### Contexto Pedagógico Las 35 **implementaciones GAMILIT** (exercise_type) se clasifican en **7 categorías pedagógicas**: | Categoría | Implementaciones GAMILIT | Objetivo | GAPs* | |-----------|--------------------------|----------|-------| | **Vocabulario** | crucigrama, sopa_letras, emparejamiento, flashcard, completar_espacios | Reconocimiento y memorización | 1 | | **Gramática** | - | Comprensión y aplicación de reglas | 8 | | **Lectura** | detective_textual, construccion_hipotesis, prediccion_narrativa, analisis_fuentes, puzzle_contexto | Comprensión de textos | 0 | | **Escritura** | ensayo_argumentativo, resena_critica, diario_multimedia, comic_digital, email_formal, chat_literario | Producción escrita | 0 | | **Audio** | comprension_auditiva, podcast_argumentativo | Comprensión auditiva | 1 | | **Pronunciación** | - | Producción oral | 2 | | **Cultura** | tribunal_opiniones, collage_prensa, call_to_action | Conocimiento cultural maya | 1 | **\* GAPs:** Mecánicas pedagógicas documentadas sin implementación GAMILIT específica (13 GAPs totales identificados en DB-112) **Nota:** El mapeo completo entre categorías pedagógicas e implementaciones GAMILIT se mantiene en la tabla `exercise_mechanic_mapping`. Ver ET-EDU-001 v2.0 para detalles del sistema dual. ### Alcance **Incluye:** - ✅ 35 implementaciones específicas GAMILIT (exercise_type) - ✅ Mapeo a 7 categorías pedagógicas + 31 subcategorías - ✅ Estructura de contenido estandarizada (JSONB) - ✅ Validación de respuestas por implementación - ✅ Sistema de hints (pistas) configurable - ✅ Scoring y feedback automático - ✅ Adaptabilidad a 8 niveles CEFR **Excluye:** - ❌ Generación automática de contenido (se crea manualmente) - ❌ Traducción automática - ❌ AI para corrección de escritura libre --- ## ⚙️ Requerimientos Funcionales ### Categoría 1: Vocabulario (6 mecánicas) #### 1.1. Multiple Choice (Selección Múltiple) **ID:** `multiple_choice` **Descripción:** Seleccionar la respuesta correcta entre 4 opciones **Estructura de contenido:** ```json { "question": "¿Qué significa 'k'áak''?", "options": [ { "id": "a", "text": "Fuego" }, { "id": "b", "text": "Agua" }, { "id": "c", "text": "Tierra" }, { "id": "d", "text": "Aire" } ], "correct_answer": "a" } ``` **Validación:** - Respuesta: `{ "selected": "a" }` - Correcto si: `selected === correct_answer` --- #### 1.2. Fill in the Blank (Completar el Espacio) **ID:** `fill_in_blank` **Descripción:** Escribir la palabra que completa la oración **Estructura:** ```json { "sentence": "Le ___ ku ts'o'okol u k'áatik.", "blank_position": 1, "correct_answer": "paal", "context": "El niño está pidiendo agua", "accept_variations": ["páal", "paal"] } ``` **Validación:** - Normalizar respuesta (quitar acentos opcionales) - Verificar contra `accept_variations` --- #### 1.3. Matching Pairs (Emparejar) **ID:** `matching_pairs` **Descripción:** Conectar palabras en maya con su traducción **Estructura:** ```json { "pairs": [ { "id": 1, "maya": "k'áak'", "spanish": "fuego" }, { "id": 2, "maya": "ha'", "spanish": "agua" }, { "id": 3, "maya": "lu'um", "spanish": "tierra" }, { "id": 4, "maya": "ik'", "spanish": "viento" } ], "randomize": true } ``` **Validación:** - Respuesta: `[{ maya_id: 1, spanish_id: 1 }, ...]` - Correcto si todos los pares coinciden --- #### 1.4. Flashcard (Tarjeta de Memoria) **ID:** `flashcard` **Descripción:** Recordar la traducción de una palabra mostrada **Estructura:** ```json { "front": "k'áak'", "back": "fuego", "direction": "maya_to_spanish" } ``` --- #### 1.5. Word Search (Sopa de Letras) **ID:** `word_search` **Descripción:** Encontrar palabras mayas en una grilla **Estructura:** ```json { "grid": [ ["K", "A", "A", "K"], ["H", "A", "X", "T"], ... ], "words_to_find": ["KAAK", "HA", "LUUM"], "size": { "rows": 10, "cols": 10 } } ``` --- #### 1.6. Image Association (Asociación con Imagen) **ID:** `image_association` **Descripción:** Seleccionar la palabra maya que corresponde a la imagen **Estructura:** ```json { "image_url": "/images/fire.jpg", "options": ["k'áak'", "ha'", "lu'um", "ik'"], "correct_answer": "k'áak'" } ``` --- ### Categoría 2: Gramática (8 mecánicas) #### 2.1. Verb Conjugation (Conjugación Verbal) **ID:** `verb_conjugation` **Descripción:** Conjugar verbo en tiempo/persona correcta **Estructura:** ```json { "verb_infinitive": "han", "tense": "present", "person": "first_singular", "prompt": "Yo como", "correct_answer": "kin hant", "accept_variations": ["ki'n hant", "kin hant"] } ``` --- #### 2.2. Sentence Builder (Constructor de Oraciones) **ID:** `sentence_builder` **Descripción:** Ordenar palabras para formar oración correcta **Estructura:** ```json { "words": ["Le", "paal", "ku", "han"], "correct_order": [0, 1, 2, 3], "translation": "El niño come" } ``` --- #### 2.3. Error Detection (Detección de Errores) **ID:** `error_detection` **Descripción:** Identificar el error gramatical en la oración **Estructura:** ```json { "sentence": "Le paal ku hano", "error_position": 3, "error_type": "verb_conjugation", "correction": "hant" } ``` --- #### 2.4. Sentence Transformation (Transformación) **ID:** `sentence_transformation` **Descripción:** Transformar oración (afirmativa → negativa, etc.) **Estructura:** ```json { "original": "Kin han", "transform_to": "negative", "correct_answer": "Ma' kin hant" } ``` --- #### 2.5. Pronoun Selection (Selección de Pronombre) **ID:** `pronoun_selection` **Descripción:** Elegir el pronombre correcto **Estructura:** ```json { "sentence": "___ ku han", "context": "Él come", "options": ["Teen", "Le", "Tech"], "correct_answer": "Le" } ``` --- #### 2.6. Possessive Forms (Formas Posesivas) **ID:** `possessive_forms` **Descripción:** Construir forma posesiva correcta **Estructura:** ```json { "noun": "nah", "owner": "first_singular", "correct_answer": "in nah", "translation": "mi casa" } ``` --- #### 2.7. Pluralization (Pluralización) **ID:** `pluralization` **Descripción:** Convertir palabra a plural **Estructura:** ```json { "singular": "paal", "correct_plural": "paalal", "translation": "niños" } ``` --- #### 2.8. Aspect Markers (Marcadores de Aspecto) **ID:** `aspect_markers` **Descripción:** Identificar/usar marcador de aspecto correcto **Estructura:** ```json { "sentence_template": "___ han", "aspect": "progressive", "correct_marker": "táan", "complete_sentence": "Táan in hant" } ``` --- ### Categoría 3: Lectura (4 mecánicas) #### 3.1. Reading Comprehension (Comprensión Lectora) **ID:** `reading_comprehension` **Descripción:** Responder preguntas sobre un texto **Estructura:** ```json { "text": "Le ch'upalo'ob ku bin xíimbal ti' le k'áaxo'... (300 palabras)", "questions": [ { "id": 1, "question": "¿A dónde van las niñas?", "type": "multiple_choice", "options": ["Al bosque", "A la milpa", "A la ciudad"], "correct_answer": "Al bosque" }, ... ] } ``` --- #### 3.2. True or False (Verdadero o Falso) **ID:** `true_or_false` **Descripción:** Determinar si afirmación sobre texto es verdadera **Estructura:** ```json { "text": "Le paal ku ts'aik ja' ti' le wakax", "statement": "El niño da agua a la vaca", "correct_answer": true } ``` --- #### 3.3. Inference (Inferencia) **ID:** `inference` **Descripción:** Inferir información implícita del texto **Estructura:** ```json { "text": "Le ch'upal ku yantal ti' le k'áan. U yich ku siis", "question": "¿Cómo se siente la niña?", "correct_answer": "cansada", "accept_synonyms": ["fatigada", "agotada"] } ``` --- #### 3.4. Sequence Ordering (Orden de Secuencia) **ID:** `sequence_ordering` **Descripción:** Ordenar eventos de una narrativa **Estructura:** ```json { "text": "Historia larga...", "events": [ "El niño fue al cenote", "Encontró una tortuga", "La llevó a su casa", "La liberó en el río" ], "correct_order": [0, 1, 2, 3] } ``` --- ### Categoría 4: Escritura (4 mecánicas) #### 4.1. Free Writing (Escritura Libre) **ID:** `free_writing` **Descripción:** Escribir 2-3 oraciones sobre un tema **Estructura:** ```json { "prompt": "Describe tu familia en maya", "min_words": 15, "max_words": 50, "rubric": { "grammar": 30, "vocabulary": 30, "coherence": 40 } } ``` **Nota:** Requiere revisión manual o AI --- #### 4.2. Sentence Completion (Completar Oración) **ID:** `sentence_completion` **Descripción:** Completar oración con coherencia **Estructura:** ```json { "prompt": "Le paal ku bin ti'...", "correct_answers": [ "le naj", "u nah", "le k'aax" ], "min_words": 2 } ``` --- #### 4.3. Translation (Traducción) **ID:** `translation` **Descripción:** Traducir oración de español a maya **Estructura:** ```json { "spanish": "El niño está comiendo tortillas", "correct_maya": "Le paal táan u hantik waaj", "accept_variations": [ "Le paal ku hantik waaj", "Táan u hantik waaj le paalo'" ] } ``` --- #### 4.4. Dictation (Dictado) **ID:** `dictation` **Descripción:** Escribir lo que se escucha en audio **Estructura:** ```json { "audio_url": "/audio/sentence_123.mp3", "correct_text": "Le paal ku bin ti' le k'aax", "accept_minor_errors": true, "max_errors_allowed": 2 } ``` --- ### Categoría 5: Audio (3 mecánicas) #### 5.1. Listening Comprehension (Comprensión Auditiva) **ID:** `listening_comprehension` **Descripción:** Responder preguntas sobre audio **Estructura:** ```json { "audio_url": "/audio/conversation_maya.mp3", "transcript": "...", "questions": [ { "question": "¿De qué hablan?", "type": "multiple_choice", "options": [...], "correct_answer": "..." } ] } ``` --- #### 5.2. Audio Matching (Emparejar Audio) **ID:** `audio_matching` **Descripción:** Emparejar audio con texto/imagen **Estructura:** ```json { "audios": [ { "id": 1, "url": "/audio/word1.mp3" }, { "id": 2, "url": "/audio/word2.mp3" } ], "texts": [ { "id": "a", "text": "k'áak'" }, { "id": "b", "text": "ha'" } ], "correct_pairs": [ { "audio": 1, "text": "a" }, { "audio": 2, "text": "b" } ] } ``` --- #### 5.3. Tone Recognition (Reconocimiento de Tonos) **ID:** `tone_recognition` **Descripción:** Identificar tono glotal correcto **Estructura:** ```json { "audio_url": "/audio/kaak_vs_kak.mp3", "question": "¿La palabra tiene glotal (') o no?", "correct_answer": "yes_glottal", "word_written": "k'áak'" } ``` --- ### Categoría 6: Pronunciación (2 mecánicas) #### 6.1. Speech Recording (Grabación de Voz) **ID:** `speech_recording` **Descripción:** Grabar pronunciación de palabra/frase **Estructura:** ```json { "prompt": "Pronuncia: 'K'aaba' in k'aaba' Pedro'", "reference_audio_url": "/audio/reference_pedro.mp3", "evaluation_criteria": { "glottal_stops": true, "tones": true, "clarity": true } } ``` **Nota:** Requiere evaluación con Speech Recognition AI --- #### 6.2. Pronunciation Comparison (Comparación) **ID:** `pronunciation_comparison` **Descripción:** Escuchar dos pronunciaciones y elegir correcta **Estructura:** ```json { "word": "k'áak'", "audio_option_a": "/audio/correct_kaak.mp3", "audio_option_b": "/audio/incorrect_kaak.mp3", "correct_option": "a" } ``` --- ### Categoría 7: Cultura (4 mecánicas) #### 7.1. Cultural Context (Contexto Cultural) **ID:** `cultural_context` **Descripción:** Preguntas sobre cultura maya **Estructura:** ```json { "question": "¿Qué significa 'Halach Uinic'?", "type": "multiple_choice", "options": [ "Sacerdote", "Gobernante", "Guerrero", "Campesino" ], "correct_answer": "Gobernante" } ``` --- #### 7.2. Historical Timeline (Línea de Tiempo) **ID:** `historical_timeline` **Descripción:** Ordenar eventos históricos mayas **Estructura:** ```json { "events": [ "Período Preclásico", "Período Clásico", "Período Posclásico" ], "correct_order": [0, 1, 2] } ``` --- #### 7.3. Cultural Artifact (Artefacto Cultural) **ID:** `cultural_artifact` **Descripción:** Identificar artefacto maya **Estructura:** ```json { "image_url": "/images/estela_maya.jpg", "question": "¿Qué es este objeto?", "correct_answer": "Estela", "additional_info": "Las estelas registraban eventos importantes" } ``` --- #### 7.4. Traditional Practice (Práctica Tradicional) **ID:** `traditional_practice` **Descripción:** Preguntas sobre prácticas tradicionales **Estructura:** ```json { "practice": "Ha'nal Pixan", "question": "¿Cuándo se celebra Ha'nal Pixan?", "type": "multiple_choice", "options": ["Enero", "Abril", "Octubre-Noviembre", "Diciembre"], "correct_answer": "Octubre-Noviembre" } ``` --- ## 📋 Formatos de Respuesta por Tipo de Ejercicio Esta sección documenta los formatos de respuesta (DTOs) específicos para ejercicios que requieren validadores personalizados. ### Módulo 2: Comprensión Inferencial #### Detective Textual (Conexión de Evidencias) **Formato DTO (actualizado 2025-11-19):** ```json { "connections": [ { "from": "evidence-1", "to": "evidence-2", "relationship": "Ambos documentos describen las propiedades del radio" }, { "from": "evidence-1", "to": "evidence-3", "relationship": "El cuaderno de laboratorio confirma los experimentos del artículo" } ] } ``` **Criterios de Validación:** - Valida pares `from`-`to` correctos (orden flexible) - Verifica que `relationship` contenga keywords requeridos (threshold: 50%) - Permite crédito parcial por conexiones correctas - Score proporcional: `(conexiones correctas / total esperadas) × max_points` **Validador DB:** `educational_content.validate_detective_connections()` **Ejemplo de respuesta:** ```json { "is_correct": false, "score": 50, "feedback": "1 de 2 conexiones correctas. Revisa la relación entre evidencia-1 y evidencia-3.", "details": { "correctCount": 1, "totalExpected": 2, "correctConnections": [{"from": "evidence-1", "to": "evidence-2"}], "incorrectConnections": [{"from": "evidence-1", "to": "evidence-3"}] } } ``` --- #### Predicción Narrativa (Escenarios Múltiples) **Formato DTO (actualizado 2025-11-19):** ```json { "scenarios": { "scenario-1": "prediction-a", "scenario-2": "prediction-c", "scenario-3": "prediction-b", "scenario-4": "prediction-d" } } ``` **Criterios de Validación:** - Compara predicción seleccionada por escenario (exacta) - Proporciona explicación para cada respuesta incorrecta - Score proporcional: `(escenarios correctos / total) × max_points` - Permite crédito parcial por escenarios correctos **Validador DB:** `educational_content.validate_prediction_scenarios()` **Ejemplo de respuesta:** ```json { "is_correct": false, "score": 75, "feedback": "3 de 4 predicciones correctas. Revisa el escenario 2.", "details": { "correctCount": 3, "totalScenarios": 4, "correct": ["scenario-1", "scenario-3", "scenario-4"], "incorrect": [ { "scenario": "scenario-2", "submitted": "prediction-c", "correct": "prediction-b", "explanation": "El contexto histórico sugiere que..." } ] } } ``` --- #### Causa-Efecto (Construcción de Hipótesis - Matching) **Formato DTO (actualizado 2025-11-19):** ```json { "causes": { "cause-1": ["consequence-a", "consequence-b"], "cause-2": ["consequence-c"], "cause-3": ["consequence-d", "consequence-e", "consequence-f"] } } ``` **Criterios de Validación:** - Valida arrays de consecuencias por causa - Orden flexible por defecto (`strictOrder: false`) - Permite crédito parcial por matches correctos (`allowPartialMatches: true`) - Score proporcional: `(consecuencias correctas / total) × max_points` - Feedback detallado por causa **Validador DB:** `educational_content.validate_cause_effect_matching()` **Ejemplo de respuesta:** ```json { "is_correct": false, "score": 83, "feedback": "5 de 6 consecuencias asignadas correctamente. Revisa la causa-1.", "details": { "correctCount": 5, "totalCount": 6, "causeResults": { "cause-1": { "correct": ["consequence-a"], "incorrect": ["consequence-b"], "missing": [], "extra": [] }, "cause-2": {"correct": ["consequence-c"]}, "cause-3": {"correct": ["consequence-d", "consequence-e", "consequence-f"]} } } } ``` --- ## 📅 Historial de Cambios - Formatos DTO ### v2.1 (2025-11-19) - FE-059: Formatos Extendidos **Agregados:** - Formato de conexiones para `detective_textual` - Formato de escenarios para `prediccion_narrativa` - Formato de matching para `causa_efecto` (vía `construccion_hipotesis`) **Razón:** Discrepancias entre implementación frontend y especificaciones originales de base de datos **Decisión:** Propuesta 1 - Extender base de datos con nuevos validadores (vs. Propuesta 2 - reescribir frontend) **Implementación:** - **DB-117:** Creación de validadores SQL - **DB-123:** Actualización de configuraciones - **FE-059:** Especificaciones SQL y seeds de testing **Documentación:** `orchestration/HANDOFF-FE-059-TO-DB.md` **Beneficios:** - Frontend mantiene mecánicas más atractivas (drag & drop, conexiones visuales) - Mejor experiencia de usuario - Ahorro de tiempo: 4-6h (DB) vs 12-16h (Frontend completo) - Validación más robusta con feedback detallado --- ## 💼 Casos de Uso ### CU-EDU-001-001: Resolver Ejercicio Multiple Choice **Actor:** Estudiante **Precondiciones:** - Usuario autenticado - Ejercicio asignado o disponible **Flujo Principal:** 1. Usuario selecciona ejercicio de vocabulario (multiple_choice) 2. Sistema muestra: - Pregunta: "¿Qué significa 'k'áak''?" - 4 opciones: A) Fuego, B) Agua, C) Tierra, D) Aire 3. Usuario selecciona opción "A" 4. Usuario presiona "Verificar" 5. Sistema valida: ```typescript const correct = userAnswer === "a"; // true ``` 6. Sistema muestra: - ✅ "¡Correcto!" - Otorga 15 XP - Otorga 5 ML Coins 7. Sistema registra intento en `exercise_attempts` **Postcondiciones:** - Ejercicio marcado como completado - XP y ML Coins acreditados - Progress tracking actualizado --- ### CU-EDU-001-002: Usar Comodín "Pista" en Ejercicio **Actor:** Estudiante **Precondiciones:** - Usuario en ejercicio activo - Usuario tiene pistas disponibles **Flujo Principal:** 1. Usuario intenta ejercicio de gramática (verb_conjugation) 2. Usuario no sabe la respuesta 3. Usuario presiona "💡 Usar Pista" (tiene 5 disponibles) 4. Sistema: - Deduce 1 pista del inventario - Muestra pista #1: "Este verbo es irregular en presente" 5. Usuario intenta responder, falla 6. Usuario presiona "💡 Usar Pista" nuevamente 7. Sistema muestra pista #2: "El marcador de aspecto es 'táan'" 8. Usuario intenta y acierta 9. Sistema otorga XP completo (sin penalización) **Postcondiciones:** - 2 pistas usadas - Ejercicio completado - XP otorgado --- ## 🔒 Consideraciones de Seguridad ### 1. Validación de Respuestas | Riesgo | Mitigación | |--------|------------| | **Manipulación de respuestas en frontend** | Validación SIEMPRE en backend | | **Timing attacks (ver respuesta en código)** | Answer key nunca enviado al frontend | | **Bypass de límites de intentos** | Validación en DB con triggers | ### 2. Código Backend ```typescript // ❌ NUNCA enviar answer_key al frontend // ✅ Solo enviar después de validar async getExercise(exerciseId: string) { const exercise = await this.exerciseRepo.findOne(exerciseId); // Remover answer_key antes de enviar const { answer_key, ...exerciseForFrontend } = exercise; return exerciseForFrontend; } async submitAnswer(userId: string, exerciseId: string, answer: any) { // Obtener answer_key en backend const exercise = await this.exerciseRepo.findOne(exerciseId); // Validar según mecánica const isCorrect = this.validateAnswer(exercise.mechanic, answer, exercise.answer_key); return { correct: isCorrect }; } ``` --- ## ✅ Criterios de Aceptación ### CA-EDU-001-001: Estructura de Ejercicios - [ ] Cada ejercicio tiene campo `mechanic` (ENUM con 31 valores) - [ ] Contenido se almacena en JSONB flexible - [ ] Estructura de contenido validada según mecánica - [ ] Answer key nunca se expone en frontend ### CA-EDU-001-002: Validación de Respuestas - [ ] Cada mecánica tiene lógica de validación específica - [ ] Validación ocurre en backend - [ ] Respuestas con variaciones aceptadas se reconocen - [ ] Feedback específico por mecánica ### CA-EDU-001-003: Integración con Gamificación - [ ] Completar ejercicio otorga XP según dificultad - [ ] Otorga ML Coins - [ ] Puede desbloquear achievements - [ ] Comodines funcionan en ejercicios elegibles ### CA-EDU-001-004: Sistema de Hints - [ ] Hasta 3 hints por ejercicio - [ ] Hints progresivos (más específicos cada vez) - [ ] Usar hint deduce del inventario - [ ] Hints almacenados en campo `hints` (JSONB array) --- ## 🧪 Testing ### Test Case 1: Validar Respuesta Correcta (Multiple Choice) ```typescript test('Multiple choice exercise validates correct answer', async () => { // Arrange const exercise = await createExercise({ mechanic: 'multiple_choice', content: { question: "¿Qué significa 'k'áak''?", options: [ { id: 'a', text: 'Fuego' }, { id: 'b', text: 'Agua' }, { id: 'c', text: 'Tierra' }, { id: 'd', text: 'Aire' } ] }, answer_key: { correct_answer: 'a' } }); const user = await createUser(); // Act const result = await exerciseService.submitAnswer( user.id, exercise.id, { selected: 'a' } ); // Assert expect(result.correct).toBe(true); expect(result.xp_earned).toBeGreaterThan(0); }); ``` ### Test Case 2: Validar con Variaciones (Fill in Blank) ```typescript test('Fill in blank accepts valid variations', async () => { const exercise = await createExercise({ mechanic: 'fill_in_blank', content: { sentence: "Le ___ ku ts'o'okol u k'áatik.", blank_position: 1 }, answer_key: { correct_answer: 'paal', accept_variations: ['paal', 'páal'] } }); // Probar con acento const result1 = await exerciseService.submitAnswer( user.id, exercise.id, { answer: 'páal' } ); expect(result1.correct).toBe(true); // Probar sin acento const result2 = await exerciseService.submitAnswer( user.id, exercise.id, { answer: 'paal' } ); expect(result2.correct).toBe(true); }); ``` --- ## 📊 Métricas y Análisis ### KPIs a Monitorear | Métrica | Cálculo | Objetivo | |---------|---------|----------| | **Tasa de éxito por mecánica** | `(aciertos / intentos) GROUP BY mechanic` | >60% | | **Mecánicas más difíciles** | Mecánicas con menor tasa de éxito | Ajustar dificultad | | **Uso de hints por mecánica** | Promedio de hints usados | Identificar mecánicas confusas | | **Tiempo promedio por mecánica** | `AVG(time_to_complete) GROUP BY mechanic` | Balancear tiempos | --- ## 🔗 Referencias Adicionales ### Documentación Relacionada - [ET-EDU-001: Implementación de Mecánicas](../../02-especificaciones-tecnicas/03-contenido-educativo/ET-EDU-001-mecanicas-ejercicios.md) - [RF-EDU-002: Niveles de Dificultad](./RF-EDU-002-niveles-dificultad.md) - [RF-PRG-001: Tracking de Progreso](../04-progreso-seguimiento/RF-PRG-001-tracking-progreso.md) ### Referencias Pedagógicas - Anderson, L. W., & Krathwohl, D. R. (2001). "A Taxonomy for Learning, Teaching, and Assessing" - Duolingo Research: "Exercise Type Effectiveness Study" (2019) --- ## 📅 Historial de Cambios | Versión | Fecha | Autor | Cambios | |---------|-------|-------|---------| | 1.0 | 2025-11-07 | Database Team | Creación del documento | | 2.0 | 2025-11-11 | Database Team | **Reconciliación:** Actualizado ENUM canónico de exercise_mechanic a exercise_type. Documentado sistema de mapeo a categorías pedagógicas. 13 GAPs identificados para futuras implementaciones. Sistema dual con 35 implementaciones GAMILIT mapeadas a 7 categorías. | --- **Nota v2.0:** Este documento fue actualizado para reflejar la implementación real del sistema (DB-110, DB-111, DB-112). ENUM canónico actualizado a `exercise_type` (35 valores GAMILIT) con mapeo a categorías pedagógicas universales mediante tabla `exercise_mechanic_mapping`. Ver ET-EDU-001 v2.0 y ADR-008 para detalles técnicos. --- **Documento:** `docs/01-fase-alcance-inicial/EAI-002-actividades/requerimientos/RF-EDU-001-mecanicas-ejercicios.md` **Propósito:** Requerimientos funcionales de las 35 implementaciones GAMILIT + sistema de mapeo pedagógico **Audiencia:** Product Owner, Content Team, Pedagogical Team, Developers