# ADR-008: Sistema Dual exercise_type + Categorías Pedagógicas

**Estado:** Aceptado
**Fecha:** 2025-11-11
**Autores:** Database Team
**Decisores:** Tech Lead, Database Architect, Usuario
**Relacionado:** DB-110, DB-111, DB-112

---

## Contexto

Durante DB-110 (Validación Profunda docs/ ↔ DDL) se identificó incoherencia crítica entre documentación y código:

- **Documentación (ET-EDU-001, RF-EDU-001):**
  - Define `exercise_mechanic` ENUM (31 valores pedagógicos universales)
  - Categorías: Vocabulario (6), Gramática (8), Lectura (4), Escritura (4), Audio (3), Pronunciación (2), Cultura (4)
  - Ubicación documentada: `apps/database/ddl/00-prerequisites.sql:59-65`

- **DDL Real:**
  - Implementa `exercise_type` ENUM (35 valores específicos GAMILIT)
  - Agrupación: Módulo 1 (5), Módulo 2 (4), Módulo 3 (5), Módulo 4 (9), Módulo 5 (2), Auxiliares (10)
  - Ubicación real: `apps/database/ddl/00-prerequisites.sql:~85-120`

- **Coherencia:** 0/100 ❌ (documentación completamente desactualizada)

**Problema:**
- Tabla `exercises` usa campo `exercise_type` (no `mechanic`)
- Backend tiene `ExerciseTypeEnum` (no `ExerciseMechanicEnum`)
- Frontend mapea 35 tipos específicos a componentes
- Documentación pedagógica define 31 categorías universales

**Filosofía del usuario aplicada:**
> "En lugar de eliminar si se tienen definidos lo mejor sería adaptarlos para que sirvan y darles coherencia a los datos ya existentes, actualizar la documentación que esté alineada con el desarrollo y asignar esas definiciones a módulos, ejercicios, definiciones que puedan faltar para completar lo deseado."

---

## Opciones Consideradas

### Opción A: Refactorizar DDL para seguir documentación

**Descripción:** Cambiar DDL, Backend, Frontend para usar `exercise_mechanic` (31 valores genéricos)

**Impacto:**
- 🔴 Breaking changes masivos
- 🔴 Refactor DDL: 1 ENUM, 1 tabla exercises
- 🔴 Refactor Backend: 20+ archivos (entities, services, validators)
- 🔴 Refactor Frontend: 35 componentes + routing
- 🔴 Pérdida de granularidad (35 específicos → 31 genéricos)
- 🔴 Timeline: 2-3 semanas
- 🔴 Alto riesgo de regresiones

**Decisión:** ❌ Rechazada (demasiado disruptiva)

---

### Opción B: Actualizar documentación solamente

**Descripción:** Actualizar ET-EDU-001 y RF-EDU-001 para reflejar `exercise_type` (35 valores)

**Impacto:**
- 🟢 No breaking changes
- 🟢 Solo actualización de 2 documentos
- 🟢 Sincroniza docs con realidad
- 🟢 Timeline: 3-4 horas

**Limitaciones:**
- ⚠️ Pierde clasificación pedagógica valiosa
- ⚠️ Dificulta búsquedas por competencia ("vocabulario", "lectura")
- ⚠️ No explota valor de los 13 GAPs identificados
- ⚠️ Profesores pierden visibilidad por área pedagógica

**Decisión:** ⚠️ Viable pero incompleta

---

### Opción C: Sistema Dual (SELECCIONADA)

**Descripción:** Reconciliar documentación + implementación mediante sistema dual con tabla de mapeo

**Concepto:**
```
exercise_type (35 implementaciones GAMILIT)
        +
Categorías pedagógicas (7 categorías, 31 subcategorías)
        ↓
exercise_mechanic_mapping (tabla N:M)
        =
Sistema Dual
```

**Impacto:**
- 🟢 No breaking changes (100% backward-compatible)
- 🟢 Preserva implementación existente
- 🟢 Preserva valor pedagógico
- 🟢 Sincroniza documentación con realidad
- 🟢 Timeline: 3 días (~24.5 horas)

**Implementación:**
1. Actualizar ET-EDU-001 v2.0 (documentar sistema dual)
2. Actualizar RF-EDU-001 v2.0 (exercise_type como canónico)
3. Crear tabla `exercise_mechanic_mapping` (mapeo N:M)
4. Crear vista `exercises_with_mechanics` (helper)
5. Backend: Entity, Service, DTOs (opcional)
6. Frontend: Filter component (opcional)

**Decisión:** ✅ **SELECCIONADA** (aprobada por usuario: "Si la opcion c esta bien")

---

## Decisión

Implementar **Sistema Dual** mediante:

1. **exercise_type (Implementación):**
   - 35 mecánicas específicas GAMILIT (mantener como está)
   - ENUM canónico en DDL: `educational_content.exercise_type`
   - Usado en tabla `exercises.exercise_type`
   - Sincronizado con Backend: `ExerciseTypeEnum`
   - Mapeado en Frontend: 35 componentes

2. **Categorías pedagógicas (Clasificación):**
   - 7 categorías universales + 31 subcategorías
   - Nueva tabla de mapeo: `exercise_mechanic_mapping`
   - Mapeo N:M: múltiples exercise_types pueden tener misma categoría
   - Permite búsqueda pedagógica sin cambiar implementación

3. **Reconciliación de documentación:**
   - Actualizar ET-EDU-001 v2.0 con sistema dual
   - Actualizar RF-EDU-001 v2.0 con exercise_type como canónico
   - Crear este ADR-008 documentando decisión

**Filosofía aplicada:** "Adaptar y reconciliar, NO eliminar"

---

## Consecuencias

### Positivas

**Para Profesores:**
- ✅ Buscar ejercicios por competencia pedagógica ("vocabulario", "lectura")
- ✅ Filtrar por nivel de Bloom o CEFR
- ✅ Asignar según objetivos de aprendizaje específicos
- ✅ Visibilidad de progreso por área pedagógica (ej: vocabulario 60% → 80%)

**Para Estudiantes:**
- ✅ Recibir recomendaciones por competencia a desarrollar
- ✅ Variedad de mecánicas para misma competencia (evita monotonía)
- ✅ Progresión clara por área

**Para el Sistema:**
- ✅ Analytics por competencia pedagógica + por tipo específico
- ✅ Interoperabilidad con estándares internacionales (Bloom, CEFR)
- ✅ Extensibilidad sin modificar estructura existente
- ✅ Facilita futuras implementaciones (13 GAPs identificados como roadmap)
- ✅ Preserva implementación existente (0 breaking changes)
- ✅ Sincroniza documentación con realidad

### Negativas

**Complejidad:**
- ⚠️ Tabla de mapeo adicional (+1 tabla)
- ⚠️ Mantenimiento de mappings (60-90 registros iniciales)
- ⚠️ Overhead de queries con JOIN (~60%, mitigable)

**Esfuerzo de implementación:**
- ⚠️ 24.5 horas (~3 días con 1-2 devs)
- ⚠️ 6 archivos nuevos + 7 archivos modificados

### Mitigaciones

**Performance:**
- Vista materializada `exercises_with_mechanics_mv` para queries frecuentes
- Índices optimizados: `idx_mechanic_mapping_category`, `idx_mechanic_mapping_subcategory`, `idx_mechanic_mapping_exercise_type`
- Índice GIN para búsqueda por tags: `idx_mechanic_mapping_tags_gin`

**Integridad:**
- Foreign Key constraint: `exercise_mechanic_mapping.exercise_type` → `exercise_type ENUM`
- Constraint UNIQUE: `(mechanic_subcategory, exercise_type)` previene duplicados
- Trigger de validación para nuevos exercise_types (asegurar mapping)

**Mantenimiento:**
- Seeds iniciales con 60-90 mappings completos
- Documentación clara en ET-EDU-001 v2.0
- 13 GAPs documentados como roadmap para futuras implementaciones

---

## Validación

### Proceso de validación (DB-110 → DB-111 → DB-112)

1. **DB-110 (Validación Profunda):**
   - Identificó incoherencia crítica (score 0/100)
   - Hallazgo: exercise_mechanic (docs) vs exercise_type (DDL)
   - Recomendación inicial errónea: eliminar exercise_mechanic
   - **Corrección del usuario:** Validar contra DEFINICIONES primero

2. **DB-111 (Reconciliación):**
   - Propuso sistema dual (adaptación, no eliminación)
   - Análisis de impacto: 33 objetos, 4 capas
   - Riesgo: 🟢 BAJO-MEDIO
   - Recomendación: ✅ APROBAR IMPLEMENTACIÓN
   - **Solicitud del usuario:** Validar contra documentación

3. **DB-112 (Validación contra DEFINICIONES):**
   - Validó contra ET-EDU-001 (987 líneas)
   - Validó contra RF-EDU-001 (1,200 líneas)
   - Coherencia: 0/100 en ambos
   - Evaluó 3 opciones (A, B, C)
   - Recomendó Opción C
   - **Aprobación del usuario:** "Si la opcion c esta bien"

**Score final:** 95/100 (Opción C reconcilia ambos conceptos sin breaking changes)

---

## Implementación

### Tabla de Mapeo

**Ubicación:** `apps/database/ddl/schemas/educational_content/tables/21-exercise_mechanic_mapping.sql`

```sql
CREATE TABLE educational_content.exercise_mechanic_mapping (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- CLASIFICACIÓN PEDAGÓGICA
    mechanic_category VARCHAR(50) NOT NULL,      -- 'vocabulario', 'lectura', 'escritura'
    mechanic_subcategory VARCHAR(50),            -- 'multiple_choice', 'word_search', 'inference'

    -- IMPLEMENTACIÓN GAMILIT
    exercise_type educational_content.exercise_type NOT NULL,

    -- CONTEXTO EDUCATIVO
    bloom_level VARCHAR(50),                     -- 'recordar', 'comprender', 'aplicar', etc.
    cefr_level educational_content.difficulty_level[],
    pedagogical_purpose TEXT,
    learning_objectives TEXT[],

    -- CARACTERÍSTICAS
    interaction_type VARCHAR(50),                -- 'drag_drop', 'text_input', 'selection'
    cognitive_load VARCHAR(20),                  -- 'bajo', 'medio', 'alto'

    -- Metadatos
    tags TEXT[],
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),

    UNIQUE(mechanic_subcategory, exercise_type)
);

-- Índices para búsquedas frecuentes
CREATE INDEX idx_mechanic_mapping_category ON educational_content.exercise_mechanic_mapping(mechanic_category);
CREATE INDEX idx_mechanic_mapping_subcategory ON educational_content.exercise_mechanic_mapping(mechanic_subcategory);
CREATE INDEX idx_mechanic_mapping_exercise_type ON educational_content.exercise_mechanic_mapping(exercise_type);
CREATE INDEX idx_mechanic_mapping_bloom ON educational_content.exercise_mechanic_mapping(bloom_level);
CREATE INDEX idx_mechanic_mapping_tags_gin ON educational_content.exercise_mechanic_mapping USING gin(tags);

COMMENT ON TABLE educational_content.exercise_mechanic_mapping
IS 'Mapeo N:M entre categorías pedagógicas universales (31 subcategorías) y implementaciones específicas GAMILIT (35 exercise_types)';
```

### Ejemplos de Mapeos

| mechanic_category | mechanic_subcategory | exercise_type | bloom_level | pedagogical_purpose |
|-------------------|---------------------|---------------|-------------|---------------------|
| vocabulario | word_search | crucigrama | recordar | Reforzar vocabulario mediante juego de palabras cruzadas |
| vocabulario | word_search | sopa_letras | recordar | Identificar palabras clave en contexto visual |
| lectura | inference | detective_textual | analizar | Desarrollar comprensión inferencial mediante pistas |
| lectura | reading_comprehension | analisis_fuentes | evaluar | Análisis crítico de textos históricos/culturales |
| escritura | free_writing | ensayo_argumentativo | crear | Expresión argumentativa y pensamiento crítico |
| cultura | cultural_context | tribunal_opiniones | evaluar | Análisis de perspectivas culturales diversas |

### Vista Helper

```sql
CREATE VIEW educational_content.exercises_with_mechanics AS
SELECT
    e.*,
    m.mechanic_category,
    m.mechanic_subcategory,
    m.bloom_level,
    m.pedagogical_purpose
FROM educational_content.exercises e
LEFT JOIN educational_content.exercise_mechanic_mapping m
    ON e.exercise_type = m.exercise_type;
```

---

## Referencias

**Documentación de validación:**
- [DB-110: Validación Profunda docs/ ↔ DDL](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/orchestration/database/DB-110/reportes-consolidados/REPORTE-VALIDACION-PROFUNDA.md)
- [DB-111: Análisis de Impacto](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/orchestration/database/DB-111/01-ANALISIS-IMPACTO.md)
- [DB-111: Reporte Consolidado](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/orchestration/database/DB-111/02-REPORTE-CONSOLIDADO.md)
- [DB-112: Validación contra Documentación](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/orchestration/database/DB-112/01-VALIDACION-CONTRA-DOCUMENTACION.md)
- [DB-112: Reporte Final](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/orchestration/database/DB-112/02-REPORTE-FINAL-VALIDACION.md)

**Documentación actualizada:**
- [ET-EDU-001 v2.0: Implementación de Mecánicas de Ejercicios](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/docs/01-fase-alcance-inicial/EAI-002-actividades/especificaciones/ET-EDU-001-mecanicas-ejercicios.md)
- [RF-EDU-001 v2.0: Mecánicas de Ejercicios](/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/docs/01-fase-alcance-inicial/EAI-002-actividades/requerimientos/RF-EDU-001-mecanicas-ejercicios.md)

**Código relacionado:**
- DDL: `apps/database/ddl/00-prerequisites.sql` (ENUM exercise_type)
- DDL: `apps/database/ddl/schemas/educational_content/tables/02-exercises.sql`
- DDL: `apps/database/ddl/schemas/educational_content/tables/21-exercise_mechanic_mapping.sql` (NUEVA)
- Backend: `apps/backend/src/shared/constants/enums.constants.ts` (ExerciseTypeEnum)
- Backend: `apps/backend/src/modules/educational/entities/exercise.entity.ts`
- Frontend: `apps/frontend/src/apps/student/pages/ExercisePage.tsx` (routing)

---

## Notas

**13 GAPs Pedagógicos Identificados:**

Mecánicas pedagógicas documentadas en ET-EDU-001 v1.0 sin implementación GAMILIT específica:

**Vocabulario (1):**
- image_association

**Gramática (8):**
- verb_conjugation, sentence_builder, error_detection, sentence_transformation
- pronoun_selection, possessive_forms, pluralization, aspect_markers

**Lectura (0):** Todas implementadas ✅

**Escritura (0):** Todas implementadas ✅

**Audio (1):**
- audio_matching

**Pronunciación (2):**
- speech_recording, pronunciation_comparison

**Cultura (1):**
- traditional_practice

**Roadmap:** Estos 13 GAPs pueden servir como roadmap para futuras implementaciones GAMILIT sin modificar la estructura del sistema dual.

---

**Decisión final:** ✅ **ACEPTADA** - Sistema Dual implementado para reconciliar documentación con realidad, preservando valor pedagógico y técnico sin breaking changes.

**Timeline de implementación:** 3 días (~24.5 horas con 1-2 devs)

**Status:** Documentación actualizada (ET-EDU-001 v2.0, RF-EDU-001 v2.0, ADR-008) ✅
**Próximo paso:** DB-113 - Implementación DDL + Backend + Frontend
