package api import ( "net/http" "time" "github.com/bams/backend/internal/logger" "github.com/gorilla/mux" ) func loggingMiddleware(log *logger.Logger) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() log.Info("HTTP request", "method", r.Method, "path", r.URL.Path, "remote", r.RemoteAddr) // Wrap response writer to capture status code wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} next.ServeHTTP(wrapped, r) duration := time.Since(start) log.Info("HTTP response", "method", r.Method, "path", r.URL.Path, "status", wrapped.statusCode, "duration", duration) }) } } func corsMiddleware() mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") w.Header().Set("Access-Control-Max-Age", "3600") if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) } } func recoveryMiddleware(log *logger.Logger) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { log.Error("Panic recovered", "error", err, "path", r.URL.Path) jsonError(w, http.StatusInternalServerError, "Internal server error") } }() next.ServeHTTP(w, r) }) } } type responseWriter struct { http.ResponseWriter statusCode int } func (rw *responseWriter) WriteHeader(code int) { rw.statusCode = code rw.ResponseWriter.WriteHeader(code) }