Cambios incluidos: - INDICE-DIRECTIVAS-WORKSPACE.yml actualizado - Perfiles de agentes: PERFIL-ML.md, PERFIL-SECURITY.md - Directivas SIMCO actualizadas: - SIMCO-ASIGNACION-PERFILES.md - SIMCO-CCA-SUBAGENTE.md - SIMCO-CONTEXT-ENGINEERING.md - SIMCO-CONTEXT-RESOLUTION.md - SIMCO-DELEGACION-PARALELA.md - Inventarios actualizados: DEVENV-MASTER, DEVENV-PORTS - Documentos de analisis agregados: - Analisis y planes de fix student portal - Analisis scripts BD - Analisis achievements, duplicados, gamification - Auditoria documentacion gamilit - Backlog discrepancias NEXUS - Planes maestros de resolucion - Reportes de ejecucion agregados - Knowledge base gamilit README actualizado - Referencia submodulo gamilit actualizada (commit beb94f7) Validaciones: - Plan validado contra directivas SIMCO-GIT - Dependencias verificadas - Build gamilit: EXITOSO
261 lines
8.8 KiB
Markdown
261 lines
8.8 KiB
Markdown
# FASE 4: VALIDACIÓN DE PLAN - DUPLICADOS ACHIEVEMENTS
|
|
|
|
**Fecha:** 2026-01-10
|
|
**Proyecto:** Gamilit
|
|
**Basado en:** PLAN-DUPLICADOS-ACHIEVEMENTS-2026-01-10.md
|
|
**Estado:** VALIDACIÓN COMPLETADA
|
|
|
|
---
|
|
|
|
## 1. HALLAZGO CRÍTICO: TRIPLE DISTRIBUCIÓN DE RECOMPENSAS
|
|
|
|
### 1.1 Descubrimiento
|
|
|
|
Se identificó que las recompensas de achievements se distribuyen **TRES VECES**:
|
|
|
|
| # | Momento | Función/Trigger | Da XP | Da Coins | Registra Trans. |
|
|
|---|---------|-----------------|-------|----------|-----------------|
|
|
| 1 | Desbloqueo | `check_and_grant_achievements` | ✅ | ✅ | ✅ |
|
|
| 2 | Auto-trigger | `fn_on_achievement_unlocked` (trigger) | ✅ | ✅ | ✅ |
|
|
| 3 | Reclamar | `claim_achievement_reward` | ✅ | ✅ | ✅ |
|
|
|
|
### 1.2 Flujo Actual (PROBLEMÁTICO)
|
|
|
|
```
|
|
Usuario completa misión
|
|
│
|
|
▼
|
|
grant_mission_completion_rewards()
|
|
│
|
|
├──► check_and_grant_achievements()
|
|
│ │
|
|
│ ├──► INSERT user_achievements (is_completed = true)
|
|
│ │ │
|
|
│ │ └──► [TRIGGER] fn_on_achievement_unlocked()
|
|
│ │ │
|
|
│ │ ├──► UPDATE user_stats (XP + Coins) ⚠️ PRIMER PAGO
|
|
│ │ └──► INSERT ml_coins_transactions
|
|
│ │
|
|
│ ├──► UPDATE user_stats (XP + Coins) ⚠️ SEGUNDO PAGO
|
|
│ └──► INSERT ml_coins_transactions
|
|
│
|
|
▼
|
|
Usuario hace click "Reclamar"
|
|
│
|
|
▼
|
|
claim_achievement_reward()
|
|
│
|
|
├──► UPDATE user_stats (XP + Coins) ⚠️ TERCER PAGO
|
|
└──► INSERT ml_coins_transactions
|
|
```
|
|
|
|
### 1.3 Impacto Económico
|
|
|
|
Si un achievement da 100 XP y 50 ML Coins:
|
|
- **Usuario recibe:** 300 XP y 150 ML Coins (3x lo esperado)
|
|
- **Inflación:** Sistema de economía completamente roto
|
|
|
|
---
|
|
|
|
## 2. VALIDACIÓN DE DEPENDENCIAS
|
|
|
|
### 2.1 achievementsAPI.ts
|
|
|
|
| Consumer | Archivo | Método Usado | Impacto de Deprecar |
|
|
|----------|---------|--------------|---------------------|
|
|
| Store | `achievementsStore.ts:16` | `getUserAchievements` | ⚠️ Requiere migrar a gamification.api |
|
|
| Test | `achievementsStore.test.ts` | Mock completo | 🟡 Actualizar mocks |
|
|
| Test | `DashboardIntegration.test.tsx` | Mock completo | 🟡 Actualizar mocks |
|
|
| Test | `AchievementsIntegration.test.tsx` | Mock completo | 🟡 Actualizar mocks |
|
|
|
|
**Conclusión:** El store usa `getUserAchievements` de achievementsAPI.ts. Al deprecar, debe migrarse a `gamificationApi.getUserAchievements`.
|
|
|
|
### 2.2 Root Hook /hooks/useAchievements.ts
|
|
|
|
| Consumer | Archivo | Impacto |
|
|
|----------|---------|---------|
|
|
| Ninguno | N/A | ✅ SAFE - No tiene importadores |
|
|
|
|
**Conclusión:** El hook raíz de 450 líneas NO está siendo usado. SAFE to deprecate.
|
|
|
|
### 2.3 gamificationApi.claimAchievement
|
|
|
|
| Consumer | Archivo | Línea | Impacto |
|
|
|----------|---------|-------|---------|
|
|
| AchievementsPage | `AchievementsPage.tsx` | 274 | 🟡 Depende del fix backend |
|
|
|
|
**Conclusión:** Solo un consumidor. Cambios en backend afectarán esta página.
|
|
|
|
### 2.4 check_and_grant_achievements SQL
|
|
|
|
| Consumer | Archivo | Línea | Contexto |
|
|
|----------|---------|-------|----------|
|
|
| `grant_mission_completion_rewards` | `06-update_mission_progress.sql` | 77 | Llamado al completar misión |
|
|
|
|
**Conclusión:** Esta función ES usada. Cambios deben ser cuidadosos.
|
|
|
|
### 2.5 Trigger fn_on_achievement_unlocked
|
|
|
|
| Tabla | Evento | Impacto |
|
|
|-------|--------|---------|
|
|
| `user_achievements` | INSERT or UPDATE (is_completed) | Activa distribución automática |
|
|
|
|
**Conclusión:** Este trigger ES la fuente de duplicación. Decisión arquitectónica requerida.
|
|
|
|
---
|
|
|
|
## 3. DECISIÓN ARQUITECTÓNICA REVISADA
|
|
|
|
### 3.1 Opción A: Auto-Earn (Recompensas Automáticas)
|
|
|
|
**Modelo:** Recompensas se dan automáticamente al desbloquear
|
|
|
|
**Cambios Requeridos:**
|
|
1. ✅ Mantener trigger `fn_on_achievement_unlocked`
|
|
2. ❌ Remover distribución de `check_and_grant_achievements`
|
|
3. ❌ Remover distribución de `claim_achievement_reward`
|
|
4. ⚠️ `claim_achievement_reward` solo marca flag `rewards_claimed`
|
|
|
|
**Pros:**
|
|
- Flujo más simple
|
|
- Usuario ve recompensas inmediatamente
|
|
|
|
**Cons:**
|
|
- Sin "ceremonia" de reclamar
|
|
- Menos engagement UX
|
|
|
|
### 3.2 Opción B: Claim-to-Earn (Reclamar para Ganar) - RECOMENDADA
|
|
|
|
**Modelo:** Recompensas solo se dan al hacer click "Reclamar"
|
|
|
|
**Cambios Requeridos:**
|
|
1. ❌ Desactivar trigger `fn_on_achievement_unlocked` (solo notificación, no rewards)
|
|
2. ❌ Remover distribución de `check_and_grant_achievements`
|
|
3. ✅ `claim_achievement_reward` es única fuente de rewards
|
|
|
|
**Pros:**
|
|
- UX de "reclamar" más satisfactoria
|
|
- Usuario tiene control
|
|
- Consistente con misiones y ejercicios
|
|
|
|
**Cons:**
|
|
- Más código para mantener
|
|
- Usuario podría olvidar reclamar
|
|
|
|
### 3.3 DECISIÓN: Opción B (Claim-to-Earn)
|
|
|
|
**Justificación:**
|
|
- Misiones ya usan modelo claim-to-earn (`mission-claim.service.ts`)
|
|
- Ejercicios usan modelo claim-to-earn (`exercise-rewards.service.ts`)
|
|
- Consistencia en toda la plataforma
|
|
|
|
---
|
|
|
|
## 4. PLAN REVISADO
|
|
|
|
### 4.1 Fase A: SQL (Base de Datos)
|
|
|
|
| Orden | Archivo | Cambio | Prioridad |
|
|
|-------|---------|--------|-----------|
|
|
| A.1 | `check_and_award_achievements.sql` | Remover UPDATE user_stats y INSERT ml_coins_transactions | 🔴 CRÍTICO |
|
|
| A.2 | `fn_on_achievement_unlocked` (trigger function) | Remover distribución de XP/Coins, mantener solo notificación | 🔴 CRÍTICO |
|
|
| A.3 | `claim_achievement_reward.sql` | ✅ Ya corregida - es la única fuente | ✅ LISTO |
|
|
|
|
### 4.2 Fase B: Backend (NestJS)
|
|
|
|
| Orden | Archivo | Cambio | Prioridad |
|
|
|-------|---------|--------|-----------|
|
|
| B.1 | `achievements.service.ts` | `claimRewards()` debe llamar SQL function | 🔴 CRÍTICO |
|
|
| B.2 | `achievements.controller.ts` | Actualizar response con xp/coins granted | 🟡 IMPORTANTE |
|
|
| B.3 | `admin-progress.service.ts` | Fix schema mismatch | 🟢 MENOR |
|
|
|
|
### 4.3 Fase C: Frontend (React)
|
|
|
|
| Orden | Archivo | Cambio | Prioridad |
|
|
|-------|---------|--------|-----------|
|
|
| C.1 | `achievementsStore.ts` | Migrar de achievementsAPI a gamificationApi | 🟡 IMPORTANTE |
|
|
| C.2 | `achievementsAPI.ts` | Deprecar métodos duplicados | 🟡 IMPORTANTE |
|
|
| C.3 | `/hooks/useAchievements.ts` | Agregar @deprecated notice | 🟢 MENOR |
|
|
|
|
---
|
|
|
|
## 5. ARCHIVOS A MODIFICAR (ACTUALIZADO)
|
|
|
|
### 5.1 Base de Datos
|
|
|
|
| Archivo | Acción | Líneas Afectadas |
|
|
|---------|--------|------------------|
|
|
| `check_and_award_achievements.sql` | Remover rewards distribution | 102-132 |
|
|
| `triggers/fn_on_achievement_unlocked.sql` | Remover rewards, mantener notificación | 19-87 |
|
|
|
|
### 5.2 Backend
|
|
|
|
| Archivo | Acción | Líneas Afectadas |
|
|
|---------|--------|------------------|
|
|
| `achievements.service.ts` | Llamar SQL function | 745-759 |
|
|
| `achievements.controller.ts` | Update response type | TBD |
|
|
| `admin-progress.service.ts` | Fix field names | TBD |
|
|
|
|
### 5.3 Frontend
|
|
|
|
| Archivo | Acción | Líneas Afectadas |
|
|
|---------|--------|------------------|
|
|
| `achievementsStore.ts` | Change import | 16 |
|
|
| `achievementsAPI.ts` | Add deprecation | Multiple |
|
|
| `/hooks/useAchievements.ts` | Add @deprecated | 1-20 |
|
|
|
|
---
|
|
|
|
## 6. TESTS AFECTADOS
|
|
|
|
| Test File | Cambio Requerido |
|
|
|-----------|------------------|
|
|
| `achievementsStore.test.ts` | Update mock imports |
|
|
| `DashboardIntegration.test.tsx` | Update mock imports |
|
|
| `AchievementsIntegration.test.tsx` | Update mock imports |
|
|
|
|
---
|
|
|
|
## 7. CHECKLIST DE VALIDACIÓN
|
|
|
|
### 7.1 Pre-requisitos Verificados
|
|
|
|
- [x] Base de datos recreada exitosamente
|
|
- [x] Función `claim_achievement_reward` corregida y desplegada
|
|
- [x] Dependencias de archivos identificadas
|
|
- [x] Triple distribución de rewards identificada
|
|
|
|
### 7.2 Plan Validado Contra Requisitos
|
|
|
|
- [x] P-DUP-001: Backend no distribuye → Fix: Llamar SQL function
|
|
- [x] P-DUP-002: SQL doble reward → Fix: Remover de check_and_grant + trigger
|
|
- [x] P-DUP-003: Hook hardcoded → Fix: Deprecar
|
|
- [x] P-DUP-004: APIs duplicadas → Fix: Consolidar en gamificationApi
|
|
- [x] P-DUP-005: Transformers inconsistentes → Fix: Usar transformer externo
|
|
- [x] P-DUP-006: Admin schema mismatch → Fix: Actualizar query
|
|
|
|
### 7.3 Impacto Evaluado
|
|
|
|
- [x] Ningún archivo crítico sin backup plan
|
|
- [x] Tests identificados para actualización
|
|
- [x] Rollback plan definido
|
|
|
|
---
|
|
|
|
## 8. RECOMENDACIÓN
|
|
|
|
**PROCEDER CON FASE 5 (Refinamiento) y FASE 6 (Ejecución)**
|
|
|
|
El plan ha sido validado y las dependencias están claras. El hallazgo de triple distribución hace aún más urgente la corrección.
|
|
|
|
**Orden de ejecución recomendado:**
|
|
1. **PRIMERO:** Corregir SQL (A.1 y A.2) - Detiene la triple distribución
|
|
2. **SEGUNDO:** Corregir Backend (B.1) - Habilita claim-to-earn
|
|
3. **TERCERO:** Corregir Frontend (C.1-C.3) - Cleanup y consistencia
|
|
|
|
---
|
|
|
|
**Validado por:** Claude (Arquitecto Técnico)
|
|
**Fecha:** 2026-01-10
|
|
**Estado:** FASE 4 COMPLETADA - Listo para FASE 5 (Refinamiento)
|