This commit is contained in:
Lizandro Guarnizo
2026-05-16 13:44:32 -05:00
parent 85595e639e
commit 76a0c28b16
16 changed files with 225 additions and 725 deletions
+101 -176
View File
@@ -81,9 +81,8 @@ func Migrate() {
&models.ProyectoEntregable{},
&models.ProyectoTicket{},
&models.TicketMensaje{},
&models.Factura{}, // Sistema de notificaciones
&models.NotifEventoConfig{},
&models.SistemaNotificacion{}, ); err != nil {
&models.Factura{},
); err != nil {
log.Fatalf("Error during main migration: %v", err)
}
@@ -278,31 +277,6 @@ func SeedPlantillasBase() {
log.Println("[SEED] SeedPlantillasBase completado.")
}
// MigratePortal crea/actualiza las tablas del módulo Portal de Clientes, Proyectos,
// Facturas y Telegram. Es idempotente.
func MigratePortal() {
db := app.Http.Database.DB
if err := db.AutoMigrate(
&models.Roles{}, // agrega columnas es_portal_cliente / es_portal_partner si no existen
&models.TelegramConfig{},
&models.TelegramLog{},
&models.ClienteDocumento{},
&models.PortalUser{},
&models.PortalAcceso{},
&models.Proyecto{},
&models.ProyectoFase{},
&models.ProyectoAvance{},
&models.ProyectoEntregable{},
&models.ProyectoTicket{},
&models.TicketMensaje{},
&models.Factura{},
); err != nil {
log.Printf("[MIGRATE] Error en MigratePortal: %v", err)
} else {
log.Println("[MIGRATE] Tablas de Portal OK")
}
}
// 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() {
@@ -737,7 +711,27 @@ func SeedSaas() {
log.Println("[SEED] Seed de SaaS completado.")
}
// SeedTelegram agrega el submódulo "Telegram" al módulo "Integraciones". Es idempotente.
// MigratePortal ejecuta AutoMigrate para los modelos del portal de clientes.
func MigratePortal() {
db := app.Http.Database.DB
if err := db.AutoMigrate(
&models.Proyecto{},
&models.ProyectoFase{},
&models.ProyectoAvance{},
&models.ProyectoEntregable{},
&models.ProyectoTicket{},
&models.TicketMensaje{},
&models.PortalUser{},
&models.PortalAcceso{},
&models.Factura{},
); err != nil {
log.Printf("[MIGRATE] Error en MigratePortal: %v", err)
} else {
log.Println("[MIGRATE] MigratePortal completado.")
}
}
// SeedTelegram agrega el submódulo de Telegram al módulo "Integraciones". Es idempotente.
func SeedTelegram() {
db := app.Http.Database.DB
@@ -747,160 +741,23 @@ func SeedTelegram() {
return
}
entries := []struct{ title, desc, url string }{
{"Telegram", "Notificaciones y alertas por Telegram", "/app/telegram"},
}
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 Telegram al rol '%s': %v", rol.Name, err)
} else {
log.Printf("[SEED] Telegram asignado al rol '%s'", rol.Name)
}
}
log.Println("[SEED] Seed de Telegram completado.")
}
// SeedPortalClientes crea el módulo "Portal de Clientes" con sus submódulos. Es idempotente.
func SeedPortalClientes() {
db := app.Http.Database.DB
var modulo models.Modules
if err := db.Where("title = ?", "Portal de Clientes").First(&modulo).Error; err != nil {
modulo = models.Modules{
Title: "Portal de Clientes",
Description: "Portal de clientes: proyectos, facturas y accesos",
ModifiedAt: time.Now(),
}
if err := db.Create(&modulo).Error; err != nil {
log.Printf("[SEED] Error creando módulo Portal de Clientes: %v", err)
return
}
log.Printf("[SEED] Módulo 'Portal de Clientes' creado con ID %d", modulo.ID)
} else {
log.Printf("[SEED] Módulo 'Portal de Clientes' ya existe (ID %d)", modulo.ID)
}
entries := []struct{ title, desc, url string }{
{"Proyectos", "Gestión de proyectos y avances del portal", "/app/proyectos"},
{"Facturas", "Gestión de facturas y pagos por cliente", "/app/facturas"},
{"Portal Usuarios", "Usuarios con acceso al portal de clientes", "/app/portal-usuarios"},
{"Tickets", "Tickets de soporte abiertos por clientes del portal", "/app/tickets"},
{"Config. Notificaciones", "Configurar canales de notificación por evento", "/app/notif-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 {
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 Portal al rol '%s': %v", rol.Name, err)
} else {
log.Printf("[SEED] Submódulos de Portal de Clientes asignados al rol '%s'", rol.Name)
}
}
log.Println("[SEED] Seed de Portal de Clientes completado.")
}
// SeedNotifDefaults crea la configuración de notificaciones por defecto. Es idempotente.
func SeedNotifDefaults() {
db := app.Http.Database.DB
defaults := []models.NotifEventoConfig{
{Evento: "ticket_nuevo", Destinatario: "admin", CanalEmail: true, CanalTelegram: false, CanalSistema: true, Descripcion: "Admin recibe cuando el cliente abre un ticket"},
{Evento: "ticket_respuesta_cliente", Destinatario: "admin", CanalEmail: true, CanalTelegram: false, CanalSistema: true, Descripcion: "Admin recibe cuando el cliente responde un ticket"},
{Evento: "ticket_respuesta_admin", Destinatario: "portal_user", CanalEmail: true, CanalTelegram: false, CanalSistema: true, Descripcion: "Cliente recibe cuando el admin responde su ticket"},
{Evento: "factura_subida", Destinatario: "portal_user", CanalEmail: true, CanalTelegram: false, CanalSistema: true, Descripcion: "Cliente recibe cuando el admin sube el PDF de una factura"},
}
for _, cfg := range defaults {
var existing models.NotifEventoConfig
if err := db.Where("evento = ? AND destinatario = ?", cfg.Evento, cfg.Destinatario).First(&existing).Error; err != nil {
if err := db.Create(&cfg).Error; err != nil {
log.Printf("[SEED] Error creando notif config %s/%s: %v", cfg.Evento, cfg.Destinatario, err)
} else {
log.Printf("[SEED] Notif config creada: %s → %s", cfg.Evento, cfg.Destinatario)
}
}
}
log.Println("[SEED] Seed de notificaciones completado.")
}
// SeedShield agrega el submódulo "Shield" al módulo "Integraciones". Es idempotente.
func SeedShield() {
db := app.Http.Database.DB
var modulo models.Modules
if err := db.Where("title = ?", "Integraciones").First(&modulo).Error; err != nil {
log.Printf("[SEED] Módulo 'Integraciones' no encontrado para SeedShield: %v", err)
return
}
url := "/app/telegram"
var sub models.Submodules
if err := db.Where("url = ?", "/app/shield").First(&sub).Error; err != nil {
if err := db.Where("url = ?", url).First(&sub).Error; err != nil {
sub = models.Submodules{
Title: "Shield",
Description: "Administración de la API de seguridad USITE Shield",
Url: "/app/shield",
Title: "Telegram",
Description: "Configuración de bots de Telegram para notificaciones",
Url: url,
ModuleId: modulo.ID,
ModifiedAt: time.Now(),
}
if err := db.Create(&sub).Error; err != nil {
log.Printf("[SEED] Error creando submódulo Shield: %v", err)
if err2 := db.Create(&sub).Error; err2 != nil {
log.Printf("[SEED] Error creando submódulo Telegram: %v", err2)
return
}
log.Printf("[SEED] Submódulo 'Shield' creado (ID %d)", sub.ID)
log.Printf("[SEED] Submódulo 'Telegram' creado (ID %d)", sub.ID)
} else {
log.Printf("[SEED] Submódulo 'Shield' ya existe (ID %d)", sub.ID)
log.Printf("[SEED] Submódulo 'Telegram' ya existe (ID %d)", sub.ID)
}
var roles []models.Roles
@@ -910,5 +767,73 @@ func SeedShield() {
for _, rol := range roles {
db.Model(&rol).Association("Submodules").Append(&sub)
}
log.Println("[SEED] SeedShield completado.")
log.Println("[SEED] Seed de Telegram completado.")
}
// SeedPortalClientes agrega el módulo "Portal de Clientes" con sus submódulos. Es idempotente.
func SeedPortalClientes() {
db := app.Http.Database.DB
var modulo models.Modules
if err := db.Where("title = ?", "Portal de Clientes").First(&modulo).Error; err != nil {
modulo = models.Modules{
Title: "Portal de Clientes",
Description: "Gestión del portal de acceso para clientes",
ModifiedAt: time.Now(),
}
if err2 := db.Create(&modulo).Error; err2 != nil {
log.Printf("[SEED] Error creando módulo 'Portal de Clientes': %v", err2)
return
}
log.Printf("[SEED] Módulo 'Portal de Clientes' creado (ID %d)", modulo.ID)
} else {
log.Printf("[SEED] Módulo 'Portal de Clientes' ya existe (ID %d)", modulo.ID)
}
entries := []struct{ title, desc, url string }{
{"Proyectos", "Gestión de proyectos y roadmap para clientes", "/app/proyectos"},
{"Facturas", "Gestión de facturas y cobros del portal", "/app/facturas"},
{"Portal Usuarios", "Gestión de usuarios del portal de clientes", "/app/portal-usuarios"},
}
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 err2 := db.Create(&sub).Error; err2 != nil {
log.Printf("[SEED] Error creando submódulo '%s': %v", e.title, err2)
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 {
return
}
for _, rol := range roles {
db.Model(&rol).Association("Submodules").Append(&insertados)
}
log.Println("[SEED] Seed de Portal de Clientes completado.")
}
// SeedNotifDefaults es un stub idempotente para configuraciones de notificaciones por defecto.
func SeedNotifDefaults() {
log.Println("[SEED] SeedNotifDefaults: sin entradas por defecto definidas aún.")
}
// SeedShield es un stub idempotente para la configuración de Shield.
func SeedShield() {
log.Println("[SEED] SeedShield: sin entradas por defecto definidas aún.")
}