- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
353 lines
14 KiB
Markdown
353 lines
14 KiB
Markdown
# 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
|