From 6cd52eb085353439adf259eff2ee1a32c273d5a0 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 1 May 2026 10:49:01 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20endpoint=20/app/run-seed=20para=20inser?= =?UTF-8?q?tar=20m=C3=B3dulos=20sin=20reiniciar=20servidor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rest/controllers/seed_controller.go | 96 +++++++++++++++++++++++++++++ rest/routes/user.go | 3 + 2 files changed, 99 insertions(+) create mode 100644 rest/controllers/seed_controller.go diff --git a/rest/controllers/seed_controller.go b/rest/controllers/seed_controller.go new file mode 100644 index 0000000..7ed3cee --- /dev/null +++ b/rest/controllers/seed_controller.go @@ -0,0 +1,96 @@ +package controllers + +import ( + "log" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/sujit-baniya/fiber-boilerplate/app" + "github.com/sujit-baniya/fiber-boilerplate/pkg/models" +) + +// RunSeed ejecuta el seed de módulos/submodulos del sistema de forma idempotente. +// GET /app/run-seed — requiere sesión activa. +func RunSeed(c *fiber.Ctx) error { + if err := seedModulo("Integraciones", "Conexión con servicios externos: Hostinger, Cloudflare y más", []seedEntry{ + {"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"}, + }); err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) + } + + if err := seedModulo("Renovaciones", "Gestión de contratos, clientes y notificaciones de vencimiento", []seedEntry{ + {"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"}, + }); err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) + } + + return c.JSON(fiber.Map{ + "ok": true, + "message": "Seed ejecutado correctamente. Recarga la página de Roles.", + }) +} + +type seedEntry struct{ title, desc, url string } + +func seedModulo(titulo, descripcion string, entries []seedEntry) error { + db := app.Http.Database.DB + + var modulo models.Modules + if err := db.Where("title = ?", titulo).First(&modulo).Error; err != nil { + modulo = models.Modules{ + Title: titulo, + Description: descripcion, + ModifiedAt: time.Now(), + } + if err := db.Create(&modulo).Error; err != nil { + log.Printf("[SEED] Error creando módulo '%s': %v", titulo, err) + return err + } + log.Printf("[SEED] Módulo '%s' creado (ID %d)", titulo, modulo.ID) + } else { + log.Printf("[SEED] Módulo '%s' ya existe (ID %d)", titulo, modulo.ID) + } + + 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' ya existe (ID %d)", e.title, sub.ID) + } + insertados = append(insertados, sub) + } + + var roles []models.Roles + if err := db.Find(&roles).Error; err != nil { + return err + } + 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) + } + } + return nil +} diff --git a/rest/routes/user.go b/rest/routes/user.go index 5c0b379..84d6cf6 100755 --- a/rest/routes/user.go +++ b/rest/routes/user.go @@ -94,6 +94,9 @@ func UserRoutes(app fiber.Router) { // ─── Módulo de Renovaciones / Contratos ────────────────────────── RenovacionesRoutes(protected) + // ─── Seed manual (admin) ──────────────────────────────────────────── + protected.Get("/run-seed", controllers.RunSeed) + // ─── Hostinger API ──────────────────────────────────────────────── protected.Get("/hostinger", middlewares.MenuMiddleware, controllers.HostingerConfigPage) protected.Post("/hostinger/config", controllers.SaveHostingerConfig)