293 lines
10 KiB
Go
293 lines
10 KiB
Go
// internal/admin/approval_handler.go
|
|
package admin
|
|
|
|
import (
|
|
"rijig/middleware"
|
|
"rijig/utils"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type ApprovalHandler struct {
|
|
service ApprovalService
|
|
}
|
|
|
|
func NewApprovalHandler(service ApprovalService) *ApprovalHandler {
|
|
return &ApprovalHandler{
|
|
service: service,
|
|
}
|
|
}
|
|
|
|
// GetPendingUsers menampilkan daftar pengguna yang menunggu persetujuan
|
|
// @Summary Get pending users for approval
|
|
// @Description Retrieve list of users (pengelola/pengepul) waiting for admin approval with filtering and pagination
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param role query string false "Filter by role" Enums(pengelola, pengepul)
|
|
// @Param status query string false "Filter by status" Enums(awaiting_approval, pending) default(awaiting_approval)
|
|
// @Param page query int false "Page number" default(1) minimum(1)
|
|
// @Param limit query int false "Items per page" default(20) minimum(1) maximum(100)
|
|
// @Success 200 {object} utils.Response{data=PendingUsersListResponse} "List of pending users"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/pending [get]
|
|
func (h *ApprovalHandler) GetPendingUsers(c *fiber.Ctx) error {
|
|
// Parse query parameters
|
|
var req GetPendingUsersRequest
|
|
if err := c.QueryParser(&req); err != nil {
|
|
return utils.BadRequest(c, "Invalid query parameters: "+err.Error())
|
|
}
|
|
|
|
// Validate request
|
|
// if err := h.validator.Struct(&req); err != nil {
|
|
// return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", err.Error())
|
|
// }
|
|
|
|
// Call service
|
|
result, err := h.service.GetPendingUsers(c.Context(), &req)
|
|
if err != nil {
|
|
return utils.InternalServerError(c, "Failed to get pending users: "+err.Error())
|
|
}
|
|
|
|
return utils.SuccessWithData(c, "Pending users retrieved successfully", result)
|
|
}
|
|
|
|
// GetUserApprovalDetails menampilkan detail lengkap pengguna untuk approval
|
|
// @Summary Get user approval details
|
|
// @Description Get detailed information of a specific user for approval decision
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param user_id path string true "User ID" format(uuid)
|
|
// @Success 200 {object} utils.Response{data=PendingUserResponse} "User approval details"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 404 {object} utils.Response "User not found"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/{user_id}/approval-details [get]
|
|
func (h *ApprovalHandler) GetUserApprovalDetails(c *fiber.Ctx) error {
|
|
userID := c.Params("user_id")
|
|
if userID == "" {
|
|
return utils.BadRequest(c, "User ID is required")
|
|
}
|
|
|
|
// Validate UUID format
|
|
// if err := h.validator.Var(userID, "uuid"); err != nil {
|
|
// return utils.BadRequest(c, "Invalid user ID format")
|
|
// }
|
|
|
|
// Call service
|
|
result, err := h.service.GetUserApprovalDetails(c.Context(), userID)
|
|
if err != nil {
|
|
if err.Error() == "user not found" {
|
|
return utils.NotFound(c, "User not found")
|
|
}
|
|
return utils.InternalServerError(c, "Failed to get user details: "+err.Error())
|
|
}
|
|
|
|
return utils.SuccessWithData(c, "User approval details retrieved successfully", result)
|
|
}
|
|
|
|
// ProcessApprovalAction memproses aksi approval (approve/reject) untuk satu user
|
|
// @Summary Process approval action
|
|
// @Description Approve or reject a user registration
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param request body ApprovalActionRequest true "Approval action request"
|
|
// @Success 200 {object} utils.Response{data=ApprovalActionResponse} "Approval processed successfully"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 404 {object} utils.Response "User not found"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/approval-action [post]
|
|
func (h *ApprovalHandler) ProcessApprovalAction(c *fiber.Ctx) error {
|
|
// Get admin ID from context
|
|
adminClaims, err := middleware.GetUserFromContext(c)
|
|
if err != nil {
|
|
return utils.Unauthorized(c, "Admin authentication required")
|
|
}
|
|
|
|
// Parse request body
|
|
var req ApprovalActionRequest
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return utils.BadRequest(c, "Invalid request body: "+err.Error())
|
|
}
|
|
|
|
// Validate request
|
|
// if err := h.validator.Struct(&req); err != nil {
|
|
// return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", err.Error())
|
|
// }
|
|
|
|
// Call service
|
|
result, err := h.service.ProcessApprovalAction(c.Context(), &req, adminClaims.UserID)
|
|
if err != nil {
|
|
if err.Error() == "user not found" {
|
|
return utils.NotFound(c, "User not found")
|
|
}
|
|
return utils.InternalServerError(c, "Failed to process approval: "+err.Error())
|
|
}
|
|
|
|
actionMessage := "User approved successfully"
|
|
if req.Action == "reject" {
|
|
actionMessage = "User rejected successfully"
|
|
}
|
|
|
|
return utils.SuccessWithData(c, actionMessage, result)
|
|
}
|
|
|
|
// BulkProcessApproval memproses aksi approval untuk multiple users sekaligus
|
|
// @Summary Bulk process approval actions
|
|
// @Description Approve or reject multiple users at once
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param request body BulkApprovalRequest true "Bulk approval request"
|
|
// @Success 200 {object} utils.Response{data=BulkApprovalResponse} "Bulk approval processed"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/bulk-approval [post]
|
|
func (h *ApprovalHandler) BulkProcessApproval(c *fiber.Ctx) error {
|
|
// Get admin ID from context
|
|
adminClaims, err := middleware.GetUserFromContext(c)
|
|
if err != nil {
|
|
return utils.Unauthorized(c, "Admin authentication required")
|
|
}
|
|
|
|
// Parse request body
|
|
var req BulkApprovalRequest
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return utils.BadRequest(c, "Invalid request body: "+err.Error())
|
|
}
|
|
|
|
// Validate request
|
|
// if err := h.validator.Struct(&req); err != nil {
|
|
// return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", err.Error())
|
|
// }
|
|
|
|
// Call service
|
|
result, err := h.service.BulkProcessApproval(c.Context(), &req, adminClaims.UserID)
|
|
if err != nil {
|
|
return utils.InternalServerError(c, "Failed to process bulk approval: "+err.Error())
|
|
}
|
|
|
|
actionMessage := "Bulk approval processed successfully"
|
|
if req.Action == "reject" {
|
|
actionMessage = "Bulk rejection processed successfully"
|
|
}
|
|
|
|
return utils.SuccessWithData(c, actionMessage, result)
|
|
}
|
|
|
|
// ApproveUser endpoint khusus untuk approve satu user (shortcut)
|
|
// @Summary Approve user
|
|
// @Description Approve a user registration (shortcut endpoint)
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param user_id path string true "User ID" format(uuid)
|
|
// @Param notes body string false "Optional approval notes"
|
|
// @Success 200 {object} utils.Response{data=ApprovalActionResponse} "User approved successfully"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 404 {object} utils.Response "User not found"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/{user_id}/approve [post]
|
|
func (h *ApprovalHandler) ApproveUser(c *fiber.Ctx) error {
|
|
userID := c.Params("user_id")
|
|
if userID == "" {
|
|
return utils.BadRequest(c, "User ID is required")
|
|
}
|
|
|
|
// Validate UUID format
|
|
// if err := h.validator.Var(userID, "uuid"); err != nil {
|
|
// return utils.BadRequest(c, "Invalid user ID format")
|
|
// }
|
|
|
|
// Get admin ID from context
|
|
adminClaims, err := middleware.GetUserFromContext(c)
|
|
if err != nil {
|
|
return utils.Unauthorized(c, "Admin authentication required")
|
|
}
|
|
|
|
// Parse optional notes from body
|
|
var body struct {
|
|
Notes string `json:"notes"`
|
|
}
|
|
c.BodyParser(&body) // Ignore error as notes are optional
|
|
|
|
// Call service
|
|
result, err := h.service.ApproveUser(c.Context(), userID, adminClaims.UserID, body.Notes)
|
|
if err != nil {
|
|
if err.Error() == "user not found" {
|
|
return utils.NotFound(c, "User not found")
|
|
}
|
|
return utils.InternalServerError(c, "Failed to approve user: "+err.Error())
|
|
}
|
|
|
|
return utils.SuccessWithData(c, "User approved successfully", result)
|
|
}
|
|
|
|
// RejectUser endpoint khusus untuk reject satu user (shortcut)
|
|
// @Summary Reject user
|
|
// @Description Reject a user registration (shortcut endpoint)
|
|
// @Tags Admin - User Approval
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param user_id path string true "User ID" format(uuid)
|
|
// @Param notes body string false "Optional rejection notes"
|
|
// @Success 200 {object} utils.Response{data=ApprovalActionResponse} "User rejected successfully"
|
|
// @Failure 400 {object} utils.Response "Bad request"
|
|
// @Failure 401 {object} utils.Response "Unauthorized"
|
|
// @Failure 403 {object} utils.Response "Forbidden - Admin role required"
|
|
// @Failure 404 {object} utils.Response "User not found"
|
|
// @Failure 500 {object} utils.Response "Internal server error"
|
|
// @Security Bearer
|
|
// @Router /admin/users/{user_id}/reject [post]
|
|
func (h *ApprovalHandler) RejectUser(c *fiber.Ctx) error {
|
|
userID := c.Params("user_id")
|
|
if userID == "" {
|
|
return utils.BadRequest(c, "User ID is required")
|
|
}
|
|
|
|
// Validate UUID format
|
|
// if err := h.validator.Var(userID, "uuid"); err != nil {
|
|
// return utils.BadRequest(c, "Invalid user ID format")
|
|
// }
|
|
|
|
// Get admin ID from context
|
|
adminClaims, err := middleware.GetUserFromContext(c)
|
|
if err != nil {
|
|
return utils.Unauthorized(c, "Admin authentication required")
|
|
}
|
|
|
|
// Parse optional notes from body
|
|
var body struct {
|
|
Notes string `json:"notes"`
|
|
}
|
|
c.BodyParser(&body) // Ignore error as notes are optional
|
|
|
|
// Call service
|
|
result, err := h.service.RejectUser(c.Context(), userID, adminClaims.UserID, body.Notes)
|
|
if err != nil {
|
|
if err.Error() == "user not found" {
|
|
return utils.NotFound(c, "User not found")
|
|
}
|
|
return utils.InternalServerError(c, "Failed to reject user: "+err.Error())
|
|
}
|
|
|
|
return utils.SuccessWithData(c, "User rejected successfully", result)
|
|
} |