94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package handlers
|
|
|
|
import (
|
|
"go-server/internal/service"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type DailyOverviewController struct {
|
|
service *service.DailyOverviewService
|
|
}
|
|
|
|
func NewDailyOverviewController(service *service.DailyOverviewService) *DailyOverviewController {
|
|
return &DailyOverviewController{
|
|
service: service,
|
|
}
|
|
}
|
|
|
|
// GetDailyOverview returns comprehensive daily nutrient overview
|
|
// GET /api/daily-overview/overview
|
|
func (h *DailyOverviewController) GetDailyOverview(c *gin.Context) {
|
|
overview, err := h.service.GetDailyOverview(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get daily overview"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, overview)
|
|
}
|
|
|
|
// GetNutrientTotals returns just the aggregated nutrient totals
|
|
// GET /api/daily-overview/totals
|
|
func (h *DailyOverviewController) GetNutrientTotals(c *gin.Context) {
|
|
totals, err := h.service.GetNutrientTotals(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get nutrient totals"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, totals)
|
|
}
|
|
|
|
// GetSupplementBreakdown returns detailed breakdown by supplement
|
|
// GET /api/daily-overview/breakdown
|
|
func (h *DailyOverviewController) GetSupplementBreakdown(c *gin.Context) {
|
|
breakdown, err := h.service.GetSupplementBreakdown(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get supplement breakdown"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, breakdown)
|
|
}
|
|
|
|
// ExecuteCustomQuery allows executing custom SQL queries via API
|
|
// POST /api/daily-overview/query
|
|
// Body: {"query": "SELECT ...", "args": [...]}
|
|
func (h *DailyOverviewController) ExecuteCustomQuery(c *gin.Context) {
|
|
var request struct {
|
|
Query string `json:"query"`
|
|
Args []interface{} `json:"args"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
|
return
|
|
}
|
|
|
|
if request.Query == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Query is required"})
|
|
return
|
|
}
|
|
|
|
// Basic security: only allow SELECT statements
|
|
queryUpper := strings.ToUpper(strings.TrimSpace(request.Query))
|
|
if !strings.HasPrefix(queryUpper, "SELECT") {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Only SELECT queries are allowed"})
|
|
return
|
|
}
|
|
|
|
results, err := h.service.ExecuteCustomQuery(c.Request.Context(), request.Query, request.Args...)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to execute query"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"results": results,
|
|
"count": len(results),
|
|
})
|
|
}
|