axe/internal/handlers/filters.go

57 lines
1.8 KiB
Go
Raw Normal View History

2026-10-18 19:07:25 +00:00
package handlers
import (
"net/http"
"slices"
"time"
"github.com/gin-gonic/gin"
)
// Фильтры списков, которым нужна проверка значения до ухода в SQL.
// checkFilter — сверяет ?param= со списком допустимых значений.
// Плохое значение — 400 с именем параметра, а не пустой список:
// «введено что-то не то» и «таких записей нет» — разные вещи.
func checkFilter(c *gin.Context, param string, allowed []string) bool {
v := c.Query(param)
if v == "" || slices.Contains(allowed, v) {
return true
}
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid " + param})
return false
}
// dateRange разбирает date_from/date_to в формате YYYY-MM-DD (даты
// по created_at). Верхняя граница сдвигается на сутки: date_to=2026-10-01
// означает «весь день 1 октября», а не «до полуночи 30 сентября».
func dateRange(c *gin.Context) (from, to *time.Time, ok bool) {
parse := func(param string, end bool) (*time.Time, bool) {
v := c.Query(param)
if v == "" {
return nil, true
}
d, err := time.Parse("2006-01-02", v)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid " + param})
return nil, false
}
if end {
d = d.AddDate(0, 0, 1) // верхняя граница исключительная
}
return &d, true
}
if from, ok = parse("date_from", false); !ok {
return nil, nil, false
}
if to, ok = parse("date_to", true); !ok {
return nil, nil, false
}
if from != nil && to != nil && !to.After(*from) {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid date range"})
return nil, nil, false
}
return from, to, true
}