chore: update admin apis

This commit is contained in:
Krispire Admin
2026-06-16 15:48:44 +05:30
parent 4c42d9a7f9
commit 04ad94ad3c
4 changed files with 35 additions and 16 deletions
+10
View File
@@ -46,6 +46,16 @@ func meta(total, limit, offset int) *response.Meta {
}
}
// Stats — GET /admin/stats → system snapshot for the dashboard home.
func (h *AdminHandler) Stats(w http.ResponseWriter, r *http.Request) {
snap, err := h.svc.Stats(r.Context())
if err != nil {
response.Error(w, http.StatusInternalServerError, "could not load stats")
return
}
response.JSON(w, http.StatusOK, snap)
}
func (h *AdminHandler) ListUsers(w http.ResponseWriter, r *http.Request) {
q, limit, offset := pageParams(r)
items, total, err := h.svc.ListUsers(r.Context(), q, limit, offset)
+13 -13
View File
@@ -17,22 +17,22 @@ func NewStatsRepo(pg *Postgres) *StatsRepo { return &StatsRepo{pg: pg} }
// StatsSnapshot bundles totals, last-7-days counts, and feedback
// category breakdowns. One value rendered by /stats per request.
type StatsSnapshot struct {
Users int
UsersLast7Days int
Posts int
PostsLast7Days int
Collections int
PublicCollections int
Bookmarks int
Reshares int
Feedback int
FeedbackLast7Days int
FeedbackByCategory []CategoryCount
Users int `json:"users"`
UsersLast7Days int `json:"users_last_7_days"`
Posts int `json:"posts"`
PostsLast7Days int `json:"posts_last_7_days"`
Collections int `json:"collections"`
PublicCollections int `json:"public_collections"`
Bookmarks int `json:"bookmarks"`
Reshares int `json:"reshares"`
Feedback int `json:"feedback"`
FeedbackLast7Days int `json:"feedback_last_7_days"`
FeedbackByCategory []CategoryCount `json:"feedback_by_category"`
}
type CategoryCount struct {
Category string
Count int
Category string `json:"category"`
Count int `json:"count"`
}
// Snapshot runs every count needed by /stats. Queries run in series —
+2 -1
View File
@@ -290,7 +290,7 @@ func (s *Server) initAuth(cfg *config.Config, logger *zap.Logger) {
// Reuses the notification service (delivery) and mailer (feedback reply).
// Gated by RequireAuth + RequireAdmin in the router.
adminRepo := repository.NewAdminRepo(s.pg)
adminSvc := service.NewAdminService(adminRepo, notifSvc, feedbackSvc, mail, logger, cfg.FrontendURL)
adminSvc := service.NewAdminService(adminRepo, statsRepo, notifSvc, feedbackSvc, mail, logger, cfg.FrontendURL)
s.adminH = handler.NewAdminHandler(adminSvc)
}
@@ -986,6 +986,7 @@ func (s *Server) setupRouter() {
}
r.Use(middleware.RequireAuth(s.authIssuer, s.userRepo))
r.Use(middleware.RequireAdmin(s.userRepo))
r.Get("/stats", s.adminH.Stats)
r.Get("/users", s.adminH.ListUsers)
r.Post("/users/{id}/notify", s.adminH.NotifyUser)
r.Post("/users/{id}/ban", s.adminH.BanUser)
+10 -2
View File
@@ -22,6 +22,7 @@ var ErrAdminUserNotFound = errors.New("user not found")
// feedback-reply email — no new infrastructure.
type AdminService struct {
repo *repository.AdminRepo
stats *repository.StatsRepo
notif *NotificationService
feedback *FeedbackService
mail mailer.Mailer
@@ -29,8 +30,15 @@ type AdminService struct {
frontendURL string
}
func NewAdminService(repo *repository.AdminRepo, notif *NotificationService, feedback *FeedbackService, mail mailer.Mailer, logger *zap.Logger, frontendURL string) *AdminService {
return &AdminService{repo: repo, notif: notif, feedback: feedback, mail: mail, logger: logger, frontendURL: frontendURL}
func NewAdminService(repo *repository.AdminRepo, stats *repository.StatsRepo, notif *NotificationService, feedback *FeedbackService, mail mailer.Mailer, logger *zap.Logger, frontendURL string) *AdminService {
return &AdminService{repo: repo, stats: stats, notif: notif, feedback: feedback, mail: mail, logger: logger, frontendURL: frontendURL}
}
// Stats returns the system snapshot (counts + 7-day deltas + feedback
// breakdown) — the same data the public /stats page renders, as JSON for the
// admin dashboard home.
func (s *AdminService) Stats(ctx context.Context) (*repository.StatsSnapshot, error) {
return s.stats.Snapshot(ctx)
}
// AcknowledgeFeedback marks a feedback row acknowledged and emails the author