package v1 import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/service" applogger "github.com/gochat/gochat/pkg/logger" "github.com/gochat/gochat/pkg/pagination" "github.com/gochat/gochat/pkg/response" ) // AuditHandler handles audit log listing and retrieval. // Reference: Chatwoot enterprise audit logs controller + P2B M11 spec type AuditHandler struct { svc *service.AuditService } // NewAuditHandler creates a new AuditLog handler. func NewAuditHandler(svc *service.AuditService) *AuditHandler { return &AuditHandler{svc: svc} } // List retrieves paginated audit log entries for the current account. // GET /api/v1/accounts/:account_id/audit_logs // Query filters: action, auditable_type func (h *AuditHandler) List(c *gin.Context) { accountID := getAccountID(c) if accountID == 0 { response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified") return } pg := pagination.Parse(c) action := c.Query("action") auditableType := c.Query("auditable_type") audits, total, svcErr := h.svc.ListByAccount(c.Request.Context(), accountID, action, auditableType, pg.Page, pg.PerPage) if svcErr != nil { applogger.L().Errorf("AuditHandler.List account=%d: %v", accountID, svcErr) handleServiceError(c, svcErr) return } response.OKWithMeta(c, toInterfaceSlice(audits), pg.Page, pg.PerPage, total) } // Get retrieves a single audit log entry by ID. // GET /api/v1/accounts/:account_id/audit_logs/:id func (h *AuditHandler) Get(c *gin.Context) { accountID := getAccountID(c) if accountID == 0 { response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified") return } id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || id == 0 { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid audit log id") return } audit, svcErr := h.svc.GetByID(c.Request.Context(), uint(id)) if svcErr != nil { applogger.L().Errorf("AuditHandler.Get id=%d: %v", id, svcErr) handleServiceError(c, svcErr) return } response.OK(c, audit) } // RegisterAuditRoutes registers audit log routes on a gin.RouterGroup. func RegisterAuditRoutes(rg *gin.RouterGroup, h *AuditHandler) { audits := rg.Group("/audit_logs") { audits.GET("/", h.List) audits.GET("/:id", h.Get) } }