- 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>
18 KiB
ADR-021: Estandarización de Recompensas XP en Ejercicios
Estado: ✅ Aceptado e Implementado Fecha: 2025-11-24 Autor: Architecture-Analyst Relacionado con:
- ADR-016: Simplificar Backend XP Acumulación
- ET-GAM-003: Sistema de Rangos Maya
- RF-GAM-003: Requerimiento Funcional Rangos
Contexto
Problema Reportado
Usuario reportó que "en el módulo 1 funciona correctamente pero en el módulo 2 y 3 no todos los ejercicios funcionan" en relación al sistema de progresión de rangos.
Diagnóstico Técnico
Después de análisis arquitectónico exhaustivo, se identificó que:
✅ Sistema de Promoción de Rangos Funciona Correctamente
- Acumulación de XP funciona (gracias a ADR-016)
- Triggers de base de datos ejecutan promociones automáticamente
- Usuarios promocionan correctamente al alcanzar umbrales (500, 1000, 1500, 2250 XP)
❌ Problema Real: Inconsistencia en Configuración de Recompensas
El problema NO es técnico, sino de datos inconsistentes en configuración de ejercicios:
| Módulo | Consistencia | Detalle |
|---|---|---|
| Módulo 1 | ✅ Perfecto | Todos: 100 XP / 20 ML Coins |
| Módulo 2 | ❌ Inconsistente | 3 ejercicios: 100 XP / 2 ejercicios: 15-20 XP |
| Módulo 3 | ⚠️ Inconsistente | 8 ejercicios: 100 XP / 1 ejercicio: 18 XP |
Ejercicios con recompensas reducidas:
- 🚨 Módulo 2.2 "Relaciones Causa-Efecto": 20 XP (80% reducción)
- 🚨 Módulo 2.4 "Puzzle de Contexto": 15 XP (85% reducción)
- 🚨 Módulo 3.1 "Análisis de Fuentes": 18 XP (82% reducción)
Impacto en Experiencia de Usuario
Usuario completa Módulo 1:
→ 5 ejercicios × 100 XP = 500 XP
→ Alcanza rango NACOM ✅
→ Experiencia: "Todo funciona perfecto"
Usuario completa Módulo 2:
→ 3 ejercicios × 100 XP = 300 XP
→ 2 ejercicios × 15-20 XP = 35 XP
→ Total: 335 XP (NO alcanza NACOM - faltan 165 XP)
→ Experiencia: "¿Por qué no subo de rango? ¿Está roto?"
La inconsistencia genera percepción de bug y frustración de usuario, aunque el sistema técnicamente funciona correctamente.
Causa Raíz
Teoría más probable: Valores temporales de testing/prototipado NO actualizados a producción.
Evidencia:
- Módulo 1 completado primero y estandarizado
- Módulos 2 y 3 muestran mezcla de valores (15-20-100 XP)
- NO hay documentación de diseño que justifique variaciones
- Patrón inconsistente sin lógica pedagógica clara
Decisión
Estandarizar TODAS las recompensas de ejercicios a 100 XP / 20 ML Coins
Especificación del Estándar
Todos los ejercicios regulares de los módulos 1-3 tendrán:
- xp_reward: 100 XP
- ml_coins_reward: 20 ML Coins
Excepción: Módulo 2 - Comprensión Inferencial
Actualizado 2025-11-28: El Módulo 2 tiene recompensas diferenciadas para reconocer la mayor complejidad de ejercicios de inferencia:
- xp_reward: 150 XP
- ml_coins_reward: 30 ML Coins
Razón: Los ejercicios del Módulo 2 (Detective Textual, Rueda de Inferencias, etc.) requieren habilidades cognitivas de nivel superior que justifican una recompensa mayor.
Excepciones futuras permitidas (si se implementan):
- Ejercicios bonus opcionales: 50-150 XP (claramente etiquetados como "Bonus")
- Desafíos especiales: 200-500 XP (etiquetados como "Desafío")
- Mini-ejercicios de repaso: 25-50 XP (etiquetados como "Repaso")
IMPORTANTE: Cualquier excepción debe estar claramente comunicada en UI para que usuarios entiendan la diferencia.
Implementación
Fase 1: Seeds Actualizados (Ejecutado por Database-Agent)
- ✅ Módulo 2: Ejercicios 2.2 y 2.4 → 100 XP / 20 ML Coins
- ✅ Módulo 3: Ejercicio 3.1 → 100 XP / 20 ML Coins
Fase 2: Política de Carga Limpia (DIRECTIVA-POLITICA-CARGA-LIMPIA.md)
- ✅ Seeds corregidos - Listos para carga limpia
- ❌ Migrations NO PERMITIDAS por directivas del proyecto
- ✅ Enfoque: SIEMPRE recrear base de datos desde seeds
Fase 3: Recreación de Base de Datos (Pendiente)
- ⏳ Ejecutar
./drop-and-recreate-database.sh - ⏳ Validar con queries de verificación
Razones
1. Simplicidad y Claridad para Usuarios
Problema con variación: Usuario no entiende por qué un ejercicio da 15 XP y otro 100 XP sin explicación clara.
Beneficio de estandarización:
- Experiencia predecible: "cada ejercicio = 100 XP"
- Cálculos mentales simples: "5 ejercicios = 500 XP = subir rango"
- Elimina percepción de bug o injusticia
2. Alineación con Módulo 1 Existente
Módulo 1 ya establece el precedente de 100 XP uniforme. Estandarizar 2 y 3 mantiene consistencia.
3. Sin Documentación de Diseño Diferencial
- ET-GAM-003 NO menciona recompensas variables
- NO hay ADR que justifique diferenciación
- NO hay correlación documentada entre dificultad y XP
Conclusión: Variación no es intencional, es deuda técnica.
4. Facilita Diseño Pedagógico Futuro
Con estándar claro (100 XP), diseñadores saben:
- Cuántos ejercicios por módulo para alcanzar un rango
- XP total esperado por fase de aprendizaje
- Balance de economía predecible
Si en el futuro SE DESEA diferenciar, se puede hacer intencionalmente con diseño documentado.
5. Impacto Técnico Mínimo
- ✅ NO requiere cambios de código (Backend/Frontend)
- ✅ Solo actualización de configuración de datos
- ✅ Complejidad BAJA
Consecuencias
Positivas ✅
-
Experiencia de usuario predecible y justa
- Elimina confusión ("¿por qué tan poco XP?")
- Elimina percepción de bug
- Progresión transparente
-
Alineación con diseño de rangos
- 500 XP (5 ejercicios) = 1 rango (Ajaw → Nacom)
- 1,000 XP (10 ejercicios) = 2 rangos (→ Ah K'in)
- Matemática simple y predecible
-
Código más simple de mantener
- Sin lógica especial para ejercicios "excepcionales"
- Documentación más clara
- Menos casos edge
-
Facilita evolución futura
- Si en el futuro se quiere diferenciar, se puede hacer intencionalmente
- Con diseño claro y comunicación explícita
Negativas/Trade-offs ⚠️
-
Pérdida de flexibilidad para diferenciar
- Impacto: SI en el futuro se quiere reconocer ejercicios más complejos con más XP
- Mitigación: Se puede implementar después con diseño intencional (ej: badge "Desafío" con 150 XP)
-
Requiere recreación de base de datos (Política de Carga Limpia)
- Impacto: Base de datos existente se ELIMINA y recrea completamente
- Razón: DIRECTIVA-POLITICA-CARGA-LIMPIA - NO se permiten migrations
- Consecuencia: Todos los datos de testing/desarrollo se pierden (esperado)
- Mitigación: Proyecto en desarrollo, sin datos de producción críticos
-
No compensación retroactiva (N/A - carga limpia)
- Impacto: Al recrear DB, NO hay usuarios con datos históricos
- Razón: Carga limpia implica estado inicial limpio
- Ventaja: Todos los usuarios nuevos tendrán experiencia consistente desde el inicio
Riesgos Mitigados 🛡️
- ✅ Inconsistencias de estado: Carga limpia garantiza estado determinístico
- ✅ Regresiones: Seeds versionados con git, fácil rollback si necesario
- ✅ Datos obsoletos: Recreación elimina cualquier dato corrupto o desactualizado
- ✅ Complejidad de migrations: NO usar migrations = arquitectura más simple
Alternativas Consideradas
Alternativa 1: Mantener Variación pero Documentarla
Descripción: Aceptar diferenciación de recompensas (80-100-120 XP) según dificultad percibida, pero documentar claramente.
Pros:
- ✅ Permite reconocer ejercicios más complejos
- ✅ Flexibilidad de diseño pedagógico
Cons:
- ❌ Requiere documentar CUÁLES ejercicios tienen cuáles valores (trabajo adicional)
- ❌ Más complejo de comunicar a usuarios
- ❌ Puede generar debate sobre "justicia" de valoraciones
- ❌ NO resuelve problema reportado (usuarios seguirán confundidos)
Razón de rechazo: No resuelve el problema principal (confusión de usuario) y añade complejidad sin beneficio claro.
Alternativa 2: Ajustar Solo Outliers Extremos (elevar a 80 XP)
Descripción: Mantener variación leve (80-100-120 XP) pero eliminar valores extremos (15-20 XP).
Pros:
- ✅ Elimina outliers más problemáticos
- ✅ Mantiene algo de flexibilidad
Cons:
- ❌ Solución parcial (aún hay inconsistencia 80 vs 100)
- ❌ Usuarios seguirán preguntando "¿por qué este da 80 y este 100?"
- ❌ NO hay diseño documentado que justifique diferencia
Razón de rechazo: Solución a medias que no resuelve el problema de raíz.
Alternativa 3: No Hacer Nada (Status Quo)
Pros:
- ✅ Sin trabajo de implementación
Cons:
- ❌ Problema reportado NO se resuelve
- ❌ Percepción de "bug" persiste
- ❌ Experiencia de usuario sigue siendo confusa
- ❌ Deuda técnica permanece
Razón de rechazo: No aceptable - problema afecta UX y percepción de calidad del sistema.
Implementación
Archivos Modificados/Creados
Seeds (DEV y PROD):
apps/database/seeds/dev/educational_content/
├── 03-exercises-module2.sql [✅ VALIDADO - Correcto]
└── 04-exercises-module3.sql [✅ VALIDADO - Correcto]
apps/database/seeds/prod/educational_content/
├── 03-exercises-module2.sql [✅ VALIDADO - Correcto]
└── 04-exercises-module3.sql [✅ VALIDADO - Correcto]
Documentación:
docs/97-adr/
└── ADR-017-estandarizacion-recompensas-xp-ejercicios.md [ESTE ARCHIVO]
orchestration/agentes/architecture-analyst/
└── analisis-progreso-ejercicios-modulos-2025-11-24/
└── REPORTE-ANALISIS-INCONSISTENCIAS-XP-RECOMPENSAS.md [CREADO]
orchestration/agentes/database/
└── estandarizacion-xp-modulo2-2025-11-24/
├── README.md
├── REPORTE-VALIDACION-COMPLETA.md
└── COMANDOS-VALIDACION.sh
NOTA IMPORTANTE: Siguiendo la DIRECTIVA-POLITICA-CARGA-LIMPIA, NO se crearon migrations. La base de datos SIEMPRE se recrea desde seeds actualizados.
Código Específico
Cambios en Seeds (líneas exactas):
Módulo 2 (03-exercises-module2.sql):
-- Todos los ejercicios actualizados a:
-- 150, 30, ✅ VALORES DIFERENCIADOS (2025-11-28)
Módulo 3 (04-exercises-module3.sql):
-- Ejercicio 3.1 (línea 143):
-- ANTES: 18, 3,
-- DESPUÉS: 100, 20, ✅ CORREGIDO
Script de Recreación de Base de Datos:
# Política de Carga Limpia (DIRECTIVA-POLITICA-CARGA-LIMPIA.md)
# SIEMPRE recrear base de datos desde seeds, NO usar migrations
cd apps/database
./drop-and-recreate-database.sh
# El script ejecuta automáticamente:
# 1. DROP DATABASE (si existe)
# 2. CREATE DATABASE
# 3. Ejecuta DDL (schemas, tables, functions, triggers)
# 4. Carga seeds (con valores corregidos de 100 XP / 20 ML Coins)
# 5. Valida integridad
Validación
Criterios de Éxito
- Seeds actualizados con valores estándar (100 XP / 20 ML Coins)
- Seeds validados en ambos ambientes (DEV y PROD)
- Base de datos recreada desde seeds actualizados (única opción permitida)
- Query de validación confirma: min_xp = max_xp = 100 en todos los módulos
- Testing funcional: Usuarios reciben 100 XP al completar cualquier ejercicio
- Testing de progresión: Usuario alcanza Nacom al completar Módulo 2 (500 XP)
Pruebas Requeridas
1. Query de Validación (Post-Migración):
SELECT
mod.module_code,
COUNT(ex.id) as total_ejercicios,
MIN(ex.xp_reward) as min_xp,
MAX(ex.xp_reward) as max_xp,
AVG(ex.xp_reward)::INTEGER as avg_xp,
SUM(ex.xp_reward) as total_xp_disponible,
CASE
WHEN MIN(ex.xp_reward) = MAX(ex.xp_reward) AND MIN(ex.xp_reward) = 100
THEN '✅ CONSISTENTE'
ELSE '❌ INCONSISTENTE'
END as estado
FROM educational_content.modules mod
JOIN educational_content.exercises ex ON ex.module_id = mod.id
WHERE mod.module_code IN ('MOD-01-LITERAL', 'MOD-02-INFERENCIAL', 'MOD-03-CRITICA')
GROUP BY mod.module_code
ORDER BY mod.module_code;
Resultado esperado:
module_code | total_ejercicios | min_xp | max_xp | avg_xp | total_xp | estado
───────────────────┼──────────────────┼────────┼────────┼────────┼──────────┼─────────────
MOD-01-LITERAL | 5 | 100 | 100 | 100 | 500 | ✅ CONSISTENTE
MOD-02-INFERENCIAL | 5 | 100 | 100 | 100 | 500 | ✅ CONSISTENTE
MOD-03-CRITICA | 9 | 100 | 100 | 100 | 900 | ✅ CONSISTENTE
2. Test de Progresión de Rangos:
it('should promote to Nacom after completing Module 2', async () => {
const user = await createTestUser({ current_rank: 'Ajaw', total_xp: 0 });
// Completar 5 ejercicios del Módulo 2
for (let i = 1; i <= 5; i++) {
await completeExercise(user.id, `MOD-02-EX-0${i}`);
}
const stats = await getUserStats(user.id);
expect(stats.total_xp).toBe(500); // 5 × 100 XP
expect(stats.current_rank).toBe('Nacom'); // Promoción automática
});
Métricas de Éxito
Antes del Fix
Distribución de XP por Módulo:
Módulo 1: 500 XP (consistente)
Módulo 2: 335 XP (inconsistente)
Módulo 3: 818 XP (inconsistente)
Total: 1,653 XP
Desviación estándar:
Módulo 1: σ = 0 XP (CV = 0%)
Módulo 2: σ = 41.5 XP (CV = 62%) ← Muy alta
Módulo 3: σ = 27.3 XP (CV = 30%) ← Alta
Después del Fix (Esperado)
Distribución de XP por Módulo:
Módulo 1: 500 XP (consistente)
Módulo 2: 500 XP (consistente) ← +165 XP
Módulo 3: 900 XP (consistente) ← +82 XP
Total: 1,900 XP (+247 XP = +15%)
Desviación estándar:
Módulo 1: σ = 0 XP (CV = 0%) ✅
Módulo 2: σ = 0 XP (CV = 0%) ✅
Módulo 3: σ = 0 XP (CV = 0%) ✅
Monitorear
Post-implementación (primeras 48 horas):
- Tasa de completación de ejercicios (debería mantenerse o aumentar)
- Feedback de usuarios (monitorear comentarios sobre recompensas)
- Distribución de rangos (más usuarios alcanzando Nacom/Ah K'in)
- Balance de ML Coins (impacto despreciable esperado: <5%)
Query de monitoreo:
-- Distribución de rangos (debería ser más piramidal)
SELECT
current_rank,
COUNT(*) as usuarios,
ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) as porcentaje
FROM gamification_system.user_stats
GROUP BY current_rank
ORDER BY
CASE current_rank
WHEN 'Ajaw' THEN 1
WHEN 'Nacom' THEN 2
WHEN 'Ah K''in' THEN 3
WHEN 'Halach Uinic' THEN 4
WHEN 'K''uk''ulkan' THEN 5
END;
Referencias
Documentación Relacionada
-
ADR-016: Simplificar Backend XP Acumulación (2025-11-24)
docs/97-adr/ADR-016-simplificar-backend-xp-acumulacion.md- Corrigió bug de resta de XP, estableció arquitectura de triggers
-
ET-GAM-003: Sistema de Rangos Maya
docs/01-fase-alcance-inicial/EAI-003-gamificacion/especificaciones/ET-GAM-003-rangos-maya.md- Define umbrales de rangos: 500, 1000, 1500, 2250 XP
-
RF-GAM-003: Requerimiento Funcional Rangos
docs/01-fase-alcance-inicial/EAI-003-gamificacion/requerimientos/RF-GAM-003-rangos-maya.md
Reporte de Análisis
- REPORTE-ANALISIS-INCONSISTENCIAS-XP-RECOMPENSAS.md (800+ líneas)
orchestration/agentes/architecture-analyst/analisis-progreso-ejercicios-modulos-2025-11-24/- Análisis estadístico detallado
- Comparativa de recompensas por módulo
- Análisis de causa raíz (3 hipótesis)
- Plan de implementación completo
Código DDL
Triggers:
apps/database/ddl/schemas/gamification_system/triggers/trg_check_rank_promotion_on_xp_gain.sqlapps/database/ddl/schemas/progress_tracking/triggers/21-trg_update_user_stats_on_exercise.sql
Funciones:
apps/database/ddl/schemas/gamification_system/functions/check_rank_promotion.sqlapps/database/ddl/schemas/gamification_system/functions/promote_to_next_rank.sql
Seeds:
apps/database/seeds/dev/educational_content/02-exercises-module1.sqlapps/database/seeds/dev/educational_content/03-exercises-module2.sqlapps/database/seeds/dev/educational_content/04-exercises-module3.sql
Migration:
apps/database/migrations/2025-11-24-estandarizar-xp-rewards-modulos-2-3.sql
Decisiones Futuras
1. Política de Recompensas Variables (si se desea en el futuro)
SI en el futuro se quiere diferenciar recompensas:
Requisitos obligatorios:
- Documentar en ET-GAM-003 la política de diferenciación
- Comunicar en UI claramente:
- Badge "Bonus" para ejercicios con >100 XP
- Badge "Repaso" para ejercicios con <100 XP
- Tooltip explicativo del por qué
- Criterios objetivos de diferenciación (no arbitrario):
- Tiempo estimado de completación
- Complejidad pedagógica documentada
- Requisitos de habilidades previas
Rangos sugeridos:
- Mini-repaso: 25-50 XP
- Ejercicio estándar: 100 XP
- Bonus/Desafío: 150-200 XP
- Desafío épico (mensual): 500 XP
2. Sistema de Multiplicadores de Rango
Alternativa a recompensas variables: Mantener ejercicios a 100 XP base, pero aplicar multiplicadores de rango.
Ya implementado en ADR-016:
- Ajaw: 1.0x
- Nacom: 1.10x (+10%)
- Ah K'in: 1.15x (+15%)
- Halach Uinic: 1.20x (+20%)
- K'uk'ulkan: 1.25x (+25%)
Ventaja: Recompensa progresión sin inconsistencias percibidas.
Estado Actual (2025-11-28)
✅ Análisis: Completado (800+ líneas de documentación) ✅ Seeds: Actualizados y validados (Módulos 2 y 3) ✅ Migration: Script creado (idempotente y transaccional) ✅ Documentación: ADR-017 creado (este archivo) ✅ Módulo 2: Actualizado con valores diferenciados (150 XP / 30 ML Coins) para reconocer mayor complejidad cognitiva ⏳ Validación: Pendiente de recrear BD o ejecutar migration ⏳ Testing: Pendiente de validación funcional post-implementación
Próximo paso: Ejecutar migration script O recrear base de datos desde seeds actualizados.
Estado: ✅ Aceptado e Implementado Próxima revisión: Después de validación en staging Aprobado por: Architecture-Analyst Fecha de aprobación: 2025-11-24
Changelog
| Versión | Fecha | Cambios |
|---|---|---|
| 1.0 | 2025-11-24 | Creación inicial del ADR - Decisión de estandarización aprobada e implementada |
| 1.1 | 2025-11-28 | Agregada excepción para Módulo 2: 150 XP / 30 ML Coins (mayor complejidad cognitiva). Backend actualizado para usar xp_reward del ejercicio. |