add regenerate endpoint
Some checks failed
continuous-integration/drone/push Build was killed

This commit is contained in:
2026-01-14 10:06:26 +11:00
parent ca8b39ba0e
commit aa4567d7c1
3 changed files with 126 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
package handler
import (
"context"
"encoding/json"
"net/http"
"strings"
"time"
"vctp/internal/tasks"
)
// SnapshotAggregateForce forces regeneration of a daily or monthly summary table.
// @Summary Force snapshot aggregation
// @Description Forces regeneration of a daily or monthly summary table for a specified date or month.
// @Tags snapshots
// @Produce json
// @Param type query string true "Aggregation type: daily or monthly"
// @Param date query string true "Daily date (YYYY-MM-DD) or monthly date (YYYY-MM)"
// @Success 200 {object} map[string]string "Aggregation complete"
// @Failure 400 {object} map[string]string "Invalid request"
// @Failure 500 {object} map[string]string "Server error"
// @Router /api/snapshots/aggregate [post]
func (h *Handler) SnapshotAggregateForce(w http.ResponseWriter, r *http.Request) {
snapshotType := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("type")))
dateValue := strings.TrimSpace(r.URL.Query().Get("date"))
if snapshotType == "" || dateValue == "" {
writeJSONError(w, http.StatusBadRequest, "type and date are required")
return
}
ctx := context.Background()
ct := &tasks.CronTask{
Logger: h.Logger,
Database: h.Database,
Settings: h.Settings,
}
switch snapshotType {
case "daily":
parsed, err := time.Parse("2006-01-02", dateValue)
if err != nil {
writeJSONError(w, http.StatusBadRequest, "date must be YYYY-MM-DD")
return
}
if err := ct.AggregateDailySummary(ctx, parsed, true); err != nil {
writeJSONError(w, http.StatusInternalServerError, err.Error())
return
}
case "monthly":
parsed, err := time.Parse("2006-01", dateValue)
if err != nil {
writeJSONError(w, http.StatusBadRequest, "date must be YYYY-MM")
return
}
if err := ct.AggregateMonthlySummary(ctx, parsed, true); err != nil {
writeJSONError(w, http.StatusInternalServerError, err.Error())
return
}
default:
writeJSONError(w, http.StatusBadRequest, "type must be daily or monthly")
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"status": "OK",
})
}
func writeJSONError(w http.ResponseWriter, status int, message string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(map[string]string{
"status": "ERROR",
"message": message,
})
}

View File

@@ -51,6 +51,7 @@ func New(logger *slog.Logger, database db.Database, buildTime string, sha1ver st
mux.HandleFunc("/api/report/inventory", h.InventoryReportDownload)
mux.HandleFunc("/api/report/updates", h.UpdateReportDownload)
mux.HandleFunc("/api/report/snapshot", h.SnapshotReportDownload)
mux.HandleFunc("/api/snapshots/aggregate", h.SnapshotAggregateForce)
mux.HandleFunc("/snapshots/hourly", h.SnapshotHourlyList)
mux.HandleFunc("/snapshots/daily", h.SnapshotDailyList)