workspace/projects/gamilit/docs/95-guias-desarrollo/GUIA-VALIDACION-PRODUCCION.md
rckrdmrd a23f31ce8f feat(db): Sincronizar scripts de BD y documentacion de produccion
## Scripts de Base de Datos (12 archivos)
- init-database.sh: Inicializacion completa con usuario y BD
- init-database-v3.sh: Version con dotenv-vault
- reset-database.sh: Reset BD manteniendo usuario
- recreate-database.sh: Recreacion completa
- cleanup-duplicados.sh, fix-duplicate-triggers.sh
- verify-users.sh, verify-missions-status.sh
- load-users-and-profiles.sh, DB-127-validar-gaps.sh

## Scripts de Produccion (5 archivos)
- build-production.sh: Compilar backend y frontend
- deploy-production.sh: Desplegar con PM2
- pre-deploy-check.sh: Validaciones pre-deploy
- repair-missing-data.sh: Reparar datos faltantes
- migrate-missing-objects.sh: Migrar objetos SQL

## Documentacion (7 archivos)
- GUIA-DESPLIEGUE-PRODUCCION-COMPLETA.md
- GUIA-ACTUALIZACION-PRODUCCION.md
- GUIA-VALIDACION-PRODUCCION.md
- GUIA-DEPLOYMENT-AGENTE-PRODUCCION.md
- GUIA-SSL-NGINX-PRODUCCION.md
- GUIA-SSL-AUTOFIRMADO.md
- DIRECTIVA-DEPLOYMENT.md

## Actualizaciones DDL/Seeds
- 99-post-ddl-permissions.sql: Permisos actualizados
- LOAD-SEEDS-gamification_system.sh: Seeds completos

## Nuevos archivos
- PROMPT-AGENTE-PRODUCCION.md: Prompt para agente productivo
- FLUJO-CARGA-LIMPIA.md: Documentacion de carga limpia

Resuelve: Problema de carga de BD entre dev y produccion
Cumple: DIRECTIVA-POLITICA-CARGA-LIMPIA.md

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 15:01:03 -06:00

22 KiB

Guia de Validacion y Troubleshooting - Produccion GAMILIT

Version: 1.0.0 Fecha: 2025-12-18 Servidor: 74.208.126.102 Proposito: Validar carga correcta de BD y resolver errores comunes


Indice

  1. Validacion Rapida Post-Despliegue
  2. Validacion Completa de Base de Datos
  3. Errores Comunes y Soluciones
  4. Scripts de Diagnostico
  5. Procedimiento de Recuperacion

1. Validacion Rapida Post-Despliegue

1.1 Checklist de Validacion (5 minutos)

Ejecutar estos comandos inmediatamente despues de desplegar:

# Definir conexion
export DATABASE_URL="postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform"

# 1. Verificar conexion a BD
psql "$DATABASE_URL" -c "SELECT version();"

# 2. Verificar schemas creados (deben ser 17+)
psql "$DATABASE_URL" -c "SELECT COUNT(*) as schemas FROM information_schema.schemata WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast');"

# 3. Verificar tenant principal (CRITICO)
psql "$DATABASE_URL" -c "SELECT id, name, slug, is_active FROM auth_management.tenants WHERE slug = 'gamilit-prod';"

# 4. Verificar usuarios cargados
psql "$DATABASE_URL" -c "SELECT COUNT(*) as usuarios FROM auth.users;"

# 5. Verificar health del backend
curl -s http://localhost:3006/api/health | head -20

1.2 Resultados Esperados

Validacion Resultado Esperado Accion si Falla
Conexion BD Version PostgreSQL 16+ Verificar credenciales
Schemas 17 o mas Ejecutar create-database.sh
Tenant Principal 1 fila con is_active=true Ver seccion 3.1
Usuarios 48 o mas Ejecutar seeds de auth
Health Backend {"status":"ok"} Ver logs PM2

2. Validacion Completa de Base de Datos

2.1 Script de Validacion Completa

Crear y ejecutar este script para validacion exhaustiva:

#!/bin/bash
# validate-production-db.sh

DATABASE_URL="${DATABASE_URL:-postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform}"

echo "=============================================="
echo "VALIDACION COMPLETA - BASE DE DATOS GAMILIT"
echo "=============================================="
echo ""

# Funcion para ejecutar query y mostrar resultado
run_check() {
    local description="$1"
    local query="$2"
    local expected="$3"

    result=$(psql "$DATABASE_URL" -t -c "$query" 2>/dev/null | tr -d ' ')

    if [ "$result" == "$expected" ] || [ -z "$expected" ]; then
        echo "✅ $description: $result"
    else
        echo "❌ $description: $result (esperado: $expected)"
    fi
}

echo "=== 1. SCHEMAS ==="
run_check "Total Schemas" "SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast');"

echo ""
echo "=== 2. TABLAS POR SCHEMA ==="
psql "$DATABASE_URL" -c "
SELECT
    table_schema as schema,
    COUNT(*) as tablas
FROM information_schema.tables
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
  AND table_type = 'BASE TABLE'
GROUP BY table_schema
ORDER BY table_schema;
"

echo ""
echo "=== 3. TENANTS (CRITICO) ==="
psql "$DATABASE_URL" -c "SELECT id, name, slug, is_active, subscription_tier FROM auth_management.tenants ORDER BY created_at;"

echo ""
echo "=== 4. USUARIOS ==="
run_check "Usuarios en auth.users" "SELECT COUNT(*) FROM auth.users;"
run_check "Perfiles en auth_management.profiles" "SELECT COUNT(*) FROM auth_management.profiles;"

echo ""
echo "=== 5. CONTENIDO EDUCATIVO ==="
run_check "Modulos" "SELECT COUNT(*) FROM educational_content.modules;"
run_check "Ejercicios" "SELECT COUNT(*) FROM educational_content.exercises;"

echo ""
echo "=== 6. GAMIFICACION ==="
run_check "Rangos Maya" "SELECT COUNT(*) FROM gamification_system.maya_ranks;"
run_check "Logros" "SELECT COUNT(*) FROM gamification_system.achievements;"
run_check "Categorias Tienda" "SELECT COUNT(*) FROM gamification_system.shop_categories;"
run_check "Items Tienda" "SELECT COUNT(*) FROM gamification_system.shop_items;"

echo ""
echo "=== 7. SOCIAL ==="
run_check "Escuelas" "SELECT COUNT(*) FROM social_features.schools;"
run_check "Aulas" "SELECT COUNT(*) FROM social_features.classrooms;"

echo ""
echo "=== 8. CONFIGURACION ==="
run_check "Feature Flags" "SELECT COUNT(*) FROM system_configuration.feature_flags;"
run_check "Parametros Gamificacion" "SELECT COUNT(*) FROM system_configuration.gamification_parameters;"

echo ""
echo "=============================================="
echo "VALIDACION COMPLETADA"
echo "=============================================="

2.2 Valores Esperados Post-Carga

Entidad Tabla Cantidad Minima
Tenants auth_management.tenants 14 (1 principal + 13 usuarios)
Usuarios auth.users 48
Perfiles auth_management.profiles 48
Modulos educational_content.modules 5
Ejercicios educational_content.exercises 23
Rangos Maya gamification_system.maya_ranks 5
Logros gamification_system.achievements 30
Categorias Tienda gamification_system.shop_categories 5
Items Tienda gamification_system.shop_items 20
Escuelas social_features.schools 2
Aulas social_features.classrooms 4
Feature Flags system_configuration.feature_flags 26

3. Errores Comunes y Soluciones

3.1 ERROR: "No hay tenants activos en el sistema"

Sintoma:

POST /api/v1/auth/register → 500 Internal Server Error
"No hay tenants activos en el sistema. Contacte al administrador."

Causa: La tabla auth_management.tenants esta vacia o no tiene tenants con is_active=true.

Diagnostico:

psql "$DATABASE_URL" -c "SELECT COUNT(*) FROM auth_management.tenants WHERE is_active = true;"

Solucion Rapida (SQL directo):

-- Conectar a la BD
psql "$DATABASE_URL"

-- Insertar tenant principal
INSERT INTO auth_management.tenants (
    id, name, slug, domain, logo_url, subscription_tier,
    max_users, max_storage_gb, is_active, settings, metadata,
    created_at, updated_at
) VALUES (
    'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
    'GAMILIT Platform',
    'gamilit-prod',
    'gamilit.com',
    '/assets/logo-gamilit.png',
    'enterprise',
    10000,
    100,
    true,
    '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "features": {"analytics_enabled": true, "gamification_enabled": true, "social_features_enabled": true}}'::jsonb,
    '{"environment": "production", "version": "2.0"}'::jsonb,
    NOW(),
    NOW()
)
ON CONFLICT (id) DO UPDATE SET
    is_active = true,
    updated_at = NOW();

-- Verificar
SELECT id, name, slug, is_active FROM auth_management.tenants;

Solucion Completa (Seeds):

cd /path/to/gamilit/apps/database
psql "$DATABASE_URL" -f seeds/prod/auth_management/01-tenants.sql
psql "$DATABASE_URL" -f seeds/prod/auth_management/02-tenants-production.sql

3.2 ERROR: "relation does not exist"

Sintoma:

ERROR: relation "auth_management.tenants" does not exist

Causa: El DDL no se ejecuto correctamente.

Solucion:

cd /path/to/gamilit/apps/database
./create-database.sh "$DATABASE_URL"

3.3 ERROR: "password authentication failed"

Sintoma:

FATAL: password authentication failed for user "gamilit_user"

Solucion:

# Como usuario postgres
sudo -u postgres psql

# Resetear password
ALTER USER gamilit_user WITH PASSWORD 'nueva_password_segura';

# Verificar
\du gamilit_user

3.4 ERROR: "CORS blocked"

Sintoma:

Access to fetch at 'http://74.208.126.102:3006/api' from origin 'http://74.208.126.102:3005' has been blocked by CORS policy

Diagnostico:

grep CORS_ORIGIN apps/backend/.env.production

Solucion:

# Editar apps/backend/.env.production
CORS_ORIGIN=http://74.208.126.102:3005,http://74.208.126.102,https://74.208.126.102

# Reiniciar backend
pm2 restart gamilit-backend

3.5 ERROR: "Cannot find module"

Sintoma:

Error: Cannot find module '/path/to/dist/main.js'

Solucion:

cd apps/backend
npm install
npm run build
pm2 restart gamilit-backend

4. Scripts de Diagnostico

4.1 Script: Diagnostico Completo del Sistema

Guardar como diagnose-production.sh:

#!/bin/bash
# diagnose-production.sh - Diagnostico completo del sistema GAMILIT

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

DATABASE_URL="${DATABASE_URL:-postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform}"
BACKEND_URL="http://localhost:3006"
FRONTEND_URL="http://localhost:3005"

echo "=============================================="
echo "   DIAGNOSTICO SISTEMA GAMILIT PRODUCCION"
echo "=============================================="
echo ""

# 1. PM2 Status
echo -e "${YELLOW}=== 1. ESTADO PM2 ===${NC}"
pm2 list 2>/dev/null || echo -e "${RED}PM2 no disponible${NC}"
echo ""

# 2. Backend Health
echo -e "${YELLOW}=== 2. HEALTH BACKEND ===${NC}"
health=$(curl -s "$BACKEND_URL/api/health" 2>/dev/null)
if [ -n "$health" ]; then
    echo -e "${GREEN}Backend respondiendo:${NC}"
    echo "$health" | head -5
else
    echo -e "${RED}Backend NO responde${NC}"
fi
echo ""

# 3. Frontend
echo -e "${YELLOW}=== 3. FRONTEND ===${NC}"
frontend_status=$(curl -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL" 2>/dev/null)
if [ "$frontend_status" == "200" ]; then
    echo -e "${GREEN}Frontend OK (HTTP $frontend_status)${NC}"
else
    echo -e "${RED}Frontend ERROR (HTTP $frontend_status)${NC}"
fi
echo ""

# 4. Database Connection
echo -e "${YELLOW}=== 4. CONEXION BASE DE DATOS ===${NC}"
db_version=$(psql "$DATABASE_URL" -t -c "SELECT version();" 2>/dev/null | head -1)
if [ -n "$db_version" ]; then
    echo -e "${GREEN}BD conectada:${NC} $db_version"
else
    echo -e "${RED}No se puede conectar a la BD${NC}"
fi
echo ""

# 5. Critical Tables
echo -e "${YELLOW}=== 5. TABLAS CRITICAS ===${NC}"

check_table() {
    local table=$1
    local count=$(psql "$DATABASE_URL" -t -c "SELECT COUNT(*) FROM $table;" 2>/dev/null | tr -d ' ')
    if [ -n "$count" ] && [ "$count" -gt 0 ]; then
        echo -e "${GREEN}$table: $count registros${NC}"
    else
        echo -e "${RED}$table: VACIO o ERROR${NC}"
    fi
}

check_table "auth_management.tenants"
check_table "auth.users"
check_table "auth_management.profiles"
check_table "educational_content.modules"
check_table "educational_content.exercises"
check_table "gamification_system.maya_ranks"
check_table "gamification_system.achievements"
echo ""

# 6. Tenant Principal
echo -e "${YELLOW}=== 6. TENANT PRINCIPAL (CRITICO) ===${NC}"
tenant=$(psql "$DATABASE_URL" -t -c "SELECT slug, is_active FROM auth_management.tenants WHERE slug = 'gamilit-prod';" 2>/dev/null)
if [ -n "$tenant" ]; then
    echo -e "${GREEN}Tenant encontrado:${NC} $tenant"
else
    echo -e "${RED}❌ TENANT PRINCIPAL NO EXISTE - REGISTRO NO FUNCIONARA${NC}"
    echo -e "${YELLOW}Ejecutar: psql \$DATABASE_URL -f seeds/prod/auth_management/01-tenants.sql${NC}"
fi
echo ""

# 7. Disk Space
echo -e "${YELLOW}=== 7. ESPACIO EN DISCO ===${NC}"
df -h / | tail -1
echo ""

# 8. Memory
echo -e "${YELLOW}=== 8. MEMORIA ===${NC}"
free -h | head -2
echo ""

echo "=============================================="
echo "   DIAGNOSTICO COMPLETADO"
echo "=============================================="

4.2 Script: Reparar Datos Faltantes

Guardar como repair-missing-data.sh:

#!/bin/bash
# repair-missing-data.sh - Reparar datos faltantes en produccion

set -e

DATABASE_URL="${DATABASE_URL:-postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DB_DIR="$SCRIPT_DIR/../apps/database"

echo "=============================================="
echo "   REPARACION DE DATOS FALTANTES"
echo "=============================================="

# 1. Verificar y reparar tenants
echo ""
echo "=== Verificando Tenants ==="
tenant_count=$(psql "$DATABASE_URL" -t -c "SELECT COUNT(*) FROM auth_management.tenants WHERE is_active = true;" | tr -d ' ')

if [ "$tenant_count" -eq 0 ]; then
    echo "❌ No hay tenants activos. Cargando seeds..."
    psql "$DATABASE_URL" -f "$DB_DIR/seeds/prod/auth_management/01-tenants.sql"
    psql "$DATABASE_URL" -f "$DB_DIR/seeds/prod/auth_management/02-tenants-production.sql"
    echo "✅ Tenants cargados"
else
    echo "✅ Tenants OK ($tenant_count activos)"
fi

# 2. Verificar modulos
echo ""
echo "=== Verificando Modulos ==="
module_count=$(psql "$DATABASE_URL" -t -c "SELECT COUNT(*) FROM educational_content.modules;" | tr -d ' ')

if [ "$module_count" -lt 5 ]; then
    echo "❌ Modulos incompletos ($module_count). Cargando..."
    psql "$DATABASE_URL" -f "$DB_DIR/seeds/prod/educational_content/01-modules.sql"
    echo "✅ Modulos cargados"
else
    echo "✅ Modulos OK ($module_count)"
fi

# 3. Verificar rangos maya
echo ""
echo "=== Verificando Rangos Maya ==="
rank_count=$(psql "$DATABASE_URL" -t -c "SELECT COUNT(*) FROM gamification_system.maya_ranks;" | tr -d ' ')

if [ "$rank_count" -lt 5 ]; then
    echo "❌ Rangos Maya incompletos ($rank_count). Cargando..."
    psql "$DATABASE_URL" -f "$DB_DIR/seeds/prod/gamification_system/03-maya_ranks.sql"
    echo "✅ Rangos Maya cargados"
else
    echo "✅ Rangos Maya OK ($rank_count)"
fi

# 4. Verificar feature flags
echo ""
echo "=== Verificando Feature Flags ==="
flag_count=$(psql "$DATABASE_URL" -t -c "SELECT COUNT(*) FROM system_configuration.feature_flags;" | tr -d ' ')

if [ "$flag_count" -lt 20 ]; then
    echo "❌ Feature flags incompletos ($flag_count). Cargando..."
    psql "$DATABASE_URL" -f "$DB_DIR/seeds/prod/system_configuration/01-feature_flags_seeds.sql"
    echo "✅ Feature flags cargados"
else
    echo "✅ Feature flags OK ($flag_count)"
fi

echo ""
echo "=============================================="
echo "   REPARACION COMPLETADA"
echo "=============================================="
echo ""
echo "Reiniciar backend para aplicar cambios:"
echo "  pm2 restart gamilit-backend"

5. Procedimiento de Recuperacion

5.1 Recuperacion Completa (Reset Total)

Si la base de datos esta corrupta o incompleta, seguir estos pasos:

# 1. Detener aplicaciones
pm2 stop all

# 2. Ir al directorio de database
cd /path/to/gamilit/apps/database

# 3. Configurar conexion
export DATABASE_URL="postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform"

# 4. OPCION A: Drop y recrear (ELIMINA TODO)
./drop-and-recreate-database.sh "$DATABASE_URL"

# 4. OPCION B: Solo recrear estructura (si BD nueva)
./create-database.sh "$DATABASE_URL"

# 5. Reiniciar aplicaciones
pm2 start all

# 6. Verificar
curl http://localhost:3006/api/health

5.2 Recuperacion Parcial (Solo Seeds)

Si el DDL esta correcto pero faltan datos:

cd /path/to/gamilit/apps/database
export DATABASE_URL="postgresql://gamilit_user:PASSWORD@localhost:5432/gamilit_platform"

# Cargar seeds en orden
# 1. System Configuration (sin dependencias)
psql "$DATABASE_URL" -f seeds/prod/system_configuration/01-system_settings.sql
psql "$DATABASE_URL" -f seeds/prod/system_configuration/01-feature_flags_seeds.sql
psql "$DATABASE_URL" -f seeds/prod/system_configuration/02-gamification_parameters_seeds.sql

# 2. Auth Management (tenants y auth_providers)
psql "$DATABASE_URL" -f seeds/prod/auth_management/01-tenants.sql
psql "$DATABASE_URL" -f seeds/prod/auth_management/02-tenants-production.sql
psql "$DATABASE_URL" -f seeds/prod/auth_management/02-auth_providers.sql

# 3. Auth (usuarios)
psql "$DATABASE_URL" -f seeds/prod/auth/01-demo-users.sql
psql "$DATABASE_URL" -f seeds/prod/auth/02-production-users.sql

# 4. Educational Content (modulos ANTES de profiles)
psql "$DATABASE_URL" -f seeds/prod/educational_content/01-modules.sql

# 5. Profiles (dispara trigger initialize_user_stats)
psql "$DATABASE_URL" -f seeds/prod/auth_management/04-profiles-complete.sql
psql "$DATABASE_URL" -f seeds/prod/auth_management/06-profiles-production.sql

# 6. Social Features
psql "$DATABASE_URL" -f seeds/prod/social_features/00-schools-default.sql
psql "$DATABASE_URL" -f seeds/prod/social_features/01-schools.sql
psql "$DATABASE_URL" -f seeds/prod/social_features/02-classrooms.sql

# 7. Educational Content (ejercicios)
psql "$DATABASE_URL" -f seeds/prod/educational_content/02-exercises-module1.sql
psql "$DATABASE_URL" -f seeds/prod/educational_content/03-exercises-module2.sql
psql "$DATABASE_URL" -f seeds/prod/educational_content/04-exercises-module3.sql
psql "$DATABASE_URL" -f seeds/prod/educational_content/05-exercises-module4.sql
psql "$DATABASE_URL" -f seeds/prod/educational_content/06-exercises-module5.sql

# 8. Gamification
psql "$DATABASE_URL" -f seeds/prod/gamification_system/01-achievement_categories.sql
psql "$DATABASE_URL" -f seeds/prod/gamification_system/03-maya_ranks.sql
psql "$DATABASE_URL" -f seeds/prod/gamification_system/04-achievements.sql
psql "$DATABASE_URL" -f seeds/prod/gamification_system/12-shop_categories.sql
psql "$DATABASE_URL" -f seeds/prod/gamification_system/13-shop_items.sql

5.3 Orden de Carga de Seeds (Dependencias)

                    ORDEN DE CARGA DE SEEDS

    ┌─────────────────────────────────────────────────┐
    │ 1. system_configuration (sin dependencias)       │
    │    - system_settings                            │
    │    - feature_flags                              │
    │    - gamification_parameters                    │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 2. auth_management/tenants                      │
    │    - 01-tenants.sql (tenant principal)          │
    │    - 02-tenants-production.sql (usuarios)       │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 3. auth/users                                   │
    │    - 01-demo-users.sql                          │
    │    - 02-production-users.sql                    │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 4. educational_content/modules                   │
    │    - 01-modules.sql (ANTES de profiles!)        │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 5. auth_management/profiles                     │
    │    - 04-profiles-complete.sql                   │
    │    - 06-profiles-production.sql                 │
    │    (Dispara trigger initialize_user_stats)      │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 6. social_features                              │
    │    - schools → classrooms → members             │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 7. educational_content/exercises                │
    │    - exercises-module1 a module5                │
    └─────────────────────┬───────────────────────────┘
                          │
                          ▼
    ┌─────────────────────────────────────────────────┐
    │ 8. gamification_system                          │
    │    - maya_ranks, achievements, shop             │
    └─────────────────────────────────────────────────┘

Apendice: Queries de Verificacion Rapida

-- Verificar tenant principal
SELECT id, name, slug, is_active
FROM auth_management.tenants
WHERE slug = 'gamilit-prod';

-- Contar entidades principales
SELECT
    (SELECT COUNT(*) FROM auth_management.tenants) as tenants,
    (SELECT COUNT(*) FROM auth.users) as users,
    (SELECT COUNT(*) FROM auth_management.profiles) as profiles,
    (SELECT COUNT(*) FROM educational_content.modules) as modules,
    (SELECT COUNT(*) FROM educational_content.exercises) as exercises,
    (SELECT COUNT(*) FROM gamification_system.maya_ranks) as ranks,
    (SELECT COUNT(*) FROM gamification_system.achievements) as achievements;

-- Verificar usuarios por rol
SELECT role, COUNT(*)
FROM auth_management.profiles
GROUP BY role;

-- Verificar ejercicios por modulo
SELECT m.name, COUNT(e.id) as exercises
FROM educational_content.modules m
LEFT JOIN educational_content.exercises e ON e.module_id = m.id
GROUP BY m.name
ORDER BY m.order_index;

Contacto

Para problemas no cubiertos en esta guia:

  1. Revisar logs: pm2 logs
  2. Consultar GUIA-DESPLIEGUE-PRODUCCION-COMPLETA.md
  3. Revisar docs/DEPLOYMENT.md

Ultima actualizacion: 2025-12-18 Version: 1.0.0