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
514 lines
20 KiB
Markdown
514 lines
20 KiB
Markdown
# FASE 1: ANÁLISIS INICIAL DE DUPLICADOS - ACHIEVEMENTS SYSTEM
|
|
|
|
**Fecha:** 2026-01-10
|
|
**Proyecto:** Gamilit
|
|
**Componente:** Sistema de Achievements (Full Stack)
|
|
**Estado:** EN ANÁLISIS
|
|
|
|
---
|
|
|
|
## 1. RESUMEN EJECUTIVO
|
|
|
|
Se identificaron **múltiples duplicaciones y conflictos críticos** en el sistema de achievements a través de las tres capas (Database, Backend, Frontend):
|
|
|
|
| Capa | Duplicados | Severidad |
|
|
|------|------------|-----------|
|
|
| **Database (SQL)** | 4 funciones con overlap | 🔴 CRÍTICO |
|
|
| **Backend (NestJS)** | 3 servicios con lógica inconsistente | 🔴 CRÍTICO |
|
|
| **Frontend (React)** | 6+ archivos duplicados | 🟡 IMPORTANTE |
|
|
|
|
---
|
|
|
|
## 2. HALLAZGOS POR CAPA
|
|
|
|
### 2.1 BASE DE DATOS - Funciones SQL Duplicadas
|
|
|
|
#### CRÍTICO: Flujo de Recompensas Inconsistente
|
|
|
|
| Función | Otorga XP | Otorga Coins | Registra Transacción | Usa Multiplicador |
|
|
|---------|-----------|--------------|----------------------|-------------------|
|
|
| `claim_achievement_reward` | ✅ | ✅ | ✅ | ❌ |
|
|
| `check_and_award_achievements` | ✅ | ✅ | ✅ | ❌ |
|
|
| `award_ml_coins` | ❌ | ✅ | ✅ | ✅ (rank) |
|
|
| `process_exercise_completion` | ✅ | ✅ | ❌ | ❌ |
|
|
| `promote_to_next_rank` | ❌ | ✅ | ✅ | ❌ |
|
|
| `consume_comodin` | ✅ | ❌ | ❌ | ❌ |
|
|
|
|
**Problema Principal:** `claim_achievement_reward` y `check_and_award_achievements` duplican funcionalidad:
|
|
- `check_and_award_achievements`: Otorga recompensas AL DESBLOQUEAR
|
|
- `claim_achievement_reward`: Otorga recompensas AL RECLAMAR
|
|
|
|
**Riesgo:** Si ambas se ejecutan, el usuario recibe recompensas DUPLICADAS.
|
|
|
|
#### Funciones SQL Relacionadas
|
|
|
|
```
|
|
/apps/database/ddl/schemas/gamification_system/functions/
|
|
├── claim_achievement_reward.sql # MODIFICADA - Reclamar recompensas
|
|
├── check_and_award_achievements.sql # DUPLICACIÓN - Otorga al desbloquear
|
|
├── award_ml_coins.sql # HELPER - Con multiplicador de rank
|
|
├── process_exercise_completion.sql # PARCIAL - XP/coins sin transacción
|
|
├── promote_to_next_rank.sql # RANK - Bonus por promoción
|
|
├── update_user_rank.sql # RANK - Similar a promote
|
|
├── check_rank_promotion.sql # RANK - Orquestación
|
|
├── consume_comodin.sql # ITEMS - XP sin transacción
|
|
└── apply_xp_boost.sql # HELPER - Solo lectura
|
|
```
|
|
|
|
---
|
|
|
|
### 2.2 BACKEND - Servicios con Lógica Inconsistente
|
|
|
|
#### CRÍTICO: claimRewards() NO Distribuye Recompensas
|
|
|
|
**Archivo:** `achievements.service.ts`
|
|
```typescript
|
|
// PROBLEMA: Solo marca como reclamado, NO distribuye XP/Coins
|
|
async claimRewards(userId: string, achievementId: string): Promise<UserAchievement> {
|
|
// ... validaciones ...
|
|
userAchievement.rewards_claimed = true;
|
|
return this.userAchievementRepo.save(userAchievement);
|
|
// ❌ FALTA: Llamar a UserStatsService.addXp()
|
|
// ❌ FALTA: Llamar a MLCoinsService.addCoins()
|
|
}
|
|
```
|
|
|
|
**Contraste con otros servicios:**
|
|
|
|
| Servicio | Método | Distribuye Rewards |
|
|
|----------|--------|-------------------|
|
|
| `achievements.service.ts` | `claimRewards()` | ❌ NO |
|
|
| `exercise-rewards.service.ts` | `claimRewards()` | ✅ SÍ (XP + Coins) |
|
|
| `mission-claim.service.ts` | `claimMission()` | ✅ SÍ (XP + Coins) |
|
|
|
|
#### CRÍTICO: Backend NO Llama a claim_achievement_reward SQL
|
|
|
|
**Hallazgo:** Ningún archivo del backend invoca la función SQL `claim_achievement_reward`.
|
|
- La función SQL está corregida pero NO se usa
|
|
- El backend usa TypeORM directamente para actualizar `rewards_claimed`
|
|
- Las recompensas (XP/Coins) NO se distribuyen en absoluto
|
|
|
|
#### Schema Mismatch en Admin
|
|
|
|
**Archivo:** `admin-progress.service.ts`
|
|
|
|
| Campo SQL Query | Campo en Entity | Problema |
|
|
|-----------------|-----------------|----------|
|
|
| `a.tier` | `a.rarity` / `a.difficulty_level` | ❌ No existe |
|
|
| `ua.progress_current` | `ua.progress` | ❌ Nombre diferente |
|
|
| `ua.progress_required` | `ua.max_progress` | ❌ Nombre diferente |
|
|
| `ua.unlocked_at` | `ua.completed_at` | ❌ Nombre diferente |
|
|
|
|
---
|
|
|
|
### 2.3 FRONTEND - Archivos Duplicados
|
|
|
|
#### APIs Duplicadas (3 archivos)
|
|
|
|
| Archivo | Ubicación | Métodos Duplicados |
|
|
|---------|-----------|-------------------|
|
|
| `achievementsAPI.ts` | `/features/gamification/social/api/` | `claimAchievementRewards()` |
|
|
| `gamification.api.ts` | `/lib/api/` | `claimAchievement()` |
|
|
| `achievementsApi.ts` | `/services/api/admin/` | Admin-only (OK) |
|
|
|
|
**Problema:** `claimAchievementRewards()` y `claimAchievement()` son implementaciones diferentes del mismo endpoint.
|
|
|
|
#### Hooks Duplicados (4 archivos)
|
|
|
|
| Hook | Ubicación | Líneas | Propósito |
|
|
|------|-----------|--------|-----------|
|
|
| `useAchievements.ts` | `/hooks/` | ~450 | Definiciones hardcodeadas + polling |
|
|
| `useAchievements.ts` | `/features/gamification/social/hooks/` | ~80 | Wrapper del store |
|
|
| `useAchievementsEnhanced.ts` | `/apps/student/hooks/` | ~300 | Filtrado avanzado |
|
|
| `useAchievementsStats.ts` | `/apps/teacher/hooks/` | ~50 | Analytics (OK - diferente) |
|
|
|
|
**Problema Principal:** `/hooks/useAchievements.ts` tiene 450+ líneas de definiciones de achievements hardcodeadas que deberían venir del backend.
|
|
|
|
#### Transformers Inconsistentes
|
|
|
|
| Archivo | Approach |
|
|
|---------|----------|
|
|
| `achievementsAPI.ts` | Mappers INLINE (`mapToFrontendAchievement`) |
|
|
| `achievementTransformer.ts` | Transformer EXTERNO (`transformAchievements`) |
|
|
| `gamification.api.ts` | Usa transformer externo |
|
|
|
|
---
|
|
|
|
## 3. MATRIZ DE DUPLICACIÓN
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ FLUJO DE CLAIM REWARDS │
|
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Frontend Backend Database │
|
|
│ ───────── ─────── ──────── │
|
|
│ │
|
|
│ achievementsAPI.ts ──► achievements.service.ts ──► [NO LLAMA SQL] │
|
|
│ claimAchievementRewards() claimRewards() claim_achievement_reward│
|
|
│ │ │ │
|
|
│ │ │ ❌ Solo marca flag │
|
|
│ │ │ ❌ NO distribuye rewards │
|
|
│ │ │ │
|
|
│ gamification.api.ts ───► [MISMO ENDPOINT] │
|
|
│ claimAchievement() │
|
|
│ │
|
|
│ ════════════════════════════════════════════════════════════════════════ │
|
|
│ PROBLEMA: Las recompensas NUNCA se distribuyen al reclamar achievements │
|
|
│ ════════════════════════════════════════════════════════════════════════ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 4. ARCHIVOS IDENTIFICADOS PARA ANÁLISIS DETALLADO
|
|
|
|
### 4.1 Database (SQL) - 9 archivos
|
|
```
|
|
/apps/database/ddl/schemas/gamification_system/functions/
|
|
├── claim_achievement_reward.sql # MODIFICADO
|
|
├── check_and_award_achievements.sql # DUPLICACIÓN POTENCIAL
|
|
├── award_ml_coins.sql # HELPER - Debería usarse
|
|
├── process_exercise_completion.sql # INCONSISTENTE
|
|
├── promote_to_next_rank.sql # OVERLAP CON update_user_rank
|
|
├── update_user_rank.sql # OVERLAP CON promote
|
|
├── check_rank_promotion.sql # ORQUESTACIÓN
|
|
├── consume_comodin.sql # INCONSISTENTE
|
|
└── update_leaderboard_streaks.sql # MENOR
|
|
```
|
|
|
|
### 4.2 Backend (NestJS) - 6 archivos
|
|
```
|
|
/apps/backend/src/modules/
|
|
├── gamification/
|
|
│ ├── services/
|
|
│ │ ├── achievements.service.ts # CRÍTICO - NO distribuye rewards
|
|
│ │ └── missions/mission-claim.service.ts # REFERENCIA - SÍ distribuye
|
|
│ ├── controllers/achievements.controller.ts
|
|
│ └── entities/
|
|
│ ├── achievement.entity.ts
|
|
│ └── user-achievement.entity.ts
|
|
├── progress/services/
|
|
│ └── grading/exercise-rewards.service.ts # REFERENCIA - SÍ distribuye
|
|
└── admin/services/
|
|
└── admin-progress.service.ts # SCHEMA MISMATCH
|
|
```
|
|
|
|
### 4.3 Frontend (React) - 8 archivos
|
|
```
|
|
/apps/frontend/src/
|
|
├── features/gamification/
|
|
│ ├── social/
|
|
│ │ ├── api/achievementsAPI.ts # MODIFICADO
|
|
│ │ ├── store/achievementsStore.ts # MODIFICADO
|
|
│ │ ├── hooks/useAchievements.ts # WRAPPER
|
|
│ │ └── types/achievementsTypes.ts
|
|
│ └── achievements/utils/
|
|
│ └── achievementTransformer.ts # NO USADO CONSISTENTEMENTE
|
|
├── hooks/useAchievements.ts # DUPLICADO - 450 líneas hardcoded
|
|
├── apps/student/hooks/useAchievementsEnhanced.ts
|
|
└── lib/api/gamification.api.ts # DUPLICADO
|
|
```
|
|
|
|
---
|
|
|
|
## 5. PROBLEMAS CRÍTICOS IDENTIFICADOS
|
|
|
|
### P-DUP-001: Recompensas NO Distribuidas al Reclamar
|
|
- **Severidad:** 🔴 CRÍTICO
|
|
- **Impacto:** Los usuarios reclaman achievements pero NO reciben XP/ML Coins
|
|
- **Causa:** Backend no llama función SQL ni servicios de distribución
|
|
- **Archivos:** `achievements.service.ts`, `claim_achievement_reward.sql`
|
|
|
|
### P-DUP-002: Doble Otorgamiento de Recompensas
|
|
- **Severidad:** 🔴 CRÍTICO
|
|
- **Impacto:** Si se usa `check_and_award_achievements` + `claim_achievement_reward`, rewards duplicados
|
|
- **Causa:** Dos funciones con mismo propósito
|
|
- **Archivos:** `check_and_award_achievements.sql`, `claim_achievement_reward.sql`
|
|
|
|
### P-DUP-003: APIs Frontend Duplicadas
|
|
- **Severidad:** 🟡 IMPORTANTE
|
|
- **Impacto:** Inconsistencia en manejo de errores y respuestas
|
|
- **Causa:** Dos archivos con mismo endpoint
|
|
- **Archivos:** `achievementsAPI.ts`, `gamification.api.ts`
|
|
|
|
### P-DUP-004: Hook con Definiciones Hardcodeadas
|
|
- **Severidad:** 🟡 IMPORTANTE
|
|
- **Impacto:** Achievements pueden no coincidir con backend
|
|
- **Causa:** 450 líneas de definiciones en frontend
|
|
- **Archivos:** `/hooks/useAchievements.ts`
|
|
|
|
### P-DUP-005: Schema Mismatch Admin
|
|
- **Severidad:** 🟡 IMPORTANTE
|
|
- **Impacto:** Dashboard admin muestra datos incorrectos o NULL
|
|
- **Causa:** Campos SQL no coinciden con entities
|
|
- **Archivos:** `admin-progress.service.ts`
|
|
|
|
### P-DUP-006: Transformers Inconsistentes
|
|
- **Severidad:** 🟢 MENOR
|
|
- **Impacto:** Código duplicado de transformación
|
|
- **Causa:** Inline mappers vs external transformer
|
|
- **Archivos:** `achievementsAPI.ts`, `achievementTransformer.ts`
|
|
|
|
---
|
|
|
|
## 6. SIGUIENTE FASE
|
|
|
|
**FASE 2:** Análisis detallado de cada archivo identificado para:
|
|
1. Confirmar duplicaciones con comparación línea a línea
|
|
2. Identificar dependencias entre archivos
|
|
3. Determinar cuál versión mantener/consolidar
|
|
4. Mapear impacto de cambios
|
|
|
|
---
|
|
|
|
## 7. FASE 2: ANÁLISIS DETALLADO
|
|
|
|
### 7.1 Comparación SQL: claim_achievement_reward vs check_and_grant_achievements
|
|
|
|
#### Función: `check_and_grant_achievements.sql` (Líneas 92-139)
|
|
|
|
```sql
|
|
-- AL DESBLOQUEAR (is_completed = true):
|
|
-- 1. Inserta en user_achievements
|
|
INSERT INTO gamification_system.user_achievements (
|
|
user_id, achievement_id, is_completed, completed_at, progress, max_progress
|
|
) VALUES (p_user_id, v_achievement.id, true, NOW(), 100, 100);
|
|
|
|
-- 2. Actualiza user_stats (XP + ML Coins)
|
|
UPDATE gamification_system.user_stats
|
|
SET
|
|
total_xp = COALESCE(total_xp, 0) + v_xp_reward,
|
|
ml_coins = v_new_balance,
|
|
achievements_earned = COALESCE(achievements_earned, 0) + 1
|
|
WHERE user_id = p_user_id;
|
|
|
|
-- 3. Registra transacción de coins
|
|
INSERT INTO gamification_system.ml_coins_transactions (...)
|
|
VALUES (...'earned_achievement'...'Logro desbloqueado: '...);
|
|
```
|
|
|
|
#### Función: `claim_achievement_reward.sql` (Líneas 54-95)
|
|
|
|
```sql
|
|
-- AL RECLAMAR (rewards_claimed = true):
|
|
-- 1. Actualiza user_achievements
|
|
UPDATE gamification_system.user_achievements
|
|
SET rewards_claimed = TRUE
|
|
WHERE user_id = p_user_id AND achievement_id = p_achievement_id;
|
|
|
|
-- 2. Actualiza user_stats (XP + ML Coins)
|
|
UPDATE gamification_system.user_stats
|
|
SET
|
|
total_xp = total_xp + COALESCE((v_achievement.rewards->>'xp')::INTEGER, v_achievement.points_value, 0),
|
|
ml_coins = v_new_balance
|
|
WHERE user_id = p_user_id;
|
|
|
|
-- 3. Registra transacción de coins
|
|
INSERT INTO gamification_system.ml_coins_transactions (...)
|
|
VALUES (...'earned_achievement'...'Recompensa reclamada: '...);
|
|
```
|
|
|
|
#### Tabla Comparativa
|
|
|
|
| Aspecto | check_and_grant | claim_achievement_reward |
|
|
|---------|-----------------|--------------------------|
|
|
| **Cuándo se ejecuta** | Al desbloquear logro | Al reclamar recompensa |
|
|
| **Otorga XP** | ✅ Sí | ✅ Sí |
|
|
| **Otorga ML Coins** | ✅ Sí | ✅ Sí |
|
|
| **Registra transacción** | ✅ Sí | ✅ Sí |
|
|
| **Incrementa achievements_earned** | ✅ Sí | ❌ No |
|
|
| **Mensaje transacción** | "Logro desbloqueado:" | "Recompensa reclamada:" |
|
|
|
|
**⚠️ PROBLEMA CRÍTICO:** Si ambas funciones se ejecutan para el mismo achievement, el usuario recibe **DOBLE** recompensa de XP y ML Coins.
|
|
|
|
---
|
|
|
|
### 7.2 Backend: achievements.service.ts - claimRewards() (Líneas 745-759)
|
|
|
|
```typescript
|
|
async claimRewards(userId: string, achievementId: string): Promise<UserAchievement> {
|
|
const userAchievement = await this.checkProgress(userId, achievementId);
|
|
|
|
if (!userAchievement.is_completed) {
|
|
throw new BadRequestException(`Achievement ${achievementId} is not completed yet`);
|
|
}
|
|
|
|
if (userAchievement.rewards_claimed) {
|
|
throw new BadRequestException(`Rewards already claimed for achievement ${achievementId}`);
|
|
}
|
|
|
|
// ⚠️ PROBLEMA: Solo marca el flag, NO distribuye recompensas
|
|
userAchievement.rewards_claimed = true;
|
|
|
|
return this.userAchievementRepo.save(userAchievement);
|
|
|
|
// ❌ FALTA: No llama a claim_achievement_reward SQL
|
|
// ❌ FALTA: No llama a UserStatsService.addXp()
|
|
// ❌ FALTA: No llama a MLCoinsService.addCoins()
|
|
// ❌ FALTA: No registra transacción de coins
|
|
}
|
|
```
|
|
|
|
**Contraste con otros servicios que SÍ distribuyen:**
|
|
|
|
| Servicio | Distribuye XP | Distribuye Coins | Registra Trans. |
|
|
|----------|--------------|------------------|-----------------|
|
|
| `achievements.service.claimRewards()` | ❌ NO | ❌ NO | ❌ NO |
|
|
| `exercise-rewards.service.claimRewards()` | ✅ SÍ | ✅ SÍ | ✅ SÍ |
|
|
| `mission-claim.service.claimMission()` | ✅ SÍ | ✅ SÍ | ✅ SÍ |
|
|
|
|
---
|
|
|
|
### 7.3 Frontend APIs: Comparación Detallada
|
|
|
|
#### achievementsAPI.ts - claimAchievementRewards() (Líneas 303-334)
|
|
|
|
```typescript
|
|
export const claimAchievementRewards = async (
|
|
userId: string,
|
|
achievementId: string,
|
|
): Promise<{
|
|
success: boolean;
|
|
achievement_id: string;
|
|
rewards_claimed: boolean;
|
|
ml_coins_awarded?: number; // ⚠️ Espera valores que backend NO envía
|
|
xp_awarded?: number; // ⚠️ Espera valores que backend NO envía
|
|
}> => {
|
|
const { data } = await apiClient.post<ApiResponse<{...}>>(
|
|
`/gamification/users/${userId}/achievements/${achievementId}/claim`
|
|
);
|
|
|
|
return {
|
|
success: true,
|
|
achievement_id: achievementId,
|
|
rewards_claimed: data.data.rewards_claimed,
|
|
// ml_coins_awarded y xp_awarded NO vienen del backend
|
|
};
|
|
};
|
|
```
|
|
|
|
#### gamification.api.ts - claimAchievement() (Líneas 166-172)
|
|
|
|
```typescript
|
|
claimAchievement: async (userId: string, achievementId: string): Promise<UserAchievement> => {
|
|
const { data } = await apiClient.post<UserAchievement>(
|
|
`/gamification/users/${userId}/achievements/${achievementId}/claim`,
|
|
{},
|
|
);
|
|
return data; // Retorna datos sin transformar
|
|
};
|
|
```
|
|
|
|
#### Diferencias Clave
|
|
|
|
| Aspecto | achievementsAPI.ts | gamification.api.ts |
|
|
|---------|-------------------|---------------------|
|
|
| **Ubicación** | /features/gamification/social/api/ | /lib/api/ |
|
|
| **Tipo retorno** | Custom object | UserAchievement |
|
|
| **Transformación** | Inline | Sin transformar |
|
|
| **Usado por** | achievementsStore.ts | AchievementsPage.tsx |
|
|
| **Manejo errores** | handleAPIError() | throw directo |
|
|
|
|
---
|
|
|
|
### 7.4 Frontend Hook: /hooks/useAchievements.ts - Definiciones Hardcodeadas
|
|
|
|
**⚠️ PROBLEMA MAYOR:** Este hook tiene ~450 líneas de código con achievement definitions hardcodeadas:
|
|
|
|
```typescript
|
|
// Líneas 71-250 - DEFINICIONES DUPLICADAS DEL BACKEND
|
|
const ACHIEVEMENT_DEFINITIONS: AchievementDefinition[] = [
|
|
{
|
|
id: 'first_steps',
|
|
title: 'Primeros Pasos',
|
|
description: 'Completa tu primer ejercicio',
|
|
icon: '👣',
|
|
rarity: 'common',
|
|
xp_reward: 10, // ⚠️ Puede no coincidir con backend
|
|
ml_coins_reward: 5, // ⚠️ Puede no coincidir con backend
|
|
condition: { type: 'exercises_completed', value: 1, operator: '>=' },
|
|
},
|
|
// ... 20+ más achievements hardcodeados
|
|
];
|
|
```
|
|
|
|
**Problemas:**
|
|
1. Las recompensas pueden NO coincidir con la base de datos
|
|
2. Nuevos achievements no aparecen hasta modificar código
|
|
3. Difícil mantener sincronizado con seeds/backend
|
|
4. Duplica lógica de detección que el backend ya tiene
|
|
|
|
---
|
|
|
|
### 7.5 Transformer: achievementTransformer.ts vs Inline Mappers
|
|
|
|
#### achievementTransformer.ts (Externo - CORRECTO)
|
|
|
|
```typescript
|
|
// Líneas 212-266 - Bien estructurado
|
|
export const transformAchievement = (apiResponse: ApiAchievementResponse): Achievement => {
|
|
const rewards = {
|
|
xp: apiResponse.rewards?.xp ?? apiResponse.points_value ?? 0,
|
|
mlCoins: apiResponse.rewards?.ml_coins ?? apiResponse.ml_coins_reward ?? 0,
|
|
// ...
|
|
};
|
|
return {
|
|
id: apiResponse.id,
|
|
name: apiResponse.name,
|
|
// ... mapeo completo y consistente
|
|
};
|
|
};
|
|
```
|
|
|
|
#### achievementsAPI.ts (Inline - INCONSISTENTE)
|
|
|
|
```typescript
|
|
// Líneas 382-411 - Duplica lógica del transformer
|
|
export const mapToFrontendAchievement = (
|
|
backendAchievement: BackendAchievement,
|
|
userProgress?: BackendUserAchievement,
|
|
): Achievement => {
|
|
return {
|
|
id: backendAchievement.id,
|
|
title: backendAchievement.name, // ⚠️ 'title' vs 'name' en transformer
|
|
// ... mapeo diferente
|
|
mlCoinsReward: backendAchievement.rewards?.ml_coins ?? backendAchievement.ml_coins_reward ?? 0,
|
|
xpReward: backendAchievement.rewards?.xp ?? backendAchievement.points_value ?? 0,
|
|
// ... campos diferentes
|
|
};
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 8. RESUMEN DE PROBLEMAS CONFIRMADOS
|
|
|
|
### CRÍTICOS (Requieren corrección inmediata)
|
|
|
|
| ID | Problema | Impacto | Archivos |
|
|
|----|----------|---------|----------|
|
|
| P-DUP-001 | Backend NO distribuye recompensas al claim | Users no reciben XP/Coins | achievements.service.ts |
|
|
| P-DUP-002 | SQL puede dar DOBLE recompensa | Inflación de economía | check_and_grant + claim_achievement |
|
|
| P-DUP-003 | Hook tiene 450+ líneas hardcoded | Desincronización con backend | /hooks/useAchievements.ts |
|
|
|
|
### IMPORTANTES (Deben corregirse pronto)
|
|
|
|
| ID | Problema | Impacto | Archivos |
|
|
|----|----------|---------|----------|
|
|
| P-DUP-004 | APIs duplicadas con diferente retorno | Confusión de desarrolladores | achievementsAPI.ts, gamification.api.ts |
|
|
| P-DUP-005 | Transformers inconsistentes | Datos transformados diferente | achievementsAPI.ts inline mappers |
|
|
|
|
### MENORES (Mejoras de calidad)
|
|
|
|
| ID | Problema | Impacto | Archivos |
|
|
|----|----------|---------|----------|
|
|
| P-DUP-006 | Schema mismatch en admin | Dashboard puede fallar | admin-progress.service.ts |
|
|
|
|
---
|
|
|
|
**Analizado por:** Claude (Arquitecto Técnico)
|
|
**Fecha:** 2026-01-10
|
|
**Estado:** FASE 2 COMPLETADA - Pendiente FASE 3 (Planeación)
|