workspace-v1/orchestration/analisis/PLAN-FIX-GAMIFICATION-SUMMARY-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

229 lines
6.5 KiB
Markdown

# PLAN DE CORRECCION - ERRORES GAMIFICATION SUMMARY
**Fecha:** 2026-01-10
**Proyecto:** Gamilit
**Estado:** EN PLANEACION
**Referencia:** ANALISIS-ERRORES-GAMIFICATION-SUMMARY-2026-01-10.md
**Conventional Commits:** `fix(gamification): correct profile lookup by id instead of user_id`
---
## 0. RESUMEN EJECUTIVO
### Problema
Error 500 y 404 en endpoints de gamificación `/summary` debido a búsqueda incorrecta de profile.
### Causa Raíz
El método `validateProfileExists` busca por `profiles.user_id` (FK a auth.users) en lugar de `profiles.id` (PK referenciado por user_stats FK).
### Solución
Cambiar la búsqueda de `{ user_id: userId }` a `{ id: userId }` en `user-stats.service.ts:52`.
### Impacto
- **Backend:** 1 archivo, 1 línea de código
- **Base de datos:** Ninguno
- **Frontend:** Ninguno
---
## 1. ARCHIVOS A MODIFICAR
### 1.1 Cambio Principal
| ID | Archivo | Línea | Cambio |
|----|---------|-------|--------|
| CORR-GAM-001 | `apps/backend/src/modules/gamification/services/user-stats.service.ts` | 52 | Cambiar `user_id` por `id` |
### 1.2 Código Actual vs Nuevo
**ANTES (líneas 50-62):**
```typescript
private async validateProfileExists(userId: string): Promise<Profile> {
const profile = await this.profileRepo.findOne({
where: { user_id: userId }, // INCORRECTO
});
if (!profile) {
throw new NotFoundException(
`Profile not found for user ${userId}. User may not be properly initialized. ` +
`Please ensure the user registration process completed successfully.`
);
}
return profile;
}
```
**DESPUÉS (líneas 50-67):**
```typescript
/**
* P0-001: Verifica que el perfil existe antes de operaciones de gamificación
*
* CORR-GAM-001: Corregido para buscar por profiles.id (PK) en lugar de
* profiles.user_id (FK a auth.users). La FK user_stats_user_id_fkey
* referencia profiles(id), no profiles(user_id).
*
* @param userId - El ID del profile (profiles.id), NO el ID de auth.users
* @returns Profile si existe
* @throws NotFoundException si el perfil no existe
*/
private async validateProfileExists(userId: string): Promise<Profile> {
// CORR-GAM-001: Buscar por id (PK) no por user_id (FK a auth.users)
const profile = await this.profileRepo.findOne({
where: { id: userId },
});
if (!profile) {
throw new NotFoundException(
`Profile not found for id ${userId}. User may not be properly initialized. ` +
`Please ensure the user registration process completed successfully.`
);
}
return profile;
}
```
---
## 2. DEPENDENCIAS VERIFICADAS
### 2.1 Archivos que llaman validateProfileExists
```bash
# Grep realizado - Solo 1 llamada:
user-stats.service.ts:86 → this.validateProfileExists(userId)
```
**Conclusión:** Solo el método `create()` usa `validateProfileExists`, no hay otros consumidores.
### 2.2 Archivos que serán corregidos automáticamente
Una vez que `validateProfileExists` funcione correctamente, los siguientes endpoints funcionarán:
| Endpoint | Archivo | Estado Actual | Estado Post-Fix |
|----------|---------|---------------|-----------------|
| `GET /users/:id/summary` | user-stats.controller.ts | 500 | 200 OK |
| `GET /users/:id/achievements/summary` | achievements.controller.ts | 404 | 200 OK |
| `GET /users/:id/stats` | user-stats.controller.ts | 404 | 200 OK |
| `GET /users/:id/rank` | user-stats.controller.ts | 404 | 200 OK |
### 2.3 Base de Datos
| Objeto | Cambio Requerido |
|--------|------------------|
| `user_stats` tabla | Ninguno - DDL correcto |
| `user_stats_user_id_fkey` FK | Ninguno - apunta a profiles(id) correctamente |
| `profiles` tabla | Ninguno - estructura correcta |
### 2.4 Frontend
| Archivo | Cambio Requerido |
|---------|------------------|
| `gamificationAPI.ts` | Ninguno - envía profile.id correcto |
| `gamification.api.ts` | Ninguno - envía profile.id correcto |
| `useUserGamification.ts` | Ninguno |
| `AchievementsPage.tsx` | Ninguno |
---
## 3. PLAN DE EJECUCION
### Paso 1: Validar que profile existe en BD
```sql
SELECT id, user_id, email, display_name, role
FROM auth_management.profiles
WHERE id = 'cccccccc-cccc-cccc-cccc-cccccccccccc';
```
### Paso 2: Aplicar corrección CORR-GAM-001
Modificar `apps/backend/src/modules/gamification/services/user-stats.service.ts`:
- Línea 52: `{ user_id: userId }``{ id: userId }`
- Agregar comentario explicativo con ID CORR-GAM-001
### Paso 3: Verificar compilación TypeScript
```bash
cd apps/backend && npx tsc --noEmit
```
### Paso 4: Probar endpoints manualmente
```bash
# Endpoint 1: Summary
curl -X GET http://localhost:3006/api/v1/gamification/users/cccccccc-cccc-cccc-cccc-cccccccccccc/summary \
-H "Authorization: Bearer <token>"
# Endpoint 2: Achievements Summary
curl -X GET http://localhost:3006/api/v1/gamification/users/cccccccc-cccc-cccc-cccc-cccccccccccc/achievements/summary \
-H "Authorization: Bearer <token>"
```
---
## 4. VALIDACION POST-CORRECCION
### 4.1 Verificar user_stats creado
```sql
SELECT id, user_id, level, total_xp, ml_coins, current_rank
FROM gamification_system.user_stats
WHERE user_id = 'cccccccc-cccc-cccc-cccc-cccccccccccc';
```
**Resultado esperado:** 1 fila con valores iniciales (level=1, total_xp=0, ml_coins=100)
### 4.2 Verificar respuesta de endpoints
| Endpoint | Código Esperado | Respuesta Esperada |
|----------|-----------------|---------------------|
| `/summary` | 200 | `{ userId, level, totalXP, mlCoins, rank, ... }` |
| `/achievements/summary` | 200 | `{ total_available, completed, completion_percentage, unclaimed_rewards }` |
---
## 5. ROLLBACK
Si algo sale mal:
```typescript
// Revertir línea 52 de user-stats.service.ts
where: { id: userId } // → revertir a:
where: { user_id: userId }
```
Y eliminar el registro de user_stats creado:
```sql
DELETE FROM gamification_system.user_stats
WHERE user_id = 'cccccccc-cccc-cccc-cccc-cccccccccccc';
```
---
## 6. MENSAJE DE COMMIT
```
fix(gamification): correct profile lookup by id instead of user_id
CORR-GAM-001: The validateProfileExists method was searching for profiles
using profiles.user_id (FK to auth.users) instead of profiles.id (PK).
The FK user_stats_user_id_fkey references profiles(id), so when creating
user_stats records, we must validate the profile exists by its PK (id),
not by its FK to auth.users (user_id).
This fixes:
- Error 500 on GET /gamification/users/:userId/summary
- Error 404 on GET /gamification/users/:userId/achievements/summary
Refs: ANALISIS-ERRORES-GAMIFICATION-SUMMARY-2026-01-10.md
```
---
**Elaborado por:** Claude (Arquitecto Técnico)
**Fecha:** 2026-01-10
**Próximo paso:** FASE 4 - Validación del Plan