add regenerate endpoint
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
68
server/handler/snapshotRegenerateHourly.go
Normal file
68
server/handler/snapshotRegenerateHourly.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"vctp/internal/report"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SnapshotRegenerateHourlyReports regenerates missing hourly snapshot XLSX reports on disk.
|
||||||
|
// @Summary Regenerate hourly snapshot reports
|
||||||
|
// @Description Regenerates XLSX reports for hourly snapshots when the report files are missing or empty.
|
||||||
|
// @Tags snapshots
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} map[string]interface{} "Regeneration summary"
|
||||||
|
// @Failure 500 {object} map[string]string "Server error"
|
||||||
|
// @Router /api/snapshots/regenerate-hourly-reports [post]
|
||||||
|
func (h *Handler) SnapshotRegenerateHourlyReports(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
reportsDir := strings.TrimSpace(h.Settings.Values.Settings.ReportsDir)
|
||||||
|
if reportsDir == "" {
|
||||||
|
reportsDir = "/var/lib/vctp/reports"
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(reportsDir, 0o755); err != nil {
|
||||||
|
h.Logger.Error("failed to create reports directory", "error", err, "path", reportsDir)
|
||||||
|
writeJSONError(w, http.StatusInternalServerError, "failed to create reports directory")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Unix(0, 0)
|
||||||
|
end := time.Now().AddDate(10, 0, 0) // sufficiently in the future to include all records
|
||||||
|
records, err := report.SnapshotRecordsWithFallback(ctx, h.Database, "hourly", "inventory_hourly_", "epoch", start, end)
|
||||||
|
if err != nil {
|
||||||
|
h.Logger.Error("failed to list hourly snapshots", "error", err)
|
||||||
|
writeJSONError(w, http.StatusInternalServerError, "failed to list hourly snapshots")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var regenerated, skipped, errors int
|
||||||
|
for _, rec := range records {
|
||||||
|
dest := filepath.Join(reportsDir, rec.TableName+".xlsx")
|
||||||
|
if info, err := os.Stat(dest); err == nil && info.Size() > 0 {
|
||||||
|
skipped++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, err := report.SaveTableReport(h.Logger, h.Database, ctx, rec.TableName, reportsDir); err != nil {
|
||||||
|
errors++
|
||||||
|
h.Logger.Warn("failed to regenerate hourly report", "table", rec.TableName, "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
regenerated++
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := map[string]interface{}{
|
||||||
|
"status": "OK",
|
||||||
|
"total": len(records),
|
||||||
|
"regenerated": regenerated,
|
||||||
|
"skipped": skipped,
|
||||||
|
"errors": errors,
|
||||||
|
"reports_dir": reportsDir,
|
||||||
|
"snapshotType": "hourly",
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(resp)
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ func New(logger *slog.Logger, database db.Database, buildTime string, sha1ver st
|
|||||||
mux.HandleFunc("/api/report/snapshot", h.SnapshotReportDownload)
|
mux.HandleFunc("/api/report/snapshot", h.SnapshotReportDownload)
|
||||||
mux.HandleFunc("/api/snapshots/aggregate", h.SnapshotAggregateForce)
|
mux.HandleFunc("/api/snapshots/aggregate", h.SnapshotAggregateForce)
|
||||||
mux.HandleFunc("/api/snapshots/migrate", h.SnapshotMigrate)
|
mux.HandleFunc("/api/snapshots/migrate", h.SnapshotMigrate)
|
||||||
|
mux.HandleFunc("/api/snapshots/regenerate-hourly-reports", h.SnapshotRegenerateHourlyReports)
|
||||||
|
|
||||||
mux.HandleFunc("/snapshots/hourly", h.SnapshotHourlyList)
|
mux.HandleFunc("/snapshots/hourly", h.SnapshotHourlyList)
|
||||||
mux.HandleFunc("/snapshots/daily", h.SnapshotDailyList)
|
mux.HandleFunc("/snapshots/daily", h.SnapshotDailyList)
|
||||||
|
|||||||
Reference in New Issue
Block a user