workspace/projects/gamilit/apps/database/_deprecated/scripts-violacion-carga-limpia/validate-update-user-rank-fix.sql
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -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
-- =====================================================================================