|
| 1 | +// pkg/api/handlers.go |
| 2 | + |
1 | 3 | package api |
2 | 4 |
|
3 | 5 | import ( |
4 | 6 | "net/http" |
| 7 | + "strconv" |
| 8 | + "time" |
5 | 9 |
|
6 | 10 | "github.com/gin-gonic/gin" |
| 11 | + "github.com/moosh3/github-actions-aggregator/pkg/db/models" |
| 12 | + "gorm.io/gorm" |
7 | 13 | ) |
8 | 14 |
|
9 | | -func GetStats(c *gin.Context) { |
10 | | - // Placeholder for actual logic |
11 | | - stats := map[string]interface{}{ |
12 | | - "total_runs": 100, |
13 | | - "success_rate": 95.0, |
| 15 | +func GetWorkflowStats(c *gin.Context) { |
| 16 | + workflowIDParam := c.Param("id") |
| 17 | + startTimeParam := c.Query("start_time") |
| 18 | + endTimeParam := c.Query("end_time") |
| 19 | + |
| 20 | + // Convert workflowID to integer |
| 21 | + workflowID, err := strconv.ParseInt(workflowIDParam, 10, 64) |
| 22 | + if err != nil { |
| 23 | + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid workflow ID"}) |
| 24 | + return |
| 25 | + } |
| 26 | + |
| 27 | + // Parse start and end times |
| 28 | + var startTime, endTime time.Time |
| 29 | + if startTimeParam != "" { |
| 30 | + startTime, err = time.Parse(time.RFC3339, startTimeParam) |
| 31 | + if err != nil { |
| 32 | + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid start_time format"}) |
| 33 | + return |
| 34 | + } |
| 35 | + } else { |
| 36 | + startTime = time.Now().AddDate(0, 0, -30) |
| 37 | + } |
| 38 | + |
| 39 | + if endTimeParam != "" { |
| 40 | + endTime, err = time.Parse(time.RFC3339, endTimeParam) |
| 41 | + if err != nil { |
| 42 | + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid end_time format"}) |
| 43 | + return |
| 44 | + } |
| 45 | + } else { |
| 46 | + endTime = time.Now() |
| 47 | + } |
| 48 | + |
| 49 | + if !startTime.Before(endTime) { |
| 50 | + c.JSON(http.StatusBadRequest, gin.H{"error": "start_time must be before end_time"}) |
| 51 | + return |
| 52 | + } |
| 53 | + |
| 54 | + // Access the database |
| 55 | + db, ok := c.MustGet("db").(*gorm.DB) |
| 56 | + if !ok { |
| 57 | + c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection not found"}) |
| 58 | + return |
14 | 59 | } |
15 | | - c.JSON(http.StatusOK, stats) |
| 60 | + |
| 61 | + // Check if the workflow exists |
| 62 | + var workflow models.Workflow |
| 63 | + err = db.First(&workflow, "id = ?", workflowID).Error |
| 64 | + if err != nil { |
| 65 | + if err == gorm.ErrRecordNotFound { |
| 66 | + c.JSON(http.StatusNotFound, gin.H{"error": "Workflow not found"}) |
| 67 | + } else { |
| 68 | + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve workflow"}) |
| 69 | + } |
| 70 | + return |
| 71 | + } |
| 72 | + |
| 73 | + // Query workflow runs |
| 74 | + var runs []models.WorkflowRun |
| 75 | + err = db.Where("workflow_id = ?", workflowID). |
| 76 | + Where("created_at BETWEEN ? AND ?", startTime, endTime). |
| 77 | + Find(&runs).Error |
| 78 | + if err != nil { |
| 79 | + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve workflow runs"}) |
| 80 | + return |
| 81 | + } |
| 82 | + |
| 83 | + // Calculate statistics |
| 84 | + totalRuns := len(runs) |
| 85 | + successCount := 0 |
| 86 | + failureCount := 0 |
| 87 | + |
| 88 | + for _, run := range runs { |
| 89 | + switch run.Conclusion { |
| 90 | + case "success": |
| 91 | + successCount++ |
| 92 | + case "failure": |
| 93 | + failureCount++ |
| 94 | + } |
| 95 | + } |
| 96 | + |
| 97 | + // Calculate percentages |
| 98 | + var successRate, failureRate float64 |
| 99 | + if totalRuns > 0 { |
| 100 | + successRate = float64(successCount) / float64(totalRuns) * 100 |
| 101 | + failureRate = float64(failureCount) / float64(totalRuns) * 100 |
| 102 | + } |
| 103 | + |
| 104 | + // Respond with statistics |
| 105 | + c.JSON(http.StatusOK, gin.H{ |
| 106 | + "workflow_id": workflowID, |
| 107 | + "workflow_name": workflow.Name, |
| 108 | + "total_runs": totalRuns, |
| 109 | + "success_count": successCount, |
| 110 | + "failure_count": failureCount, |
| 111 | + "success_rate": successRate, |
| 112 | + "failure_rate": failureRate, |
| 113 | + "start_time": startTime.Format(time.RFC3339), |
| 114 | + "end_time": endTime.Format(time.RFC3339), |
| 115 | + }) |
16 | 116 | } |
0 commit comments