workspace/projects/gamilit/apps/database/scripts/validations/validate-update-user-rank-fix.sql
rckrdmrd 289c5a4ee5
Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Gamilit: Backend fixes, frontend API updates, deployment guides and validations
Backend:
- Fix email verification and password recovery services
- Fix exercise submission and student progress services

Frontend:
- Update missions, password, and profile API services
- Fix ExerciseContentRenderer component

Docs & Scripts:
- Add SSL/Certbot deployment guide
- Add quick deployment guide
- Database scripts for testing and validations
- Migration and homologation reports
- Functions inventory documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 23:42:48 -06:00

232 lines
8.4 KiB
PL/PgSQL

-- =====================================================================================
-- Script: Validación de corrección update_user_rank()
-- Propósito: Validar que la función update_user_rank() incluye balance_before y balance_after
-- Fecha: 2025-11-24
-- Uso: psql -d gamilit_platform -f scripts/validate-update-user-rank-fix.sql
-- =====================================================================================
\echo ''
\echo '========================================='
\echo 'VALIDACIÓN: update_user_rank() - Balance Fields'
\echo '========================================='
\echo ''
-- =====================================================================================
-- PASO 1: Verificar existencia de la función
-- =====================================================================================
\echo '1. Verificando existencia de función...'
SELECT
p.proname AS function_name,
n.nspname AS schema_name,
pg_get_function_result(p.oid) AS return_type,
pg_get_function_arguments(p.oid) AS arguments
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname = 'update_user_rank'
AND n.nspname = 'gamification_system';
\echo ''
-- =====================================================================================
-- PASO 2: Verificar estructura de la tabla ml_coins_transactions
-- =====================================================================================
\echo '2. Verificando estructura de ml_coins_transactions...'
SELECT
column_name,
data_type,
is_nullable,
column_default
FROM information_schema.columns
WHERE table_schema = 'gamification_system'
AND table_name = 'ml_coins_transactions'
AND column_name IN ('balance_before', 'balance_after', 'transaction_type', 'amount', 'user_id')
ORDER BY ordinal_position;
\echo ''
-- =====================================================================================
-- PASO 3: Verificar valores del ENUM transaction_type
-- =====================================================================================
\echo '3. Verificando ENUM transaction_type...'
SELECT
t.typname AS enum_name,
e.enumlabel AS enum_value,
e.enumsortorder AS sort_order
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typname = 'transaction_type'
AND n.nspname = 'gamification_system'
ORDER BY e.enumsortorder;
\echo ''
-- =====================================================================================
-- PASO 4: Verificar que 'earned_rank' existe en el ENUM
-- =====================================================================================
\echo '4. Verificando que ''earned_rank'' existe en el ENUM...'
SELECT
CASE
WHEN EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typname = 'transaction_type'
AND n.nspname = 'gamification_system'
AND e.enumlabel = 'earned_rank'
) THEN '✅ ENUM ''earned_rank'' existe'
ELSE '❌ ERROR: ENUM ''earned_rank'' NO existe'
END AS validation_result;
\echo ''
-- =====================================================================================
-- PASO 5: Ver código fuente de la función (últimas líneas del INSERT)
-- =====================================================================================
\echo '5. Verificando código fuente de la función (fragmento del INSERT)...'
SELECT
substring(
pg_get_functiondef(p.oid),
position('INSERT INTO gamification_system.ml_coins_transactions' in pg_get_functiondef(p.oid)),
500
) AS insert_statement_fragment
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname = 'update_user_rank'
AND n.nspname = 'gamification_system';
\echo ''
-- =====================================================================================
-- PASO 6: Test básico de sintaxis (sin ejecutar realmente)
-- =====================================================================================
\echo '6. Validación de sintaxis SQL...'
\echo 'Preparando transacción de prueba (se hará ROLLBACK)...'
BEGIN;
-- Crear usuario de prueba temporal
DO $$
DECLARE
v_test_user_id UUID := 'test-user-validate-rank-fix'::UUID;
BEGIN
-- Limpiar si existe
DELETE FROM gamification_system.user_stats WHERE user_id = v_test_user_id;
DELETE FROM gamification_system.user_ranks WHERE user_id = v_test_user_id;
DELETE FROM auth_management.profiles WHERE id = v_test_user_id;
-- Crear perfil de prueba
INSERT INTO auth_management.profiles (id, display_name, role, tenant_id)
VALUES (
v_test_user_id,
'Test User - Validate Rank Fix',
'student',
(SELECT id FROM auth_management.tenants LIMIT 1)
);
-- Crear user_stats inicial (debe disparar trigger de inicialización)
-- Si el trigger funciona, creará el registro automáticamente
RAISE NOTICE 'Usuario de prueba creado: %', v_test_user_id;
END $$;
-- Verificar que el usuario se creó correctamente
\echo ''
\echo 'Verificando creación de user_stats...'
SELECT
user_id,
total_xp,
COALESCE(ml_coins, 0) AS ml_coins,
created_at
FROM gamification_system.user_stats
WHERE user_id = 'test-user-validate-rank-fix'::UUID;
-- Simular XP suficiente para ascender de rango
UPDATE gamification_system.user_stats
SET total_xp = 5000 -- Suficiente para pasar de Ajaw
WHERE user_id = 'test-user-validate-rank-fix'::UUID;
\echo ''
\echo 'Ejecutando update_user_rank()...'
SELECT * FROM gamification_system.update_user_rank('test-user-validate-rank-fix'::UUID);
\echo ''
\echo 'Verificando transacción creada...'
SELECT
user_id,
amount,
balance_before,
balance_after,
transaction_type,
description,
created_at
FROM gamification_system.ml_coins_transactions
WHERE user_id = 'test-user-validate-rank-fix'::UUID
AND transaction_type = 'earned_rank'
ORDER BY created_at DESC
LIMIT 1;
\echo ''
\echo 'Validando integridad de balance...'
SELECT
CASE
WHEN balance_after = balance_before + amount THEN '✅ Balance correcto'
ELSE '❌ ERROR: Balance incorrecto'
END AS balance_validation,
balance_before,
amount,
balance_after,
(balance_before + amount) AS expected_balance_after
FROM gamification_system.ml_coins_transactions
WHERE user_id = 'test-user-validate-rank-fix'::UUID
AND transaction_type = 'earned_rank'
ORDER BY created_at DESC
LIMIT 1;
-- Rollback para no afectar la base de datos
ROLLBACK;
\echo ''
\echo '✅ Transacción de prueba revertida (ROLLBACK)'
\echo ''
-- =====================================================================================
-- PASO 7: Resumen de validación
-- =====================================================================================
\echo '========================================='
\echo 'RESUMEN DE VALIDACIÓN'
\echo '========================================='
\echo ''
\echo 'Checklist de corrección:'
\echo ' [ ] Función update_user_rank() existe'
\echo ' [ ] Campos balance_before y balance_after existen en ml_coins_transactions'
\echo ' [ ] Campos son NOT NULL'
\echo ' [ ] ENUM transaction_type tiene valor ''earned_rank'''
\echo ' [ ] Función incluye balance_before y balance_after en INSERT'
\echo ' [ ] Balance calculado correctamente (balance_after = balance_before + amount)'
\echo ''
\echo 'Si todos los pasos anteriores mostraron ✅, la corrección es exitosa.'
\echo ''
-- =====================================================================================
-- PASO 8: Instrucciones finales
-- =====================================================================================
\echo '========================================='
\echo 'INSTRUCCIONES'
\echo '========================================='
\echo ''
\echo 'Para aplicar la corrección a producción:'
\echo ' 1. Verificar que este script ejecuta sin errores'
\echo ' 2. Aplicar función: psql -d gamilit_platform -f ddl/schemas/gamification_system/functions/update_user_rank.sql'
\echo ' 3. Validar con usuarios reales en ambiente de staging'
\echo ' 4. Deploy a producción'
\echo ''
\echo 'Para revisar otras funciones que usan ml_coins_transactions:'
\echo ' grep -r "INSERT INTO.*ml_coins_transactions" apps/database/ddl/'
\echo ''
-- =====================================================================================
-- FIN DEL SCRIPT
-- =====================================================================================