package handler import ( "encoding/json" "net/http" "strconv" "time" "freeleaps.com/gitea-webhook-ambassador/internal/auth" "freeleaps.com/gitea-webhook-ambassador/internal/config" "freeleaps.com/gitea-webhook-ambassador/internal/database" "freeleaps.com/gitea-webhook-ambassador/internal/logger" ) // LogsHandler handles trigger logs API endpoints type LogsHandler struct { db *database.DB config *config.Configuration auth *auth.Middleware } // NewLogsHandler creates a new logs handler func NewLogsHandler(db *database.DB, config *config.Configuration) *LogsHandler { return &LogsHandler{ db: db, config: config, auth: auth.NewMiddleware(config.Server.SecretKey), } } // TriggerLogResponse represents a trigger log response type TriggerLogResponse struct { ID int64 `json:"id"` RepositoryName string `json:"repository_name"` BranchName string `json:"branch_name"` CommitSHA string `json:"commit_sha"` JobName string `json:"job_name"` Status string `json:"status"` ErrorMessage string `json:"error_message,omitempty"` CreatedAt time.Time `json:"created_at"` } // verifyAuth verifies the JWT token in the request func (h *LogsHandler) verifyAuth(r *http.Request) error { return h.auth.VerifyToken(r) } // HandleGetTriggerLogs handles retrieving trigger logs func (h *LogsHandler) HandleGetTriggerLogs(w http.ResponseWriter, r *http.Request) { // Verify JWT token if err := h.verifyAuth(r); err != nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // Get query parameters repoName := r.URL.Query().Get("repository") branchName := r.URL.Query().Get("branch") sinceStr := r.URL.Query().Get("since") limitStr := r.URL.Query().Get("limit") // Parse since parameter var since time.Time var err error if sinceStr != "" { since, err = time.Parse(time.RFC3339, sinceStr) if err != nil { http.Error(w, "Invalid since parameter format (use RFC3339)", http.StatusBadRequest) return } } // Parse limit parameter limit := 100 // default limit if limitStr != "" { limit, err = strconv.Atoi(limitStr) if err != nil { http.Error(w, "Invalid limit parameter", http.StatusBadRequest) return } if limit <= 0 { http.Error(w, "Limit must be greater than 0", http.StatusBadRequest) return } if limit > 1000 { limit = 1000 // maximum limit } } // Get trigger logs logs, err := h.db.GetTriggerLogs(repoName, branchName, since, limit) if err != nil { logger.Error("Failed to get trigger logs: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } // Convert to response format response := make([]TriggerLogResponse, len(logs)) for i, log := range logs { response[i] = TriggerLogResponse{ ID: log.ID, RepositoryName: log.RepositoryName, BranchName: log.BranchName, CommitSHA: log.CommitSHA, JobName: log.JobName, Status: log.Status, ErrorMessage: log.ErrorMessage, CreatedAt: log.CreatedAt, } } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) }