package api import ( "net/http" "github.com/ez-api/ez-api/internal/model" "github.com/gin-gonic/gin" ) type OperationLogView struct { ID uint `json:"id"` CreatedAt int64 `json:"created_at"` Actor string `json:"actor"` Method string `json:"method"` Path string `json:"path"` Query string `json:"query"` StatusCode int `json:"status_code"` LatencyMs int64 `json:"latency_ms"` ClientIP string `json:"client_ip"` RequestID string `json:"request_id"` UserAgent string `json:"user_agent"` ErrorMessage string `json:"error_message"` } func toOperationLogView(l model.OperationLog) OperationLogView { return OperationLogView{ ID: l.ID, CreatedAt: l.CreatedAt.UTC().Unix(), Actor: l.Actor, Method: l.Method, Path: l.Path, Query: l.Query, StatusCode: l.StatusCode, LatencyMs: l.LatencyMs, ClientIP: l.ClientIP, RequestID: l.RequestID, UserAgent: l.UserAgent, ErrorMessage: l.ErrorMessage, } } // ListOperationLogs godoc // @Summary List operation logs // @Description List admin operation logs // @Tags admin // @Produce json // @Security AdminAuth // @Param page query int false "page (1-based)" // @Param limit query int false "limit (default 50, max 200)" // @Param search query string false "search by actor/method/path" // @Success 200 {object} ResponseEnvelope{data=[]OperationLogView} // @Failure 500 {object} ResponseEnvelope{data=MapData} // @Router /admin/operation-logs [get] func (h *AdminHandler) ListOperationLogs(c *gin.Context) { var rows []model.OperationLog q := h.db.Model(&model.OperationLog{}).Order("id desc") query := parseListQuery(c) q = applyListSearch(q, query.Search, "actor", "method", "path") q = applyListPagination(q, query) if err := q.Find(&rows).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list operation logs", "details": err.Error()}) return } out := make([]OperationLogView, 0, len(rows)) for _, row := range rows { out = append(out, toOperationLogView(row)) } c.JSON(http.StatusOK, out) }