Agregar funcionalidad de importación de backups
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
Implementa la capacidad de restaurar la base de datos desde un archivo SQL de backup exportado previamente. Cambios: Backend: - Nuevo endpoint POST /api/debug/import-database.post.ts - Recibe archivo .sql via multipart/form-data - Ejecuta el SQL del backup (que incluye DROP y CREATE) - Reemplaza completamente la base de datos existente Frontend: - Nuevo botón verde "📥 IMPORTAR BACKUP" - Input file oculto con accept=".sql" - Validación de extensión de archivo - Confirmación con advertencia clara - Estado de carga durante importación Flujo de uso: 1. Usuario hace click en "📥 IMPORTAR BACKUP" 2. Selecciona archivo .sql previamente exportado 3. Confirma que desea reemplazar toda la BD 4. Sistema ejecuta el SQL completo 5. Muestra mensaje de éxito/error 6. Usuario recarga la página Esto completa el ciclo backup/restore permitiendo recuperación completa del estado de la base de datos.
This commit is contained in:
97
nuxt4/server/api/debug/import-database.post.ts
Normal file
97
nuxt4/server/api/debug/import-database.post.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* ⚠️ ⚠️ ⚠️ ENDPOINT DE DEBUG - TEMPORAL ⚠️ ⚠️ ⚠️
|
||||
*
|
||||
* POST /api/debug/import-database
|
||||
*
|
||||
* IMPORTA UN BACKUP SQL COMPLETO (reemplaza todo lo existente)
|
||||
*
|
||||
* ⚠️ 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('📥 IMPORT DATABASE - Importando backup SQL...')
|
||||
|
||||
// Leer el archivo del request
|
||||
const formData = await readMultipartFormData(event)
|
||||
|
||||
if (!formData || formData.length === 0) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'No se recibió ningún archivo',
|
||||
data: { message: 'Debes enviar un archivo .sql en el campo "file"' },
|
||||
})
|
||||
}
|
||||
|
||||
const fileData = formData.find(item => item.name === 'file')
|
||||
|
||||
if (!fileData) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Campo "file" no encontrado',
|
||||
data: { message: 'El archivo debe enviarse en el campo "file"' },
|
||||
})
|
||||
}
|
||||
|
||||
const sqlContent = fileData.data.toString('utf-8')
|
||||
const fileSize = (sqlContent.length / 1024).toFixed(2)
|
||||
|
||||
console.log(` - Archivo recibido: ${fileData.filename || 'sin nombre'}`)
|
||||
console.log(` - Tamaño: ${fileSize} KB`)
|
||||
|
||||
if (!sqlContent.trim()) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Archivo vacío',
|
||||
data: { message: 'El archivo SQL está vacío' },
|
||||
})
|
||||
}
|
||||
|
||||
const client = await getClient()
|
||||
|
||||
try {
|
||||
await client.query('BEGIN')
|
||||
|
||||
console.log(' - Ejecutando SQL del backup...')
|
||||
console.log(' - ADVERTENCIA: Esto eliminará y recreará todas las tablas')
|
||||
|
||||
// Ejecutar el SQL del backup
|
||||
// Los backups de pg_dump con --clean --if-exists ya incluyen los DROP necesarios
|
||||
await client.query(sqlContent)
|
||||
|
||||
await client.query('COMMIT')
|
||||
|
||||
console.log('✅ Backup importado exitosamente')
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Backup importado exitosamente. La base de datos ha sido restaurada.',
|
||||
file_size: fileSize,
|
||||
filename: fileData.filename || 'sin nombre',
|
||||
}
|
||||
} catch (error) {
|
||||
await client.query('ROLLBACK')
|
||||
throw error
|
||||
} finally {
|
||||
client.release()
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('❌ Error importando backup:', error)
|
||||
|
||||
// Si el error ya es un createError, reusarlo
|
||||
if (error.statusCode) {
|
||||
throw error
|
||||
}
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Error importando backup',
|
||||
data: { message: error.message },
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user