workspace-v1/orchestration/analisis/VALIDACION-PLAN-DUPLICADOS-2026-01-10.md
rckrdmrd e56e927a4d [MAINT-001] docs(orchestration): Actualizacion directivas SIMCO, perfiles y documentacion
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
2026-01-10 04:51:28 -06:00

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)