package handlers import ( "net/http" "runtime" "time" "visiona-local/server/internal/deps" "github.com/gin-gonic/gin" ) type SystemHandler struct { startTime time.Time version string buildTime string shutdownFn func() depsCache []deps.Dependency } func NewSystemHandler(version, buildTime string, shutdownFn func()) *SystemHandler { return &SystemHandler{ startTime: time.Now(), version: version, buildTime: buildTime, shutdownFn: shutdownFn, depsCache: deps.CheckAll(), } } func (h *SystemHandler) HealthCheck(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) } func (h *SystemHandler) Info(c *gin.Context) { c.JSON(200, gin.H{ "success": true, "data": gin.H{ "version": h.version, "platform": runtime.GOOS + "/" + runtime.GOARCH, "uptime": time.Since(h.startTime).Seconds(), "goVersion": runtime.Version(), }, }) } func (h *SystemHandler) Metrics(c *gin.Context) { var ms runtime.MemStats runtime.ReadMemStats(&ms) c.JSON(200, gin.H{ "success": true, "data": gin.H{ "version": h.version, "buildTime": h.buildTime, "platform": runtime.GOOS + "/" + runtime.GOARCH, "goVersion": runtime.Version(), "uptimeSeconds": time.Since(h.startTime).Seconds(), "goroutines": runtime.NumGoroutine(), "memHeapAllocMB": float64(ms.HeapAlloc) / 1024 / 1024, "memSysMB": float64(ms.Sys) / 1024 / 1024, "memHeapObjects": ms.HeapObjects, "gcCycles": ms.NumGC, "nextGcMB": float64(ms.NextGC) / 1024 / 1024, }, }) } func (h *SystemHandler) Deps(c *gin.Context) { c.JSON(200, gin.H{ "success": true, "data": gin.H{"deps": h.depsCache}, }) } func (h *SystemHandler) Restart(c *gin.Context) { c.JSON(200, gin.H{"success": true, "data": gin.H{"message": "restarting"}}) if f, ok := c.Writer.(http.Flusher); ok { f.Flush() } go func() { time.Sleep(200 * time.Millisecond) // shutdownFn signals the main goroutine to perform exec after server shutdown if h.shutdownFn != nil { h.shutdownFn() } }() }