Files
artifactapi/internal/api/v2/stats.go
T
benvin a481a5c3b7 feat: tree view for cached objects, top-files stats on dashboard (#48)
- Objects page renders paths as a collapsible tree instead of flat list
  with expand/collapse all, aggregated size/hits per directory
- Dashboard gains top-files-by-hits and top-files-by-bandwidth tables
- Backend: new /api/v2/stats/top-files-by-hits and
  /api/v2/stats/top-files-by-bandwidth endpoints
- Raised per_page max to 5000 for objects listing

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #48
2026-06-22 22:49:56 +10:00

63 lines
1.5 KiB
Go

package v2
import (
"net/http"
"github.com/go-chi/chi/v5"
"git.unkin.net/unkin/artifactapi/internal/database"
)
type StatsHandler struct {
db *database.DB
}
func NewStatsHandler(db *database.DB) *StatsHandler {
return &StatsHandler{db: db}
}
func (h *StatsHandler) Routes() chi.Router {
r := chi.NewRouter()
r.Get("/", h.overview)
r.Get("/top-remotes", h.topRemotes)
r.Get("/top-files-by-hits", h.topFilesByHits)
r.Get("/top-files-by-bandwidth", h.topFilesByBandwidth)
return r
}
func (h *StatsHandler) overview(w http.ResponseWriter, r *http.Request) {
stats, err := h.db.GetOverviewStats(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, http.StatusOK, stats)
}
func (h *StatsHandler) topRemotes(w http.ResponseWriter, r *http.Request) {
remotes, err := h.db.GetTopRemotes(r.Context(), 10)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, http.StatusOK, remotes)
}
func (h *StatsHandler) topFilesByHits(w http.ResponseWriter, r *http.Request) {
files, err := h.db.GetTopFilesByHits(r.Context(), 10)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, http.StatusOK, files)
}
func (h *StatsHandler) topFilesByBandwidth(w http.ResponseWriter, r *http.Request) {
files, err := h.db.GetTopFilesByBandwidth(r.Context(), 10)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, http.StatusOK, files)
}