Feat: agregar botones de debug para limpiar datos y exportar backup
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s
- Agregar botón 'LIMPIAR DATOS' que hace TRUNCATE de tablas sin borrar estructura - Agregar botón 'EXPORTAR BACKUP' que descarga pg_dump completo de la BD - Crear endpoint POST /api/debug/clear-data para TRUNCATE CASCADE - Crear endpoint POST /api/debug/export-database para pg_dump con descarga - Mantener estructura de botones temporales de debug existentes - Incluir confirmaciones y manejo de errores apropiados
This commit is contained in:
57
nuxt4/server/api/debug/clear-data.post.ts
Normal file
57
nuxt4/server/api/debug/clear-data.post.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* ⚠️ ⚠️ ⚠️ ENDPOINT DE DEBUG - TEMPORAL ⚠️ ⚠️ ⚠️
|
||||
*
|
||||
* POST /api/debug/clear-data
|
||||
*
|
||||
* ELIMINA TODOS LOS DATOS DE LAS TABLAS (TRUNCATE) SIN BORRAR LA ESTRUCTURA
|
||||
*
|
||||
* ⚠️ NO ELIMINAR SIN CONSULTAR A DARIO/DRAGANEL/NUCLEO000 ⚠️
|
||||
*
|
||||
* Este endpoint fue creado para desarrollo y debugging.
|
||||
* Antes de eliminarlo, preguntar si todavía es necesario.
|
||||
*/
|
||||
|
||||
import { getClient } from '../../utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
console.log('🧹 CLEAR DATA - Eliminando todos los datos de las tablas...')
|
||||
|
||||
const client = await getClient()
|
||||
|
||||
try {
|
||||
await client.query('BEGIN')
|
||||
|
||||
// Eliminar datos de todas las tablas en orden correcto (respetar foreign keys)
|
||||
console.log(' - Truncando operacion_lotes...')
|
||||
await client.query('TRUNCATE TABLE operacion_lotes CASCADE')
|
||||
|
||||
console.log(' - Truncando operaciones...')
|
||||
await client.query('TRUNCATE TABLE operaciones CASCADE')
|
||||
|
||||
console.log(' - Truncando lotes...')
|
||||
await client.query('TRUNCATE TABLE lotes CASCADE')
|
||||
|
||||
await client.query('COMMIT')
|
||||
|
||||
console.log('✅ Datos eliminados exitosamente. Las tablas están vacías pero la estructura se mantiene.')
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Datos eliminados exitosamente. Las tablas están vacías.',
|
||||
}
|
||||
} catch (error) {
|
||||
await client.query('ROLLBACK')
|
||||
throw error
|
||||
} finally {
|
||||
client.release()
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('❌ Error limpiando datos:', error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Error limpiando datos',
|
||||
data: { message: error.message },
|
||||
})
|
||||
}
|
||||
})
|
||||
100
nuxt4/server/api/debug/export-database.post.ts
Normal file
100
nuxt4/server/api/debug/export-database.post.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* ⚠️ ⚠️ ⚠️ ENDPOINT DE DEBUG - TEMPORAL ⚠️ ⚠️ ⚠️
|
||||
*
|
||||
* POST /api/debug/export-database
|
||||
*
|
||||
* EXPORTA TODA LA BASE DE DATOS A UN ARCHIVO SQL (pg_dump)
|
||||
*
|
||||
* ⚠️ NO ELIMINAR SIN CONSULTAR A DARIO/DRAGANEL/NUCLEO000 ⚠️
|
||||
*
|
||||
* Este endpoint fue creado para desarrollo y debugging.
|
||||
* Antes de eliminarlo, preguntar si todavía es necesario.
|
||||
*/
|
||||
|
||||
import { exec } from 'child_process'
|
||||
import { promisify } from 'util'
|
||||
|
||||
const execAsync = promisify(exec)
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
console.log('💾 EXPORT DATABASE - Generando backup con pg_dump...')
|
||||
|
||||
// Obtener credenciales de la base de datos
|
||||
const config = useRuntimeConfig()
|
||||
let host: string
|
||||
let port: string
|
||||
let database: string
|
||||
let user: string
|
||||
let password: string
|
||||
|
||||
if (config.postgresUrl) {
|
||||
// Parsear la URL de conexión
|
||||
const url = new URL(config.postgresUrl)
|
||||
host = url.hostname
|
||||
port = url.port || '5432'
|
||||
database = url.pathname.slice(1)
|
||||
user = url.username
|
||||
password = url.password
|
||||
} else {
|
||||
// Fallback a variables de entorno
|
||||
const defaultHost = process.env.APP_NAME ? `${process.env.APP_NAME}-postgres` : 'postgres'
|
||||
host = process.env.POSTGRES_HOST || defaultHost
|
||||
port = process.env.POSTGRES_PORT || '5432'
|
||||
database = process.env.POSTGRES_DB || 'seguidor_lotes'
|
||||
user = process.env.POSTGRES_USER || 'seguidor'
|
||||
password = process.env.POSTGRES_PASSWORD || 'seguidor_password'
|
||||
}
|
||||
|
||||
console.log(` - Host: ${host}`)
|
||||
console.log(` - Puerto: ${port}`)
|
||||
console.log(` - Base de datos: ${database}`)
|
||||
console.log(` - Usuario: ${user}`)
|
||||
|
||||
// Generar timestamp para el nombre del archivo
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
|
||||
const filename = `backup-seguidordelotes-${timestamp}.sql`
|
||||
|
||||
// Ejecutar pg_dump
|
||||
// Usar PGPASSWORD en la variable de entorno para evitar prompt de contraseña
|
||||
const command = `PGPASSWORD="${password}" pg_dump -h ${host} -p ${port} -U ${user} -d ${database} --clean --if-exists --no-owner --no-acl`
|
||||
|
||||
console.log(' - Ejecutando pg_dump...')
|
||||
const { stdout, stderr } = await execAsync(command, {
|
||||
maxBuffer: 50 * 1024 * 1024, // 50MB buffer para backups grandes
|
||||
})
|
||||
|
||||
if (stderr && !stderr.includes('NOTICE')) {
|
||||
console.warn('⚠️ Advertencias de pg_dump:', stderr)
|
||||
}
|
||||
|
||||
console.log('✅ Backup generado exitosamente')
|
||||
console.log(` - Tamaño: ${(stdout.length / 1024).toFixed(2)} KB`)
|
||||
|
||||
// Establecer headers para descarga
|
||||
setResponseHeader(event, 'Content-Type', 'application/sql')
|
||||
setResponseHeader(event, 'Content-Disposition', `attachment; filename="${filename}"`)
|
||||
setResponseHeader(event, 'Content-Length', stdout.length.toString())
|
||||
|
||||
return stdout
|
||||
} catch (error: any) {
|
||||
console.error('❌ Error exportando base de datos:', error)
|
||||
|
||||
// Si el error es porque pg_dump no está disponible
|
||||
if (error.message?.includes('pg_dump') && error.message?.includes('not found')) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'pg_dump no está disponible',
|
||||
data: {
|
||||
message: 'El comando pg_dump no está disponible en el servidor. Asegúrate de que PostgreSQL client tools estén instalados.',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Error exportando base de datos',
|
||||
data: { message: error.message },
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user