package handler import ( "net/http" "strconv" "time" "github.com/gin-gonic/gin" "github.com/dhao2001/mygo/internal/api" "github.com/dhao2001/mygo/internal/model" "github.com/dhao2001/mygo/internal/service" ) // AdminHandler handles admin-only endpoints for user management. type AdminHandler struct { adminService *service.AdminService } // NewAdminHandler creates an AdminHandler. func NewAdminHandler(adminService *service.AdminService) *AdminHandler { return &AdminHandler{adminService: adminService} } // adminUserResponse exposes all user fields, including status, for admin views. type adminUserResponse struct { ID string `json:"id"` Username string `json:"username"` Email string `json:"email"` IsAdmin bool `json:"is_admin"` Status string `json:"status"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // adminUserListResponse wraps a paginated list of admin user views. type adminUserListResponse struct { Users []adminUserResponse `json:"users"` Total int64 `json:"total"` } func toAdminResponse(u *model.User) adminUserResponse { return adminUserResponse{ ID: u.ID, Username: u.Username, Email: u.Email, IsAdmin: u.IsAdmin, Status: u.Status, CreatedAt: u.CreatedAt, UpdatedAt: u.UpdatedAt, } } // DeleteUser handles DELETE /api/v1/admin/users/:id — soft-deletes a user. func (h *AdminHandler) DeleteUser(c *gin.Context) { id := c.Param("id") if err := h.adminService.DeleteUser(c.Request.Context(), id); err != nil { api.RespondError(c, err) return } c.Status(http.StatusNoContent) } // GetUser handles GET /api/v1/admin/users/:id — returns a user including deleted. func (h *AdminHandler) GetUser(c *gin.Context) { id := c.Param("id") user, err := h.adminService.GetUser(c.Request.Context(), id) if err != nil { api.RespondError(c, err) return } c.JSON(http.StatusOK, toAdminResponse(user)) } // ListUsers handles GET /api/v1/admin/users — returns a paginated list of all users. func (h *AdminHandler) ListUsers(c *gin.Context) { offset, err := strconv.Atoi(c.DefaultQuery("offset", "0")) if err != nil || offset < 0 { api.Error(c, http.StatusBadRequest, "invalid offset") return } limit, err := strconv.Atoi(c.DefaultQuery("limit", "50")) if err != nil || limit < 1 { api.Error(c, http.StatusBadRequest, "invalid limit") return } if limit > 200 { limit = 200 } users, total, err := h.adminService.ListUsers(c.Request.Context(), offset, limit) if err != nil { api.RespondError(c, err) return } items := make([]adminUserResponse, 0, len(users)) for i := range users { items = append(items, toAdminResponse(&users[i])) } c.JSON(http.StatusOK, adminUserListResponse{ Users: items, Total: total, }) }