add middlewares, handlers and database models

This commit is contained in:
juancwu 2025-12-16 10:46:34 -05:00
commit 7e288ea67a
24 changed files with 1045 additions and 14 deletions

View file

@ -0,0 +1,70 @@
package middleware
import (
"log/slog"
"net/http"
"strings"
"time"
)
// responseWriter wraps http.ResponseWriter to capture status code
type responseWriter struct {
http.ResponseWriter
statusCode int
written bool
}
func (rw *responseWriter) WriteHeader(code int) {
if !rw.written {
rw.statusCode = code
rw.written = true
rw.ResponseWriter.WriteHeader(code)
}
}
func (rw *responseWriter) Write(b []byte) (int, error) {
if !rw.written {
rw.WriteHeader(http.StatusOK)
}
return rw.ResponseWriter.Write(b)
}
// Paths to skip logging (static assets, etc.)
var skipLoggingPaths = []string{
"/assets/",
"/uploads/",
"/favicon.ico",
}
// RequestLogging logs HTTP requests with method, path, status, and duration
// Skips logging for paths defined in skipLoggingPaths
func RequestLogging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Skip logging for configured paths
for _, prefix := range skipLoggingPaths {
if strings.HasPrefix(r.URL.Path, prefix) {
next.ServeHTTP(w, r)
return
}
}
start := time.Now()
rw := &responseWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
written: false,
}
next.ServeHTTP(rw, r)
duration := time.Since(start)
slog.Info("http request",
"method", r.Method,
"path", r.URL.Path,
"status", rw.statusCode,
"duration_ms", duration.Milliseconds(),
"remote_addr", getClientIP(r),
)
})
}