Files
soft_usite/rest/routes/user.go
T
Lizandro GuarnizoandClaude Sonnet 5 da0bffe661 feat: orquestador uMind (SPA Vue) + tools custom + canales Telegram/WhatsApp
SPA nueva en /orchestrator (Vue 3 + Vite, servida por el mismo binario Go
bajo /orchestrator para que la cookie de sesión funcione sin tocar CORS),
reemplaza al panel Alpine.js como punto de entrada del menú.

Backend, todo aditivo sobre el motor de uMind ya existente:
- UmindHerramienta: tools custom por tenant que llaman un webhook HTTP,
  integradas al loop de function-calling existente. Cliente HTTP con
  guardas SSRF (bloqueo de IPs privadas/loopback/link-local resuelto en el
  momento de conectar, no antes, para cerrar la ventana de DNS rebinding)
  que no existían en el proyecto.
- UmindCanal: Telegram y WhatsApp Business Cloud API como canales
  adicionales del mismo agente que ya atiende el widget web, ambos
  reusando ProcessWidgetMessage. WhatsApp valida X-Hub-Signature-256.
  Credenciales cifradas en reposo con el mismo AES-GCM+APP_KEY que ya usa
  el proyecto para la contraseña SMTP (primer uso para secretos de uMind).
- Se conecta middlewares.Limit() (rate limiter que existía pero no se
  usaba en ningún lado) al widget público y a los webhooks nuevos.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 22:16:20 -05:00

620 lines
42 KiB
Go
Executable File

package routes
import (
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/rest/controllers"
apiControllers "github.com/sujit-baniya/fiber-boilerplate/rest/controllers/api"
"github.com/sujit-baniya/fiber-boilerplate/rest/middlewares"
)
func UserRoutes(app fiber.Router) {
protected := app.Group("/app").
Use(
middlewares.AuthWeb(), // Middleware de autenticación
middlewares.LoadUserMiddleware, // Middleware para cargar el usuario
)
// Perfil del usuario autenticado
protected.Get("/profile", middlewares.MenuMiddleware, controllers.Profile)
protected.Get("/profile/telegram-status", controllers.TelegramStaffStatus)
protected.Post("/profile/telegram-init", controllers.TelegramStaffInit)
protected.Post("/profile/telegram-validar", controllers.TelegramStaffValidar)
// Rutas de la aplicación
// web me redireccione a /
protected.Get("/web", func(c *fiber.Ctx) error { return c.Redirect("/", http.StatusSeeOther) })
app.Get("/web", func(c *fiber.Ctx) error { return c.Redirect("/", http.StatusSeeOther) })
protected.Get("/", controllers.App)
protected.Get("/dashboard", middlewares.MenuMiddleware, controllers.Dashboard)
protected.Get("/modules", middlewares.MenuMiddleware, controllers.Modules) // Renderizar la vista
protected.Get("/loadmodules", controllers.GetModules) // Obtener todos los módulos
protected.Post("/modules", middlewares.SoloAdmin, controllers.CreateModule) // Crear un nuevo módulo
protected.Put("/modules/:id", middlewares.SoloAdmin, controllers.UpdateModule) // Actualizar un módulo existente
protected.Delete("/modules/:id", middlewares.SoloAdmin, controllers.DeleteModule) // Eliminar un módulo
// Rutas de roles
protected.Get("/roles", middlewares.MenuMiddleware, controllers.Roles) // Renderizar la vista
protected.Get("/loadroles", controllers.GetRoles) // Obtener todos
protected.Post("/roles", middlewares.SoloAdmin, controllers.CreateRole) // Crear
protected.Put("/roles/:id", middlewares.SoloAdmin, controllers.UpdateRole) // Actualizar
protected.Delete("/roles/:id", middlewares.SoloAdmin, controllers.DeleteRole) // Eliminar
// Rutas de módulos
protected.Get("/submodules", middlewares.MenuMiddleware, controllers.Submodules) // Renderizar la vista
protected.Get("/loadsubmodules", controllers.GetSubmodules) // Obtener todos los módulos
protected.Post("/submodules", middlewares.SoloAdmin, controllers.CreateSubmodule) // Crear un nuevo módulo
protected.Put("/submodules/:id", middlewares.SoloAdmin, controllers.UpdateSubmodule) // Actualizar un módulo existente
protected.Delete("/submodules/:id", middlewares.SoloAdmin, controllers.DeleteSubmodule) // Eliminar un módulo
// Rutas de usuarios
protected.Get("/users", middlewares.MenuMiddleware, controllers.Users) // Renderizar la vista
protected.Get("/loadusers", controllers.GetUsers) // Obtener
protected.Post("/users", middlewares.SoloAdmin, controllers.CreateUser) // Crear
protected.Put("/users/:id", middlewares.SoloAdmin, controllers.UpdateUser) // Actualizar
protected.Put("/password/:id", middlewares.SoloAdmin, controllers.UpdatePassword) // Actualizar
protected.Delete("/users/:id", middlewares.SoloAdmin, controllers.DeleteUser) // Eliminar
protected.Get("/user/:id", controllers.GetUser) // Buscar un usuario
protected.Post("/users/:id/credenciales", controllers.EnviarCredencialesUsuario) // Enviar credenciales
// Rutas de conexiones ssh
protected.Get("/conexion_ssh", middlewares.MenuMiddleware, controllers.ConxSsh) // Renderizar la vista
protected.Get("/loadconexionssh", controllers.GetConxSsh) // Obtener
protected.Post("/conexionssh", controllers.CreateConxSsh) // Crear
protected.Put("/conexionssh/:id", controllers.UpdateConxSsh) // Actualizar
protected.Delete("/conexionssh/:id", controllers.DeleteConxSsh) // Eliminar
// Rutas de conexiones db
protected.Get("/conexion_db", middlewares.MenuMiddleware, controllers.ConxDb) // Renderizar la vista
protected.Get("/loadconexiondb", controllers.GetConxDb) // Obtener
protected.Get("/api/conxdb/select", controllers.GetConxDbSelect) // Select (filtrado por ?servidor_id=)
protected.Post("/conexiondb", controllers.CreateConxDb) // Crear
protected.Put("/conexiondb/:id", controllers.UpdateConxDb) // Actualizar
protected.Delete("/conexiondb/:id", controllers.DeleteConxDb) // Eliminar
// Rutas de servidor
protected.Get("/servidor", middlewares.MenuMiddleware, controllers.Servidor)
protected.Get("/servidor-dashboard", middlewares.MenuMiddleware, controllers.ServidorDashboard)
protected.Get("/loadservidorselect", controllers.GetServidor)
protected.Get("/loadservidor", controllers.GetServidor)
protected.Post("/servidor", controllers.CreateServidor)
protected.Put("/servidor/:id", controllers.UpdateServidor)
protected.Delete("/servidor/:id", controllers.DeleteServidor)
protected.Get("/servidor-dashboard/:id", controllers.GetServidorDashboard)
protected.Get("/conx-ping/:id", controllers.PingConexion)
protected.Post("/servidor/:id/agent-token", controllers.GenerateAgentToken)
protected.Get("/servidor/:id/metricas-history", controllers.GetMetricasHistory)
protected.Post("/servidor/:id/sync-hostinger", controllers.SyncServidorFromHostinger)
// Tareas (kanban)
protected.Get("/tareas", middlewares.MenuMiddleware, controllers.TareasIndex)
protected.Get("/tareas/data", controllers.GetTareas)
protected.Get("/tareas/usuarios", controllers.GetUsuariosSistema)
protected.Post("/tarea", controllers.CreateTarea)
protected.Get("/tarea/:id", controllers.GetTareaDetalle)
protected.Put("/tarea/:id", controllers.UpdateTarea)
protected.Put("/tarea/:id/estado", controllers.CambiarEstadoTarea)
protected.Delete("/tarea/:id", controllers.DeleteTareaHandler)
protected.Post("/tarea/:id/comentario", controllers.AddComentario)
// Monitor de URLs
protected.Get("/url-monitor", middlewares.MenuMiddleware, controllers.UrlMonitorIndex)
protected.Get("/url-monitors", controllers.GetUrlMonitors)
protected.Post("/url-monitor", controllers.CreateUrlMonitor)
protected.Put("/url-monitor/:id", controllers.UpdateUrlMonitor)
protected.Delete("/url-monitor/:id", controllers.DeleteUrlMonitorHandler)
protected.Post("/url-monitor/:id/check", controllers.CheckUrlMonitorNow)
protected.Get("/url-monitor/:id/logs", controllers.GetUrlMonitorLogsHandler)
// Rutas de proveedores de servidor
protected.Get("/prov_servidor", middlewares.MenuMiddleware, controllers.ProvServidor)
protected.Get("/loadprovservidor", controllers.GetProvServidor)
protected.Post("/provservidor", controllers.CreateProvServidor)
protected.Put("/provservidor/:id", controllers.UpdateProvServidor)
protected.Put("/provservidor/:id/integraciones", controllers.SetProvServidorIntegraciones)
protected.Delete("/provservidor/:id", controllers.DeleteProvServidor)
// Rutas de tipos de servidor
protected.Get("/tipo_servidor", middlewares.MenuMiddleware, controllers.TipoServidor)
protected.Get("/loadtiposervidor", controllers.GetTipoServidor)
protected.Post("/tiposervidor", controllers.CreateTipoServidor)
protected.Put("/tiposervidor/:id", controllers.UpdateTipoServidor)
protected.Delete("/tiposervidor/:id", controllers.DeleteTipoServidor)
// Rutas de tipo db
protected.Get("/tipo_db", middlewares.MenuMiddleware, controllers.TipoDb)
protected.Get("/loadtipodb", controllers.GetTipoDb)
protected.Post("/tipodb", controllers.CreateTipoDb)
protected.Put("/tipodb/:id", controllers.UpdateTipoDb)
protected.Delete("/tipodb/:id", controllers.DeleteTipoDb)
// ─── Módulo de Renovaciones / Contratos ──────────────────────────
RenovacionesRoutes(protected)
// ─── Seed manual (admin) ────────────────────────────────────────────
protected.Get("/run-seed", middlewares.SoloAdmin, controllers.RunSeed)
// ─── Query Runner (editor SQL) ────────────────────────────────────────────
protected.Get("/query-runner", middlewares.MenuMiddleware, controllers.QueryRunnerPage)
protected.Get("/query-runner/connections", controllers.GetConxDbList)
protected.Get("/query-runner/databases", controllers.GetDatabases)
protected.Get("/query-runner/tables", controllers.GetTables)
protected.Get("/query-runner/relations", controllers.GetRelations)
protected.Get("/query-runner/test", controllers.TestConnection)
// Sin SoloAdmin a propósito: RunQuery/RunBatchQuery ya limitan el alcance
// internamente (un no-admin solo ve/consulta las conexiones que su rol
// tiene asignadas vía Role.ConxDBs). El acceso real se controla asignando o
// no el submódulo "Query Runner" a su rol, no aquí.
protected.Post("/query-runner/run", controllers.RunQuery)
protected.Post("/query-runner/run-batch", controllers.RunBatchQuery)
protected.Get("/query-runner/history", controllers.GetHistory)
protected.Delete("/query-runner/history", controllers.ClearHistory)
protected.Post("/query-runner/export/csv", controllers.ExportCSV)
protected.Post("/query-runner/export/json", controllers.ExportJSON)
protected.Get("/query-runner/columns", controllers.GetTableColumnsHandler)
protected.Post("/query-runner/update-cell", controllers.UpdateCellHandler)
protected.Post("/query-runner/suggest", controllers.CorrectQueryHandler)
protected.Post("/query-runner/nl2sql", controllers.NL2SQLHandler)
// ─── Hostinger API ────────────────────────────────────────────────
protected.Get("/hostinger", middlewares.MenuMiddleware, controllers.HostingerConfigPage)
protected.Post("/hostinger/config", controllers.SaveHostingerConfig)
protected.Get("/hostinger/vps", controllers.GetHostingerVPS)
protected.Get("/hostinger/domains", controllers.GetHostingerDomains)
protected.Get("/hostinger/dns/:domain", controllers.GetHostingerDNS)
protected.Put("/hostinger/dns/:domain", controllers.UpdateHostingerDNS)
protected.Post("/hostinger/dns/:domain/reset", controllers.ResetHostingerDNS)
protected.Get("/hostinger/orders", controllers.GetHostingerOrders)
protected.Get("/hostinger/hosting", controllers.GetHostingerHosting)
// Domains: escritura
protected.Put("/hostinger/domains/:domain/nameservers", controllers.UpdateHostingerNameservers)
protected.Put("/hostinger/domains/:domain/domain-lock", controllers.EnableHostingerDomainLock)
protected.Delete("/hostinger/domains/:domain/domain-lock", controllers.DisableHostingerDomainLock)
protected.Put("/hostinger/domains/:domain/privacy", controllers.EnableHostingerPrivacy)
protected.Delete("/hostinger/domains/:domain/privacy", controllers.DisableHostingerPrivacy)
// VPS: acciones
protected.Post("/hostinger/vps/:id/start", controllers.StartHostingerVPS)
protected.Post("/hostinger/vps/:id/stop", controllers.StopHostingerVPS)
protected.Post("/hostinger/vps/:id/restart", controllers.RestartHostingerVPS)
protected.Put("/hostinger/vps/:id/root-password", controllers.SetHostingerVPSRootPassword)
protected.Put("/hostinger/vps/:id/hostname", controllers.SetHostingerVPSHostname)
protected.Get("/hostinger/vps/:id/metrics", controllers.GetHostingerVPSMetrics)
protected.Get("/hostinger/vps/:id/backups", controllers.GetHostingerVPSBackups)
// Billing: autorenovación
protected.Patch("/hostinger/billing/:id/auto-renewal/enable", controllers.EnableHostingerAutoRenewal)
protected.Delete("/hostinger/billing/:id/auto-renewal/disable", controllers.DisableHostingerAutoRenewal)
// ─── Cloudflare API ───────────────────────────────────────────────
protected.Get("/cloudflare", middlewares.MenuMiddleware, controllers.CloudflareConfigPage)
protected.Post("/cloudflare/config", controllers.SaveCloudflareConfig)
protected.Get("/cloudflare/verify", controllers.VerifyCloudflareToken)
protected.Post("/cloudflare/clean-token", controllers.CleanCloudflareToken)
protected.Get("/cloudflare/user", controllers.GetCloudflareUser)
protected.Get("/cloudflare/zones", controllers.GetCloudflareZones)
protected.Get("/cloudflare/zones/:zone_id/dns", controllers.GetCloudflareDNS)
protected.Post("/cloudflare/zones/:zone_id/dns", controllers.CreateCloudflareDNS)
protected.Put("/cloudflare/zones/:zone_id/dns/:record_id", controllers.UpdateCloudflareDNS)
protected.Patch("/cloudflare/zones/:zone_id/dns/:record_id", controllers.PatchCloudflareDNS)
protected.Delete("/cloudflare/zones/:zone_id/dns/:record_id", controllers.DeleteCloudflareDNS)
protected.Get("/cloudflare/zones/:zone_id/ssl", controllers.GetCloudflareSSL)
protected.Get("/cloudflare/zones/:zone_id/firewall", controllers.GetCloudflareFirewall)
// ─── Coolify API ──────────────────────────────────────────────────
protected.Get("/coolify", middlewares.MenuMiddleware, controllers.CoolifyIndex)
// Gestión de instancias Coolify (multi-instancia)
protected.Get("/coolify/configs", controllers.CoolifyListConfigs)
protected.Post("/coolify/configs", controllers.CoolifyCreateConfig)
protected.Get("/coolify/configs/:id", controllers.CoolifyGetConfigByID)
protected.Put("/coolify/configs/:id", controllers.CoolifyUpdateConfig)
protected.Delete("/coolify/configs/:id", controllers.CoolifyDeleteConfig)
protected.Get("/coolify/configs/:id/test", controllers.CoolifyTestConfig)
// Compat legado (upsert sobre primer registro)
protected.Get("/coolify/config", controllers.CoolifyGetConfig)
protected.Post("/coolify/config", controllers.CoolifySaveConfig)
protected.Get("/coolify/health", controllers.CoolifyTestConnection)
// Applications
protected.Get("/coolify/apps", controllers.CoolifyListApplications)
protected.Get("/coolify/apps/:uuid", controllers.CoolifyGetApplication)
protected.Get("/coolify/apps/:uuid/logs", controllers.CoolifyApplicationLogs)
protected.Get("/coolify/apps/:uuid/envs", controllers.CoolifyApplicationEnvs)
protected.Post("/coolify/apps/:uuid/envs", controllers.CoolifyApplicationEnvCreate)
protected.Patch("/coolify/apps/:uuid/envs", controllers.CoolifyApplicationEnvUpdateBulk)
protected.Delete("/coolify/apps/:uuid/envs/:env_id", controllers.CoolifyApplicationEnvDelete)
protected.Get("/coolify/apps/:uuid/start", controllers.CoolifyApplicationStart)
protected.Get("/coolify/apps/:uuid/stop", controllers.CoolifyApplicationStop)
protected.Get("/coolify/apps/:uuid/restart", controllers.CoolifyApplicationRestart)
protected.Get("/coolify/apps/:uuid/deployments", controllers.CoolifyApplicationDeployments)
protected.Post("/coolify/apps/:uuid/deploy", controllers.CoolifyApplicationDeploy)
// Servers
protected.Get("/coolify/servers", controllers.CoolifyListServers)
protected.Get("/coolify/servers/:uuid", controllers.CoolifyGetServer)
protected.Get("/coolify/servers/:uuid/resources", controllers.CoolifyServerResources)
protected.Get("/coolify/servers/:uuid/domains", controllers.CoolifyServerDomains)
protected.Get("/coolify/servers/:uuid/validate", controllers.CoolifyServerValidate)
// Services
protected.Get("/coolify/services", controllers.CoolifyListServices)
protected.Get("/coolify/services/:uuid", controllers.CoolifyGetService)
protected.Get("/coolify/services/:uuid/start", controllers.CoolifyServiceStart)
protected.Get("/coolify/services/:uuid/stop", controllers.CoolifyServiceStop)
protected.Get("/coolify/services/:uuid/restart", controllers.CoolifyServiceRestart)
protected.Get("/coolify/services/:uuid/envs", controllers.CoolifyServiceEnvs)
protected.Patch("/coolify/services/:uuid/envs", controllers.CoolifyServiceEnvUpdateBulk)
// Databases
protected.Get("/coolify/databases", controllers.CoolifyListDatabases)
protected.Get("/coolify/databases/:uuid", controllers.CoolifyGetDatabase)
protected.Get("/coolify/databases/:uuid/start", controllers.CoolifyDatabaseStart)
protected.Get("/coolify/databases/:uuid/stop", controllers.CoolifyDatabaseStop)
protected.Get("/coolify/databases/:uuid/restart", controllers.CoolifyDatabaseRestart)
// Projects
protected.Get("/coolify/projects", controllers.CoolifyListProjects)
protected.Get("/coolify/projects/:uuid", controllers.CoolifyGetProject)
protected.Get("/coolify/projects/:uuid/environments", controllers.CoolifyProjectEnvironments)
// Deployments
protected.Get("/coolify/deployments", controllers.CoolifyListDeployments)
protected.Get("/coolify/deployments/:uuid", controllers.CoolifyGetDeployment)
// Team
protected.Get("/coolify/team", controllers.CoolifyCurrentTeam)
protected.Get("/coolify/team/members", controllers.CoolifyTeamMembers)
protected.Get("/coolify/teams", controllers.CoolifyListTeams)
// ─── Pasarelas de Pago ────────────────────────────────────────────
protected.Get("/pasarelas-pago", middlewares.MenuMiddleware, controllers.PasarelasPage)
// Bold
protected.Get("/pasarelas/bold/config", controllers.GetBoldConfigAPI)
protected.Post("/pasarelas/bold/save", controllers.SaveBoldConfig)
protected.Get("/pasarelas/bold/logs", controllers.BoldWebhookLogs)
protected.Post("/pasarelas/bold/logs/:id/validar", controllers.ValidarBoldLog)
protected.Get("/pasarelas/bold/callbacks", controllers.BoldCallbackLogs)
protected.Post("/pasarelas/bold/callbacks/:id/validar", controllers.ValidarBoldCallback)
// dLocal
protected.Get("/pasarelas/dlocal/config", controllers.GetDlocalConfigAPI)
protected.Post("/pasarelas/dlocal/save", controllers.SaveDlocalConfigWeb)
protected.Get("/pasarelas/dlocal/logs", controllers.DlocalPaymentLogsPaginated)
protected.Post("/pasarelas/dlocal/logs/:id/validar", controllers.ValidarDlocalLog)
protected.Post("/pasarelas/dlocal/registro-pago", apiControllers.DlocalRegistrarPago)
// PayPal
protected.Get("/pasarelas/paypal/config", controllers.GetPaypalConfigAPI)
protected.Post("/pasarelas/paypal/save", controllers.SavePaypalConfigWeb)
// Bold API (crear link, consultar estado)
protected.Post("/pasarelas/bold/crear-link", apiControllers.BoldCreatePaymentLink)
protected.Get("/pasarelas/bold/link/:linkID", apiControllers.BoldGetLinkStatus)
// ─── Landing Generator (admin) ────────────────────────────────────────────
protected.Get("/landing-pages", middlewares.MenuMiddleware, apiControllers.LandingAdminList)
// ─── Productos SaaS ──────────────────────────────────────────────────────
protected.Get("/saas", middlewares.MenuMiddleware, controllers.SaasIndex)
protected.Get("/loadsaas", controllers.GetSaasProductos)
protected.Post("/saas", controllers.CreateSaasProducto)
protected.Put("/saas/:id", controllers.UpdateSaasProducto)
protected.Delete("/saas/:id", controllers.DeleteSaasProducto)
protected.Get("/saas/:id/health", controllers.HealthCheckSaas)
// ─── Documentación: categorías globales ──────────────────────────────────
protected.Get("/doc/categorias", middlewares.MenuMiddleware, controllers.DocCategoriasIndex)
protected.Get("/doc/loadcategorias", controllers.GetDocCategorias)
protected.Post("/doc/categorias", controllers.CreateDocCategoria)
protected.Put("/doc/categorias/:id", controllers.UpdateDocCategoria)
protected.Delete("/doc/categorias/:id", controllers.DeleteDocCategoria)
// ─── Documentación: páginas ───────────────────────────────────────────────
protected.Get("/doc/paginas", middlewares.MenuMiddleware, controllers.DocPaginasIndex)
protected.Get("/doc/loadpaginas", controllers.GetDocPaginas)
protected.Get("/doc/paginas/:id", controllers.GetDocPaginaDetalle)
protected.Post("/doc/paginas", controllers.CreateDocPagina)
protected.Put("/doc/paginas/:id", controllers.UpdateDocPagina)
protected.Delete("/doc/paginas/:id", controllers.DeleteDocPagina)
// ─── Documentación: lectura privada (usuario logueado) ───────────────────
protected.Get("/docs/:saas", middlewares.MenuMiddleware, controllers.DocsPrivadoIndex)
protected.Get("/docs/:saas/:slug", middlewares.MenuMiddleware, controllers.DocsPrivadaPagina)
// ─── Integraciones SaaS (dispatcher de pagos) ─────────────────────────────
protected.Get("/saas-api", middlewares.MenuMiddleware, controllers.SaasApiIndex)
protected.Get("/loadsaasapi", controllers.GetSaasApiConfigs)
protected.Post("/saas-api", controllers.CreateSaasApiConfig)
protected.Put("/saas-api/:id", controllers.UpdateSaasApiConfig)
protected.Delete("/saas-api/:id", controllers.DeleteSaasApiConfig)
protected.Post("/saas-api/:id/probar", controllers.ProbaSaasApiConfig)
// Logs de despacho
protected.Get("/saas-api/logs", middlewares.MenuMiddleware, controllers.SaasDispatchLogIndex)
protected.Get("/loadsaasdispatchlogs", controllers.GetSaasDispatchLogs)
// ─── Configuraciones de IA (Qwen, OpenAI, etc.) ─────────────────────────
protected.Get("/ai-config", middlewares.MenuMiddleware, controllers.AiConfigIndex)
protected.Get("/ai-config/list", controllers.GetAiConfigs)
protected.Get("/api/ai-config/select", controllers.GetAiConfigSelect)
protected.Post("/ai-config", controllers.CreateAiConfigHandler)
protected.Put("/ai-config/:id", controllers.UpdateAiConfigHandler)
protected.Delete("/ai-config/:id", controllers.DeleteAiConfigHandler)
protected.Get("/ai-config/:id/test", controllers.TestAiConfigHandler)
// ─── Pagos externos (API para que apps de terceros pidan cobros) ───────────
// Sensible: emitir/regenerar un token da acceso a crear cobros reales por
// Bold/dLocal/PayPal, así que solo un administrador puede administrarlo.
protected.Get("/pagos-externos", middlewares.MenuMiddleware, controllers.PagosExternosIndex)
protected.Get("/pagos-externos/servicios", controllers.GetServiciosPagoExterno)
protected.Post("/pagos-externos/servicios", middlewares.SoloAdmin, controllers.CreateServicioPagoExternoHandler)
protected.Put("/pagos-externos/servicios/:id", middlewares.SoloAdmin, controllers.UpdateServicioPagoExternoHandler)
protected.Delete("/pagos-externos/servicios/:id", middlewares.SoloAdmin, controllers.DeleteServicioPagoExternoHandler)
protected.Post("/pagos-externos/servicios/:id/regenerar-token", middlewares.SoloAdmin, controllers.RegenerarTokenServicioPagoHandler)
protected.Get("/pagos-externos/solicitudes", controllers.GetSolicitudesPagoExternoHandler)
// ─── API Keys de /api/v2 (token + IP obligatoria + scopes) ────────────────
// Muy sensible: un scope "usuarios" o "query_runner" filtrado equivale a
// dar acceso administrativo — solo un administrador puede administrarlas.
protected.Get("/api-keys", middlewares.MenuMiddleware, controllers.ApiKeysIndex)
protected.Get("/api-keys/list", controllers.GetApiKeys)
protected.Post("/api-keys", middlewares.SoloAdmin, controllers.CreateApiKeyHandler)
protected.Put("/api-keys/:id", middlewares.SoloAdmin, controllers.UpdateApiKeyHandler)
protected.Delete("/api-keys/:id", middlewares.SoloAdmin, controllers.DeleteApiKeyHandler)
protected.Post("/api-keys/:id/regenerar-token", middlewares.SoloAdmin, controllers.RegenerarApiKeyHandler)
// ─── uMind: chat con IA embebible por tenant ───────────────────────────────
// Sensible: un tenant queda ligado a una config de IA (API key) y controla
// desde qué dominios se puede llamar al widget, así que crear/editar es
// solo para administradores.
protected.Get("/umind", middlewares.MenuMiddleware, controllers.UmindIndex)
protected.Get("/umind/tenants", controllers.GetUmindTenants)
protected.Post("/umind/tenants", middlewares.SoloAdmin, controllers.CreateUmindTenantHandler)
protected.Put("/umind/tenants/:id", middlewares.SoloAdmin, controllers.UpdateUmindTenantHandler)
protected.Delete("/umind/tenants/:id", middlewares.SoloAdmin, controllers.DeleteUmindTenantHandler)
protected.Get("/umind/documentos", controllers.GetUmindDocumentosHandler)
protected.Post("/umind/documentos", middlewares.SoloAdmin, controllers.CreateUmindDocumentoHandler)
protected.Delete("/umind/documentos/:id", middlewares.SoloAdmin, controllers.DeleteUmindDocumentoHandler)
protected.Get("/umind/sesiones", controllers.GetUmindSesionesHandler)
protected.Get("/umind/historial", controllers.GetUmindHistorialHandler)
protected.Get("/umind/tools", controllers.GetUmindHerramientasHandler)
protected.Post("/umind/tools", middlewares.SoloAdmin, controllers.CreateUmindHerramientaHandler)
protected.Put("/umind/tools/:id", middlewares.SoloAdmin, controllers.UpdateUmindHerramientaHandler)
protected.Delete("/umind/tools/:id", middlewares.SoloAdmin, controllers.DeleteUmindHerramientaHandler)
protected.Get("/umind/canales", controllers.GetUmindCanalesHandler)
protected.Post("/umind/canales", middlewares.SoloAdmin, controllers.CreateUmindCanalHandler)
protected.Put("/umind/canales/:id", middlewares.SoloAdmin, controllers.UpdateUmindCanalHandler)
protected.Delete("/umind/canales/:id", middlewares.SoloAdmin, controllers.DeleteUmindCanalHandler)
protected.Post("/umind/chat", controllers.UmindChatPruebaHandler)
// ─── uMind Orquestador (SPA Vue) ────────────────────────────────────────────
// Estáticos reales (JS/CSS del build) ya los sirve el Static("/") general
// registrado en config.LoadStatic — esto es solo el fallback para las rutas
// del lado del cliente (vue-router en modo history), protegido con sesión.
orchestratorFallback := func(c *fiber.Ctx) error {
return c.SendFile("./public/orchestrator/index.html")
}
app.Get("/orchestrator", middlewares.AuthWeb(), orchestratorFallback)
app.Get("/orchestrator/*", middlewares.AuthWeb(), orchestratorFallback)
// ─── OSS API (Alibaba Cloud + S3/MinIO) ────────────────────────────────────
protected.Get("/oss-api", middlewares.MenuMiddleware, controllers.OssApiIndex)
protected.Get("/loadossapi", controllers.GetOssApiConfigs)
protected.Get("/oss-api/active", controllers.GetActiveOssApiList)
protected.Post("/oss-api", controllers.CreateOssApiConfig)
protected.Put("/oss-api/:id", controllers.UpdateOssApiConfig)
protected.Delete("/oss-api/:id", controllers.DeleteOssApiConfig)
// Explorador de archivos OSS
protected.Get("/oss-api/browser", controllers.OssBrowserList)
protected.Get("/oss-api/browser/url", controllers.OssBrowserSignedURL)
protected.Delete("/oss-api/browser/object", controllers.OssBrowserDelete)
protected.Post("/oss-api/browser/upload", controllers.OssBrowserUpload)
// ─── VCard API (integración Admin Laravel) ────────────────────────────────
protected.Get("/vcard-api", middlewares.MenuMiddleware, controllers.VcardApiIndex)
protected.Post("/vcard-api/login", controllers.VcardApiLogin)
protected.Get("/vcard-api/config", controllers.VcardApiGetConfig)
protected.Post("/vcard-api/config", controllers.VcardApiSaveConfig)
// Usuarios (GET)
protected.Get("/vcard-api/usuarios", controllers.VcardApiUsuarios)
protected.Get("/vcard-api/usuarios/:id/membresia", controllers.VcardApiMembresia)
protected.Get("/vcard-api/usuarios/:userId/vcards", controllers.VcardApiVcardsByUsuario)
protected.Get("/vcard-api/usuarios/:userId/pagos", controllers.VcardApiPagosByUsuario)
protected.Get("/vcard-api/usuarios/:userId/transacciones", controllers.VcardApiTransaccionesByUsuario)
protected.Get("/vcard-api/usuarios/:userId/logs", controllers.VcardApiLogsByUsuario)
protected.Get("/vcard-api/usuarios/:userId/miniwebs", controllers.VcardApiMiniwebsByUsuario)
protected.Get("/vcard-api/usuarios/:id", controllers.VcardApiUsuario)
// Usuarios (mutaciones)
protected.Put("/vcard-api/usuarios/:id", controllers.VcardApiUsuarioUpdate)
protected.Post("/vcard-api/usuarios/:id/activar", controllers.VcardApiUsuarioActivar)
protected.Post("/vcard-api/usuarios/:id/desactivar", controllers.VcardApiUsuarioDesactivar)
protected.Post("/vcard-api/usuarios/:id/activar-membresia", controllers.VcardApiActivarMembresia)
protected.Post("/vcard-api/usuarios/:id/desactivar-membresia", controllers.VcardApiDesactivarMembresia)
protected.Post("/vcard-api/usuarios/:id/cambiar-plan", controllers.VcardApiCambiarPlan)
// VCards
protected.Get("/vcard-api/vcards", controllers.VcardApiVcards)
protected.Get("/vcard-api/vcards/:id", controllers.VcardApiVcard)
protected.Put("/vcard-api/vcards/:id", controllers.VcardApiVcardUpdate)
// Resto (solo GET)
protected.Get("/vcard-api/planes", controllers.VcardApiPlanes)
protected.Get("/vcard-api/planes/:id", controllers.VcardApiPlan)
protected.Put("/vcard-api/planes/:id", controllers.VcardApiPlanUpdate)
protected.Get("/vcard-api/pagos", controllers.VcardApiPagos)
protected.Get("/vcard-api/transacciones", controllers.VcardApiTransacciones)
protected.Get("/vcard-api/logs", controllers.VcardApiLogs)
protected.Get("/vcard-api/miniwebs", controllers.VcardApiMiniwebs)
protected.Get("/vcard-api/miniwebs/:id", controllers.VcardApiMiniweb)
// ─── Telegram ─────────────────────────────────────────────────────────────
protected.Get("/telegram", middlewares.MenuMiddleware, controllers.TelegramIndex)
protected.Get("/loadtelegram", controllers.GetTelegramConfigs)
protected.Post("/telegram", controllers.CreateTelegramConfig)
protected.Put("/telegram/:id", controllers.UpdateTelegramConfig)
protected.Delete("/telegram/:id", controllers.DeleteTelegramConfig)
protected.Post("/telegram/:id/test", controllers.TestTelegramConfig)
protected.Post("/telegram/send", controllers.SendTelegramNotification)
protected.Get("/telegram/logs", controllers.GetTelegramLogs)
protected.Post("/telegram/:id/set-portal-webhook", controllers.SetPortalWebhook)
protected.Get("/telegram/:id/webhook-info", controllers.GetPortalWebhookInfo)
// ─── Portal de Clientes ────────────────────────────────────────────────────
protected.Get("/proyectos", middlewares.MenuMiddleware, controllers.ProyectosIndex)
protected.Get("/loadproyectos", controllers.LoadProyectos)
protected.Post("/proyectos", controllers.CreateProyecto)
protected.Put("/proyectos/:id", controllers.UpdateProyecto)
protected.Delete("/proyectos/:id", controllers.DeleteProyecto)
protected.Get("/proyectos/:id/detalle", middlewares.MenuMiddleware, controllers.ProyectoDetalleIndex)
protected.Get("/proyectos/:id/fases", controllers.GetFases)
protected.Post("/proyectos/:id/fases", controllers.CreateFase)
protected.Put("/proyectos/:id/fases/:faseID", controllers.UpdateFase)
protected.Delete("/proyectos/:id/fases/:faseID", controllers.DeleteFase)
protected.Post("/proyectos/:id/fases/template", controllers.ApplyTemplate)
protected.Get("/proyectos/:id/avances", controllers.GetAvances)
protected.Post("/proyectos/:id/avances", controllers.CreateAvance)
protected.Put("/proyectos/:id/avances/:avID", controllers.UpdateAvance)
protected.Delete("/proyectos/:id/avances/:avID", controllers.DeleteAvance)
protected.Get("/proyectos/:id/entregables", controllers.GetEntregables)
protected.Post("/proyectos/:id/entregables", controllers.UploadEntregable)
protected.Delete("/proyectos/:id/entregables/:entID", controllers.DeleteEntregable)
protected.Get("/proyectos/:id/entregables/:entID/download", controllers.DownloadEntregable)
protected.Put("/proyectos/:id/entregables/:entID/visibilidad", controllers.UpdateEntregableVisibilidad)
protected.Get("/proyectos/:id/tickets", controllers.GetTickets)
protected.Put("/proyectos/:id/tickets/:ticketID/estado", controllers.UpdateTicketEstadoAdmin)
protected.Post("/proyectos/:id/tickets/:ticketID/mensaje", controllers.AdminResponderTicket)
protected.Get("/proyectos/:id/documentos", controllers.GetDocumentos)
protected.Post("/proyectos/:id/documentos", controllers.UploadDocumento)
protected.Delete("/proyectos/:id/documentos/:docID", controllers.DeleteDocumento)
protected.Get("/proyectos/:id/documentos/:docID/download", controllers.DownloadDocumento)
protected.Get("/portal-usuarios", middlewares.MenuMiddleware, controllers.PortalUsuariosIndex)
protected.Get("/loadportalusuarios", controllers.LoadPortalUsuarios)
protected.Get("/loadportalusuarios/:id", controllers.GetPortalUsuarioDetail)
protected.Post("/portal-usuarios", controllers.CreatePortalUsuario)
protected.Put("/portal-usuarios/:id", controllers.UpdatePortalUsuario)
protected.Delete("/portal-usuarios/:id", controllers.DeletePortalUsuario)
protected.Get("/portal-usuarios/:id/rut-file", controllers.PortalUsuarioRutFile)
protected.Post("/portal-usuarios/:id/acceso", controllers.AddPortalAcceso)
protected.Delete("/portal-usuarios/:id/acceso/:clienteID", controllers.RemovePortalAcceso)
protected.Post("/portal-usuarios/:id/send-credentials", controllers.SendPortalCredentials)
protected.Get("/facturas", middlewares.MenuMiddleware, controllers.FacturasIndex)
protected.Get("/loadfacturas", controllers.LoadFacturas)
protected.Post("/facturas", controllers.CreateFactura)
protected.Put("/facturas/:id", controllers.UpdateFactura)
protected.Delete("/facturas/:id", controllers.DeleteFactura)
protected.Post("/facturas/:id/upload-pdf", controllers.UploadFacturaPDF)
protected.Get("/facturas/:id/download", controllers.DownloadFacturaPDF)
// ─── USITE Shield ─────────────────────────────────────────────────────────
protected.Get("/shield", middlewares.MenuMiddleware, controllers.ShieldIndex)
protected.Get("/loadshield", controllers.LoadShieldConfig)
protected.Post("/saveshield", controllers.SaveShieldConfig)
protected.Get("/shield/health", controllers.ShieldHealth)
protected.Get("/shield/extension-version", controllers.ShieldExtensionVersion)
protected.Get("/shield/logs", controllers.ShieldLogs)
protected.Get("/shield/logs/stats", controllers.ShieldLogStats)
protected.Get("/shield/review-requests", controllers.ShieldReviewRequests)
protected.Put("/shield/review-requests/:id/approve", controllers.ShieldApproveRequest)
protected.Put("/shield/review-requests/:id/reject", controllers.ShieldRejectRequest)
protected.Get("/shield/whitelist", controllers.ShieldWhitelist)
protected.Post("/shield/whitelist", controllers.ShieldAddWhitelist)
protected.Delete("/shield/whitelist/:domain", controllers.ShieldDeleteWhitelist)
protected.Get("/shield/blacklist", controllers.ShieldBlacklist)
protected.Post("/shield/blacklist", controllers.ShieldAddBlacklist)
protected.Delete("/shield/blacklist/:domain", controllers.ShieldDeleteBlacklist)
protected.Get("/shield/reputation/:domain", controllers.ShieldReputation)
protected.Put("/shield/reputation/:domain/score", controllers.ShieldAdjustScore)
// Tickets global (todos los proyectos)
protected.Get("/tickets", middlewares.MenuMiddleware, controllers.TicketsAdminIndex)
protected.Get("/tickets/data", controllers.GetAllTicketsAdmin)
protected.Put("/tickets/:ticketID/estado", controllers.UpdateTicketEstadoAdmin)
protected.Post("/tickets/:ticketID/mensaje", controllers.AdminResponderTicket)
protected.Put("/tickets/:ticketID/asignar", controllers.AsignarTicket)
protected.Get("/tickets/admins", controllers.GetSoporteAdmins)
// Configuración webhook de soporte
protected.Get("/soporte/webhook", middlewares.MenuMiddleware, controllers.SoporteWebhookConfigPage)
protected.Get("/soporte/webhook/data", controllers.GetSoporteWebhookConfig)
protected.Post("/soporte/webhook", controllers.SaveSoporteWebhookConfig)
// Configuración de notificaciones
protected.Get("/notif-config", middlewares.MenuMiddleware, controllers.NotifConfigIndex)
protected.Get("/notif-config/data", controllers.GetNotifConfigs)
protected.Post("/notif-config", controllers.SaveNotifConfig)
// Umbrales de alerta de servidores
protected.Get("/servidor-alerta-config", controllers.GetServidorAlertaConfig)
protected.Post("/servidor-alerta-config", controllers.SaveServidorAlertaConfig)
// Partner Recursos (documentación y comunicados para partners)
protected.Get("/partner-recursos", middlewares.MenuMiddleware, controllers.PartnerRecursosIndex)
protected.Get("/partner-recursos/data", controllers.LoadPartnerRecursos)
protected.Post("/partner-recursos", controllers.CreatePartnerRecurso)
protected.Put("/partner-recursos/:id", controllers.UpdatePartnerRecurso)
protected.Delete("/partner-recursos/:id", controllers.DeletePartnerRecurso)
protected.Post("/partner-recursos/:id/upload", controllers.UploadPartnerRecursoArchivo)
protected.Get("/partner-recursos/:id/download", controllers.DownloadPartnerRecurso)
protected.Get("/partner-comunicados/data", controllers.LoadPartnerComunicados)
protected.Post("/partner-comunicados", controllers.CreatePartnerComunicado)
protected.Put("/partner-comunicados/:id", controllers.UpdatePartnerComunicado)
protected.Delete("/partner-comunicados/:id", controllers.DeletePartnerComunicado)
protected.Post("/partner-comunicados/:id/upload", controllers.UploadPartnerComunicadoArchivo)
protected.Get("/partner-comunicados/:id/download", controllers.DownloadPartnerComunicadoArchivo)
// Notificaciones in-app del admin (bell)
protected.Get("/mis-notifs", controllers.GetMisNotifs)
protected.Put("/mis-notifs/:id/leida", controllers.MarcarNotifLeida)
protected.Post("/mis-notifs/marcar-todas", controllers.MarcarTodasLeidas)
// ─── Contabilidad ─────────────────────────────────────────────────────────
protected.Get("/contabilidad", middlewares.MenuMiddleware, controllers.ContabilidadIndex)
protected.Get("/contabilidad/dashboard", controllers.ContabilidadDashboard)
protected.Get("/contabilidad/consolidado", controllers.ContabilidadConsolidado)
protected.Get("/contabilidad/consolidados", controllers.ContabilidadListConsolidados)
// Transacciones
protected.Get("/contabilidad/transacciones", middlewares.MenuMiddleware, controllers.ContabilidadTransaccionesView)
protected.Get("/contabilidad/transacciones/list", controllers.GetTransacciones)
protected.Post("/contabilidad/transacciones", controllers.CreateTransaccion)
protected.Put("/contabilidad/transacciones/:id", controllers.UpdateTransaccion)
protected.Delete("/contabilidad/transacciones/:id", controllers.DeleteTransaccion)
// Cuentas (categorías contables)
protected.Get("/contabilidad/cuentas", middlewares.MenuMiddleware, controllers.ContabilidadCuentasView)
protected.Get("/contabilidad/cuentas/list", controllers.GetCuentas)
protected.Get("/contabilidad/cuentas/select", controllers.GetCuentasSelect)
protected.Post("/contabilidad/cuentas", controllers.CreateCuenta)
protected.Put("/contabilidad/cuentas/:id", controllers.UpdateCuenta)
protected.Delete("/contabilidad/cuentas/:id", controllers.DeleteCuenta)
// Entidades
protected.Get("/contabilidad/entidades", middlewares.MenuMiddleware, controllers.ContabilidadEntidadesView)
protected.Get("/contabilidad/entidades/list", controllers.GetEntidades)
protected.Get("/contabilidad/entidades/select", controllers.GetEntidadesSelect)
protected.Post("/contabilidad/entidades", controllers.CreateEntidad)
protected.Put("/contabilidad/entidades/:id", controllers.UpdateEntidad)
protected.Delete("/contabilidad/entidades/:id", controllers.DeleteEntidad)
// Cuentas por cobrar
protected.Get("/contabilidad/cuentas-cobro", middlewares.MenuMiddleware, controllers.ContabilidadCobroView)
protected.Get("/contabilidad/cuentas-cobro/list", controllers.GetCuentasCobro)
protected.Post("/contabilidad/cuentas-cobro", controllers.CreateCuentaCobro)
protected.Put("/contabilidad/cuentas-cobro/:id", controllers.UpdateCuentaCobro)
protected.Delete("/contabilidad/cuentas-cobro/:id", controllers.DeleteCuentaCobro)
protected.Post("/contabilidad/cuentas-cobro/:id/pagar", controllers.MarcarCuentaCobroPagada)
protected.Post("/contabilidad/cuentas-cobro/:id/generar-documento", controllers.GenerarDocumentoCuentaCobro)
// Cuentas por pagar
protected.Get("/contabilidad/cuentas-pagar", middlewares.MenuMiddleware, controllers.ContabilidadPagarView)
protected.Get("/contabilidad/cuentas-pagar/list", controllers.GetCuentasPagar)
protected.Post("/contabilidad/cuentas-pagar", controllers.CreateCuentaPagar)
protected.Put("/contabilidad/cuentas-pagar/:id", controllers.UpdateCuentaPagar)
protected.Post("/contabilidad/cuentas-pagar/:id/pagar", controllers.MarcarCuentaPagarPagada)
protected.Delete("/contabilidad/cuentas-pagar/:id", controllers.DeleteCuentaPagar)
protected.Get("/contabilidad/cuentas-pagar/:id/archivo", controllers.DownloadCuentaPagarArchivo)
// ─── WebSMS (LabsMobile) ───────────────────────────────────────────────────
protected.Get("/websms", middlewares.MenuMiddleware, controllers.WebSmsConfigPage)
protected.Get("/websms/config", controllers.GetWebSmsConfig)
protected.Post("/websms/save", controllers.SaveWebSmsConfig)
protected.Post("/websms/test", controllers.TestWebSms)
protected.Get("/websms/logs", controllers.GetWebSmsLogs)
protected.Get("/websms/webhook-logs", controllers.GetWebSmsWebhookLogs)
// ─── Planes dLocal (gestión desde panel protegido) ────────────────────────
protected.Get("/dlocal/planes", apiControllers.SeePlanes)
protected.Post("/dlocal/planes", apiControllers.CreatePlan)
protected.Get("/dlocal/planes/:planID", apiControllers.SeePlan)
protected.Patch("/dlocal/planes/:planID", apiControllers.UpdatedPlan)
protected.Patch("/dlocal/planes/:planID/subscription/:subscriptionId/deactivate", apiControllers.DeactivatePlan)
}