470 lines
15 KiB
Go
Executable File
470 lines
15 KiB
Go
Executable File
package migrations
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/sujit-baniya/fiber-boilerplate/app"
|
|
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Session structure for managing sessions
|
|
type Session struct {
|
|
ID uint `gorm:"primaryKey"`
|
|
SessionID string `gorm:"unique;not null"`
|
|
Data string `gorm:"type:text"`
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
ExpireAt time.Time
|
|
}
|
|
|
|
// Migrate performs the database migrations
|
|
func Migrate() {
|
|
log.Println("Initiating migration...")
|
|
|
|
// Migrate the main application models
|
|
if err := app.Http.Database.DB.Migrator().AutoMigrate(
|
|
&models.Roles{},
|
|
&models.Users{},
|
|
&models.Modules{},
|
|
&models.Submodules{},
|
|
&models.Inicio{},
|
|
&models.TipoServidor{},
|
|
&models.TipoDb{},
|
|
&models.Servidor{},
|
|
&models.ConxDb{},
|
|
&models.ConxSsh{},
|
|
&models.ProvServidor{},
|
|
&models.QrVcard{},
|
|
&models.OssApi{},
|
|
&models.VcfVcard{},
|
|
&models.DlocalApi{},
|
|
// Módulo de Renovaciones
|
|
&models.Servicio{},
|
|
&models.Cliente{},
|
|
&models.PlantillaCorreo{},
|
|
&models.NotificacionRegla{},
|
|
&models.Contrato{},
|
|
&models.NotificacionLog{},
|
|
&models.SmtpConfig{},
|
|
// Integraciones externas
|
|
&models.HostingerConfig{},
|
|
&models.CloudflareConfig{},
|
|
// Query Runner
|
|
&models.QueryHistory{},
|
|
// Pasarelas de pago
|
|
&models.BoldConfig{},
|
|
&models.BoldWebhookLog{},
|
|
); err != nil {
|
|
log.Fatalf("Error during main migration: %v", err)
|
|
}
|
|
|
|
// Open (or create) a SQLite database for sessions
|
|
db, err := gorm.Open(sqlite.Open("session.db"), &gorm.Config{})
|
|
if err != nil {
|
|
log.Fatalf("Error connecting to the database: %v", err)
|
|
return
|
|
}
|
|
|
|
// Migrate the Session structure
|
|
if err := db.AutoMigrate(&Session{}); err != nil {
|
|
log.Fatalf("Error migrating session database: %v", err)
|
|
return
|
|
}
|
|
|
|
fmt.Println("Session database created and table migrated successfully.")
|
|
|
|
// Insertar módulo y submódulos de Renovaciones
|
|
SeedRenovaciones()
|
|
|
|
// Insertar módulo y submódulos de Integraciones externas
|
|
SeedIntegraciones()
|
|
|
|
// Insertar submódulo "Pasarelas de Pago" en el módulo Integraciones
|
|
SeedPasarelas()
|
|
|
|
log.Println("Migration Completed...")
|
|
}
|
|
|
|
// MigrateRenovaciones crea/actualiza las tablas del módulo de Renovaciones.
|
|
// Es idempotente: GORM AutoMigrate solo añade columnas/tablas nuevas, nunca las borra.
|
|
func MigrateRenovaciones() {
|
|
db := app.Http.Database.DB
|
|
if err := db.AutoMigrate(
|
|
&models.Servicio{},
|
|
&models.Cliente{},
|
|
&models.PlantillaCorreo{},
|
|
&models.NotificacionRegla{},
|
|
&models.Contrato{}, // incluye columnas enlace_pago y enlace_pago_link_id
|
|
&models.NotificacionLog{},
|
|
&models.SmtpConfig{},
|
|
); err != nil {
|
|
log.Printf("[MIGRATE] Error en MigrateRenovaciones: %v", err)
|
|
} else {
|
|
log.Println("[MIGRATE] Tablas de Renovaciones OK")
|
|
}
|
|
}
|
|
|
|
// SeedRenovaciones inserta el módulo "Renovaciones" y sus submódulos si no existen,
|
|
// y los asigna a todos los roles presentes en la BD.
|
|
func SeedRenovaciones() {
|
|
db := app.Http.Database.DB
|
|
|
|
// 1. Crear/obtener módulo
|
|
var modulo models.Modules
|
|
result := db.Where("title = ?", "Renovaciones").First(&modulo)
|
|
if result.Error != nil {
|
|
modulo = models.Modules{
|
|
Title: "Renovaciones",
|
|
Description: "Gestión de contratos, clientes y notificaciones de vencimiento",
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&modulo).Error; err != nil {
|
|
log.Printf("[SEED] Error creando módulo Renovaciones: %v", err)
|
|
return
|
|
}
|
|
log.Printf("[SEED] Módulo 'Renovaciones' creado con ID %d", modulo.ID)
|
|
} else {
|
|
log.Printf("[SEED] Módulo 'Renovaciones' ya existe (ID %d)", modulo.ID)
|
|
}
|
|
|
|
// 2. Definir submódulos
|
|
entries := []struct{ title, desc, url string }{
|
|
{"Contratos", "Gestión de contratos y vencimientos", "/app/contratos"},
|
|
{"Clientes", "Clientes y datos de contacto", "/app/clientes"},
|
|
{"Servicios", "Catálogo de servicios", "/app/servicios"},
|
|
{"Plantillas Correo", "Editor de plantillas de correo", "/app/plantillas-correo"},
|
|
{"Reglas de Aviso", "Reglas de notificación automática", "/app/reglas-notificacion"},
|
|
{"Historial Notif.", "Historial de correos enviados", "/app/historial-notificaciones"},
|
|
{"Config. SMTP", "Configuración del servidor de correo", "/app/smtp-config"},
|
|
}
|
|
|
|
var insertados []models.Submodules
|
|
for _, e := range entries {
|
|
var sub models.Submodules
|
|
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
|
sub = models.Submodules{
|
|
Title: e.title,
|
|
Description: e.desc,
|
|
Url: e.url,
|
|
ModuleId: modulo.ID,
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&sub).Error; err != nil {
|
|
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
|
continue
|
|
}
|
|
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
|
} else {
|
|
// Asegurar que el submódulo apunte al módulo correcto (Renovaciones)
|
|
if sub.ModuleId != modulo.ID {
|
|
if err := db.Model(&sub).Update("module_id", modulo.ID).Error; err != nil {
|
|
log.Printf("[SEED] Error actualizando module_id de '%s': %v", sub.Title, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' reasignado a módulo Renovaciones", sub.Title)
|
|
}
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
|
}
|
|
}
|
|
insertados = append(insertados, sub)
|
|
}
|
|
|
|
// 3. Asignar a todos los roles existentes
|
|
var roles []models.Roles
|
|
if err := db.Find(&roles).Error; err != nil {
|
|
log.Printf("[SEED] Error obteniendo roles: %v", err)
|
|
return
|
|
}
|
|
for _, rol := range roles {
|
|
if err := db.Model(&rol).Association("Submodules").Append(&insertados); err != nil {
|
|
log.Printf("[SEED] Error asignando submódulos al rol '%s': %v", rol.Name, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulos de Renovaciones asignados al rol '%s'", rol.Name)
|
|
}
|
|
}
|
|
|
|
log.Println("[SEED] Seed de Renovaciones completado.")
|
|
}
|
|
|
|
// SeedIntegraciones crea el módulo "Integraciones" con los submódulos
|
|
// de Hostinger y Cloudflare, y los asigna a todos los roles existentes.
|
|
// Es idempotente: si el registro ya existe (por URL) lo reutiliza sin duplicar.
|
|
func SeedIntegraciones() {
|
|
db := app.Http.Database.DB
|
|
|
|
// 1. Crear/obtener módulo
|
|
var modulo models.Modules
|
|
if err := db.Where("title = ?", "Integraciones").First(&modulo).Error; err != nil {
|
|
modulo = models.Modules{
|
|
Title: "Integraciones",
|
|
Description: "Conexión con servicios externos: Hostinger, Cloudflare y más",
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&modulo).Error; err != nil {
|
|
log.Printf("[SEED] Error creando módulo Integraciones: %v", err)
|
|
return
|
|
}
|
|
log.Printf("[SEED] Módulo 'Integraciones' creado con ID %d", modulo.ID)
|
|
} else {
|
|
log.Printf("[SEED] Módulo 'Integraciones' ya existe (ID %d)", modulo.ID)
|
|
}
|
|
|
|
// 2. Definir submódulos
|
|
entries := []struct{ title, desc, url string }{
|
|
{"Hostinger", "Panel de VPS, dominios, hosting y DNS de Hostinger", "/app/hostinger"},
|
|
{"Cloudflare", "Gestión de zonas, DNS, SSL y firewall en Cloudflare", "/app/cloudflare"},
|
|
}
|
|
|
|
var insertados []models.Submodules
|
|
for _, e := range entries {
|
|
var sub models.Submodules
|
|
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
|
sub = models.Submodules{
|
|
Title: e.title,
|
|
Description: e.desc,
|
|
Url: e.url,
|
|
ModuleId: modulo.ID,
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&sub).Error; err != nil {
|
|
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
|
continue
|
|
}
|
|
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
|
} else {
|
|
if sub.ModuleId != modulo.ID {
|
|
if err := db.Model(&sub).Update("module_id", modulo.ID).Error; err != nil {
|
|
log.Printf("[SEED] Error actualizando module_id de '%s': %v", sub.Title, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' reasignado a módulo Integraciones", sub.Title)
|
|
}
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
|
}
|
|
}
|
|
insertados = append(insertados, sub)
|
|
}
|
|
|
|
// 3. Asignar a todos los roles existentes
|
|
var roles []models.Roles
|
|
if err := db.Find(&roles).Error; err != nil {
|
|
log.Printf("[SEED] Error obteniendo roles: %v", err)
|
|
return
|
|
}
|
|
for _, rol := range roles {
|
|
if err := db.Model(&rol).Association("Submodules").Append(&insertados); err != nil {
|
|
log.Printf("[SEED] Error asignando submódulos al rol '%s': %v", rol.Name, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulos de Integraciones asignados al rol '%s'", rol.Name)
|
|
}
|
|
}
|
|
|
|
log.Println("[SEED] Seed de Integraciones completado.")
|
|
}
|
|
|
|
// SeedPasarelas agrega el submódulo "Pasarelas de Pago" al módulo "Integraciones"
|
|
// y lo asigna a todos los roles. Es idempotente.
|
|
func SeedPasarelas() {
|
|
db := app.Http.Database.DB
|
|
|
|
// Obtener el módulo "Integraciones" (debe existir luego de SeedIntegraciones)
|
|
var modulo models.Modules
|
|
if err := db.Where("title = ?", "Integraciones").First(&modulo).Error; err != nil {
|
|
log.Printf("[SEED] Módulo 'Integraciones' no encontrado para SeedPasarelas: %v", err)
|
|
return
|
|
}
|
|
|
|
entries := []struct{ title, desc, url string }{
|
|
{"Pasarelas de Pago", "Configuración de Bold, dLocal y otras pasarelas", "/app/pasarelas-pago"},
|
|
}
|
|
|
|
var insertados []models.Submodules
|
|
for _, e := range entries {
|
|
var sub models.Submodules
|
|
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
|
sub = models.Submodules{
|
|
Title: e.title,
|
|
Description: e.desc,
|
|
Url: e.url,
|
|
ModuleId: modulo.ID,
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&sub).Error; err != nil {
|
|
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
|
continue
|
|
}
|
|
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
|
}
|
|
insertados = append(insertados, sub)
|
|
}
|
|
|
|
var roles []models.Roles
|
|
if err := db.Find(&roles).Error; err != nil {
|
|
log.Printf("[SEED] Error obteniendo roles: %v", err)
|
|
return
|
|
}
|
|
for _, rol := range roles {
|
|
if err := db.Model(&rol).Association("Submodules").Append(&insertados); err != nil {
|
|
log.Printf("[SEED] Error asignando submódulos al rol '%s': %v", rol.Name, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo Pasarelas asignado al rol '%s'", rol.Name)
|
|
}
|
|
}
|
|
|
|
log.Println("[SEED] Seed de Pasarelas completado.")
|
|
}
|
|
|
|
// SeedServidores crea el módulo "Servidores" con los submódulos de gestión
|
|
// de servidores, conexiones SSH/DB, tipos y el Query Runner. Es idempotente.
|
|
func SeedServidores() {
|
|
db := app.Http.Database.DB
|
|
|
|
// 1. Crear/obtener módulo
|
|
var modulo models.Modules
|
|
if err := db.Where("title = ?", "Servidores").First(&modulo).Error; err != nil {
|
|
modulo = models.Modules{
|
|
Title: "Servidores",
|
|
Description: "Gestión de servidores, conexiones de base de datos y Query Runner",
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&modulo).Error; err != nil {
|
|
log.Printf("[SEED] Error creando módulo Servidores: %v", err)
|
|
return
|
|
}
|
|
log.Printf("[SEED] Módulo 'Servidores' creado con ID %d", modulo.ID)
|
|
} else {
|
|
log.Printf("[SEED] Módulo 'Servidores' ya existe (ID %d)", modulo.ID)
|
|
}
|
|
|
|
// 2. Definir submódulos
|
|
entries := []struct{ title, desc, url string }{
|
|
{"Servidores", "Lista y gestión de servidores registrados", "/app/servidor"},
|
|
{"Conexión DB", "Conexiones de base de datos a servidores", "/app/conexion_db"},
|
|
{"Conexión SSH", "Conexiones SSH a servidores", "/app/conexion_ssh"},
|
|
{"Tipo DB", "Catálogo de tipos de base de datos", "/app/tipo_db"},
|
|
{"Tipo Servidor", "Catálogo de tipos de servidor", "/app/tipo_servidor"},
|
|
{"Proveedor Servidor", "Catálogo de proveedores de servidor", "/app/prov_servidor"},
|
|
{"Query Runner", "Editor SQL con historial y exportación", "/app/query-runner"},
|
|
}
|
|
|
|
var insertados []models.Submodules
|
|
for _, e := range entries {
|
|
var sub models.Submodules
|
|
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
|
sub = models.Submodules{
|
|
Title: e.title,
|
|
Description: e.desc,
|
|
Url: e.url,
|
|
ModuleId: modulo.ID,
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&sub).Error; err != nil {
|
|
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
|
continue
|
|
}
|
|
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
|
} else {
|
|
if sub.ModuleId != modulo.ID {
|
|
db.Model(&sub).Update("module_id", modulo.ID)
|
|
log.Printf("[SEED] Submódulo '%s' reasignado a módulo Servidores", sub.Title)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
|
}
|
|
}
|
|
insertados = append(insertados, sub)
|
|
}
|
|
|
|
// 3. Asignar a todos los roles existentes
|
|
var roles []models.Roles
|
|
if err := db.Find(&roles).Error; err != nil {
|
|
log.Printf("[SEED] Error obteniendo roles: %v", err)
|
|
return
|
|
}
|
|
for _, rol := range roles {
|
|
if err := db.Model(&rol).Association("Submodules").Append(&insertados); err != nil {
|
|
log.Printf("[SEED] Error asignando submódulos al rol '%s': %v", rol.Name, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulos de Servidores asignados al rol '%s'", rol.Name)
|
|
}
|
|
}
|
|
|
|
log.Println("[SEED] Seed de Servidores completado.")
|
|
}
|
|
|
|
// SeedAdministracion crea el módulo "Administración" con sus submódulos
|
|
// (Roles, Módulos, Submódulos, Usuarios) y los asigna a todos los roles. Es idempotente.
|
|
func SeedAdministracion() {
|
|
db := app.Http.Database.DB
|
|
|
|
var modulo models.Modules
|
|
if err := db.Where("title = ?", "Administración").First(&modulo).Error; err != nil {
|
|
modulo = models.Modules{
|
|
Title: "Administración",
|
|
Description: "Gestión de usuarios, roles, módulos y permisos del sistema",
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&modulo).Error; err != nil {
|
|
log.Printf("[SEED] Error creando módulo Administración: %v", err)
|
|
return
|
|
}
|
|
log.Printf("[SEED] Módulo 'Administración' creado con ID %d", modulo.ID)
|
|
} else {
|
|
log.Printf("[SEED] Módulo 'Administración' ya existe (ID %d)", modulo.ID)
|
|
}
|
|
|
|
entries := []struct{ title, desc, url string }{
|
|
{"Roles", "Gestión de roles y permisos", "/app/roles"},
|
|
{"Módulos", "Gestión de módulos del menú lateral", "/app/modules"},
|
|
{"Submódulos", "Gestión de submódulos y URLs", "/app/submodules"},
|
|
{"Usuarios", "Gestión de usuarios del sistema", "/app/users"},
|
|
}
|
|
|
|
var insertados []models.Submodules
|
|
for _, e := range entries {
|
|
var sub models.Submodules
|
|
if err := db.Where("url = ?", e.url).First(&sub).Error; err != nil {
|
|
sub = models.Submodules{
|
|
Title: e.title,
|
|
Description: e.desc,
|
|
Url: e.url,
|
|
ModuleId: modulo.ID,
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&sub).Error; err != nil {
|
|
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err)
|
|
continue
|
|
}
|
|
log.Printf("[SEED] Submódulo '%s' creado (ID %d)", e.title, sub.ID)
|
|
} else {
|
|
if sub.ModuleId != modulo.ID {
|
|
db.Model(&sub).Update("module_id", modulo.ID)
|
|
log.Printf("[SEED] Submódulo '%s' reasignado a módulo Administración", sub.Title)
|
|
} else {
|
|
log.Printf("[SEED] Submódulo '%s' ya existe (ID %d)", sub.Title, sub.ID)
|
|
}
|
|
}
|
|
insertados = append(insertados, sub)
|
|
}
|
|
|
|
var roles []models.Roles
|
|
if err := db.Find(&roles).Error; err != nil {
|
|
log.Printf("[SEED] Error obteniendo roles: %v", err)
|
|
return
|
|
}
|
|
for _, rol := range roles {
|
|
if err := db.Model(&rol).Association("Submodules").Append(&insertados); err != nil {
|
|
log.Printf("[SEED] Error asignando submódulos al rol '%s': %v", rol.Name, err)
|
|
} else {
|
|
log.Printf("[SEED] Submódulos de Administración asignados al rol '%s'", rol.Name)
|
|
}
|
|
}
|
|
|
|
log.Println("[SEED] Seed de Administración completado.")
|
|
}
|