package middleware import ( "encoding/json" "github.com/gofiber/fiber/v2" "gorm.io/gorm" "log" "strings" "time" "web-medols-be/app/database/entity" utilSvc "web-medols-be/utils/service" ) func AuditTrailsMiddleware(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { start := time.Now() requestBody := c.Body() headersMap := c.GetReqHeaders() headersJSON, _ := json.Marshal(headersMap) authHeader := c.Get("Authorization") userId := utilSvc.GetUserId(authHeader) err := c.Next() audit := entity.AuditTrails{ Method: c.Method(), Path: c.OriginalURL(), IP: getIP(c), Status: c.Response().StatusCode(), UserID: userId, RequestHeaders: string(headersJSON), RequestBody: string(requestBody), ResponseBody: string(c.Response().Body()), DurationMs: time.Since(start).Milliseconds(), CreatedAt: time.Now(), } go db.Create(&audit) return err } } func StartAuditTrailCleanup(db *gorm.DB, retention int) { go func() { for { time.Sleep(24 * time.Hour) cutoff := time.Now().AddDate(0, 0, retention) db.Where("created_at < ?", cutoff).Delete(&entity.AuditTrails{}) log.Printf(" at: %s", cutoff) } }() } func getIP(c *fiber.Ctx) string { ip := c.Get("X-Forwarded-For") if ip == "" { ip = c.IP() } if strings.Contains(ip, ":") { ip = strings.Split(ip, ":")[0] } return ip }