diff --git a/nuxt4/app/app.vue b/nuxt4/app/app.vue
index e031da5..32e8b34 100644
--- a/nuxt4/app/app.vue
+++ b/nuxt4/app/app.vue
@@ -87,6 +87,21 @@
>
💾 EXPORTAR BACKUP
+
+ 📥 IMPORTAR BACKUP
+
+
Resultados en consola (F12). Recarga la página después de usar estos botones.
@@ -459,6 +474,8 @@ const resettingDB = ref(false)
const seedingDB = ref(false)
const clearingData = ref(false)
const exportingDB = ref(false)
+const importingDB = ref(false)
+const fileInputRef = ref(null)
const resetDatabase = async () => {
if (!confirm('⚠️ ADVERTENCIA: Esto BORRARÁ TODOS LOS DATOS de la base de datos.\n\n¿Estás seguro de continuar?')) {
@@ -574,6 +591,61 @@ const exportDatabase = async () => {
exportingDB.value = false
}
}
+
+const triggerFileInput = () => {
+ fileInputRef.value?.click()
+}
+
+const importDatabase = async (event: Event) => {
+ const input = event.target as HTMLInputElement
+ const file = input.files?.[0]
+
+ if (!file) {
+ return
+ }
+
+ if (!file.name.endsWith('.sql')) {
+ alert('⚠️ Por favor selecciona un archivo .sql')
+ input.value = ''
+ return
+ }
+
+ if (!confirm('⚠️ ADVERTENCIA: Esto REEMPLAZARÁ TODA LA BASE DE DATOS con el contenido del backup.\n\nSe eliminará todo lo existente y se cargará el backup.\n\n¿Estás seguro de continuar?')) {
+ input.value = ''
+ return
+ }
+
+ console.log('📥 === IMPORTANDO BACKUP DE BASE DE DATOS ===')
+ console.log(` - Archivo: ${file.name}`)
+ console.log(` - Tamaño: ${(file.size / 1024).toFixed(2)} KB`)
+ importingDB.value = true
+
+ try {
+ const formData = new FormData()
+ formData.append('file', file)
+
+ const response = await fetch('/api/debug/import-database', {
+ method: 'POST',
+ body: formData,
+ })
+
+ const data = await response.json()
+ console.log('Status:', response.status)
+ console.log('Respuesta:', data)
+
+ if (data.success) {
+ alert('✅ Backup importado exitosamente.\n\nLa base de datos ha sido restaurada.\n\nRecarga la página para ver los cambios.')
+ } else {
+ throw new Error(data.message || 'Error desconocido')
+ }
+ } catch (error: any) {
+ console.error('❌ Error:', error)
+ alert(`❌ Error importando backup: ${error.message || 'Ver consola para más detalles'}`)
+ } finally {
+ importingDB.value = false
+ input.value = '' // Limpiar el input
+ }
+}
// ⚠️⚠️⚠️ FIN FUNCIONES DE DEBUG ⚠️⚠️⚠️
// Funciones de prueba de API
diff --git a/nuxt4/server/api/debug/import-database.post.ts b/nuxt4/server/api/debug/import-database.post.ts
new file mode 100644
index 0000000..fc35c86
--- /dev/null
+++ b/nuxt4/server/api/debug/import-database.post.ts
@@ -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 },
+ })
+ }
+})