chore: update admin apis
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 —
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user