package handlers import ( "context" "net/http" "time" "github.com/gin-gonic/gin" "go.uber.org/zap" "github.com/kms/api-key-service/internal/repository" ) // HealthHandler handles health check endpoints type HealthHandler struct { db repository.DatabaseProvider logger *zap.Logger } // NewHealthHandler creates a new health handler func NewHealthHandler(db repository.DatabaseProvider, logger *zap.Logger) *HealthHandler { return &HealthHandler{ db: db, logger: logger, } } // HealthResponse represents the health check response type HealthResponse struct { Status string `json:"status"` Timestamp string `json:"timestamp"` Version string `json:"version,omitempty"` Checks map[string]string `json:"checks,omitempty"` } // Health handles basic health check - lightweight endpoint for load balancers func (h *HealthHandler) Health(c *gin.Context) { response := HealthResponse{ Status: "healthy", Timestamp: time.Now().UTC().Format(time.RFC3339), } c.JSON(http.StatusOK, response) } // Ready handles readiness check - checks if service is ready to accept traffic func (h *HealthHandler) Ready(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second) defer cancel() checks := make(map[string]string) status := "ready" statusCode := http.StatusOK // Check database connectivity if err := h.db.Ping(ctx); err != nil { h.logger.Error("Database health check failed", zap.Error(err)) checks["database"] = "unhealthy: " + err.Error() status = "not ready" statusCode = http.StatusServiceUnavailable } else { checks["database"] = "healthy" } response := HealthResponse{ Status: status, Timestamp: time.Now().UTC().Format(time.RFC3339), Checks: checks, } c.JSON(statusCode, response) }