# 🧪 Guía de Prueba Manual: Unbuffered Query Fix

Esta guía te ayudará a verificar que el fix para el error "Cannot execute queries while other unbuffered queries are active" está funcionando correctamente.

## 📋 Archivos Modificados

Los siguientes archivos fueron modificados para resolver el problema:

1. **`src/App/Observers/FlowCompletedObserver.php`** (línea 362-366)
   - ❌ **Antes**: `exec('SELECT 1')` dejaba cursor unbuffered abierto
   - ✅ **Después**: Eliminado el `SELECT 1` innecesario

2. **`src/App/Services/CleanupFlowDataService.php`** (línea 573-617)
   - ✅ **Agregado**: Buffered query scoped en `cleanupDatabaseEntries()`
   - ✅ **Defensa**: Protección adicional que se restaura automáticamente

## 🚀 Cómo Ejecutar la Prueba

### Opción 1: Prueba con Datos Ficticios (Recomendado)

Esta es la forma más segura de probar, crea datos de prueba y los limpia.

```bash
# 1. Entra a tinker
php artisan tinker

# 2. Carga el script de prueba
require 'tests/manual/test_unbuffered_query_fix.php';

# 3. Ejecuta la prueba
testUnbufferedQueryFix();
```

**Qué hace:**
- Crea un Flow ID de prueba (99999)
- Inserta 9 registros de cleanup
- Ejecuta múltiples SELECTs (simula ensureMetricsFinalized)
- Ejecuta el cleanup (DELETE queries)
- Verifica que todo se eliminó correctamente

### Opción 2: Prueba con un Tenant Específico

```bash
php artisan tinker

# 1. Configura el tenant
setupTenantConnection('sx_db_tu_tenant');

# 2. Carga y ejecuta
require 'tests/manual/test_unbuffered_query_fix.php';
testUnbufferedQueryFix();
```

### Opción 3: Prueba con un Flow Real (¡Cuidado!)

⚠️ **ADVERTENCIA**: Esta opción eliminará datos reales de cleanup del flow.

```bash
php artisan tinker

# 1. Encuentra un flow con datos de cleanup
$flowsWithCleanup = DB::connection('tenant_connection')
    ->table('flow_duplicate_prevention')
    ->select('flow_id')
    ->distinct()
    ->limit(5)
    ->pluck('flow_id');

# 2. Prueba con uno de ellos
require 'tests/manual/test_unbuffered_query_fix.php';
testWithRealFlow(123); // Reemplaza 123 con el ID real
```

## 📊 Resultados Esperados

### ✅ Prueba Exitosa

```
🧪 INICIANDO PRUEBA DEL FIX DE UNBUFFERED QUERY
======================================================================

1️⃣  Verificando tablas necesarias...
   ✅ Todas las tablas necesarias existen

2️⃣  Limpiando datos de prueba anteriores...
   ✅ Datos anteriores limpiados

3️⃣  Insertando datos de prueba...
   ✅ Flow metric creado
   ✅ 5 registros de prevención de duplicados insertados
   ✅ Completion lock insertado
   ✅ 3 registros de prevención de páginas insertados

4️⃣  Verificando datos insertados...
   - Duplicate prevention: 5 registros
   - Completion locks: 1 registros
   - Page prevention: 3 registros
   - Total: 9 registros

5️⃣  EJECUTANDO PRUEBA DEL FIX...
   📖 Ejecutando múltiples SELECT queries...
      - SELECT #1: ✅ OK
      - SELECT #2: ✅ OK
      - SELECT #3: ✅ OK
      - SELECT #4: ✅ OK
      - SELECT #5: ✅ OK

   🗑️  Ejecutando cleanup (DELETE queries)...
      ✅ Cleanup ejecutado sin errores!

6️⃣  VERIFICANDO RESULTADOS...
   📊 Registros eliminados:
      - Duplicate prevention: 5 de 5
      - Completion locks: 1 de 1
      - Page prevention: 3 de 3
      - Total eliminado: 9

   📊 Registros restantes:
      - Duplicate prevention: 0
      - Completion locks: 0
      - Page prevention: 0
      - Total restante: 0

✅ ¡PRUEBA EXITOSA!
   Todos los registros fueron eliminados correctamente.
   El fix del unbuffered query está funcionando.
```

### ❌ Prueba Fallida (Si el fix NO funciona)

```
5️⃣  EJECUTANDO PRUEBA DEL FIX...
   📖 Ejecutando múltiples SELECT queries...
      - SELECT #1: ✅ OK
      - SELECT #2: ✅ OK
      - SELECT #3: ✅ OK
      - SELECT #4: ✅ OK
      - SELECT #5: ✅ OK

   🗑️  Ejecutando cleanup (DELETE queries)...
      ❌ ERROR durante el cleanup!

   🔴 TIPO DE ERROR: Illuminate\Database\QueryException
   🔴 MENSAJE: SQLSTATE[HY000]: General error: 2014 Cannot execute queries 
       while other unbuffered queries are active. Consider using 
       PDOStatement::fetchAll(). Alternatively, if your code is only ever 
       going to run against mysql, you may enable query buffering by 
       setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

   💥 ERROR DETECTADO: 'Cannot execute queries while other unbuffered queries are active'
   ⚠️  El fix NO está funcionando correctamente.

   📝 DIAGNÓSTICO:
      1. Verifica que los cambios en FlowCompletedObserver.php estén aplicados
      2. Verifica que los cambios en CleanupFlowDataService.php estén aplicados
      3. Si usas cache de código (OPcache), reinicia PHP-FPM
```

## 🔍 Verificar en Logs de Producción

Si quieres verificar en producción (sin ejecutar pruebas):

```bash
# 1. Ver si hay errores de unbuffered query
grep -r "unbuffered queries" storage/logs/*.log

# 2. Ver si el cleanup está funcionando
grep "Database entries cleaned up successfully" storage/logs/*.log | tail -20

# 3. Ver si hubo errores en el cleanup
grep "Failed to clean up database entries" storage/logs/*.log | tail -20
```

## 📝 Qué Verificar

### 1. El error NO debe aparecer más

Busca en los logs:
```bash
grep "Cannot execute queries while other unbuffered queries are active" storage/logs/laravel-$(date +%Y-%m-%d).log
```

**Esperado**: No debería haber resultados

### 2. El cleanup debe completarse exitosamente

```bash
grep "Database entries cleaned up successfully" storage/logs/laravel-$(date +%Y-%m-%d).log | tail -5
```

**Esperado**: Deberías ver logs recientes del cleanup exitoso

### 3. Los flows deben completarse sin errores

```bash
grep "FlowCompletedObserver: Error processing flow completion" storage/logs/laravel-$(date +%Y-%m-%d).log
```

**Esperado**: No debería haber errores

## 🐛 Si la Prueba Falla

### Paso 1: Verificar que los cambios están aplicados

```bash
# Verificar FlowCompletedObserver
grep -A 5 "ensureMetricsFinalized" src/App/Observers/FlowCompletedObserver.php | grep -c "SELECT 1"
# Debe retornar: 0 (el SELECT 1 fue eliminado)

# Verificar CleanupFlowDataService
grep -A 10 "cleanupDatabaseEntries" src/App/Services/CleanupFlowDataService.php | grep -c "PDO::MYSQL_ATTR_USE_BUFFERED_QUERY"
# Debe retornar: al menos 1 (el setAttribute está presente)
```

### Paso 2: Limpiar cache

```bash
# Limpiar cache de Laravel
php artisan cache:clear
php artisan config:clear
php artisan view:clear

# Si usas OPcache, reinicia PHP-FPM
sudo service php8.2-fpm restart
```

### Paso 3: Verificar permisos

```bash
# Asegúrate de que los archivos tienen permisos correctos
ls -la src/App/Observers/FlowCompletedObserver.php
ls -la src/App/Services/CleanupFlowDataService.php
```

## 📞 Ayuda Adicional

Si la prueba sigue fallando:

1. **Revisa el stack trace completo** en el output del script
2. **Verifica la versión de PHP**: debe ser 8.x
3. **Verifica la versión de Laravel**: debe ser 10.x
4. **Verifica que estés usando MySQL** (el fix es específico para MySQL)
5. **Revisa los logs**: `storage/logs/laravel-$(date +%Y-%m-%d).log`

## 🎯 Escenario Real de Producción

En producción, el error ocurre cuando:

1. Un flow completa su ejecución
2. Se dispara el evento `FlowCompleted`
3. El `FlowCompletedObserver` ejecuta:
   - `ensureMetricsFinalized()` → Múltiples SELECT queries
   - `cleanupFlowData()` → DELETE queries
4. **Sin el fix**: El DELETE falla porque hay cursor unbuffered abierto
5. **Con el fix**: El DELETE funciona correctamente

Para verificar en producción, monitorea los logs después del deploy:

```bash
# Monitoreo en tiempo real
tail -f storage/logs/laravel-$(date +%Y-%m-%d).log | grep -E "(unbuffered|cleanup)"
```

