334 lines
10 KiB
Go
334 lines
10 KiB
Go
package handlers
|
|
|
|
import (
|
|
"log/slog"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type CreateAdminReq struct {
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
Email string `json:"email" example:"john.doe@example.com"`
|
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
|
Password string `json:"password" example:"password123"`
|
|
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
|
|
}
|
|
|
|
// CreateAdmin godoc
|
|
// @Summary Create Admin
|
|
// @Description Create Admin
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param manger body CreateAdminReq true "Create admin"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /admin [post]
|
|
func (h *Handler) CreateAdmin(c *fiber.Ctx) error {
|
|
var companyID domain.ValidInt64
|
|
var req CreateAdminReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("RegisterUser failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
// Admins can be created without company ids and can be assigned later
|
|
if req.CompanyID == nil {
|
|
companyID = domain.ValidInt64{
|
|
Value: 0,
|
|
Valid: false,
|
|
}
|
|
} else {
|
|
_, err := h.companySvc.GetCompanyByID(c.Context(), *req.CompanyID)
|
|
if err != nil {
|
|
h.logger.Error("CreateAdmin company id is invalid", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Company ID is invalid", nil, nil)
|
|
}
|
|
companyID = domain.ValidInt64{
|
|
Value: *req.CompanyID,
|
|
Valid: true,
|
|
}
|
|
}
|
|
|
|
user := domain.CreateUserReq{
|
|
FirstName: req.FirstName,
|
|
LastName: req.LastName,
|
|
Email: req.Email,
|
|
PhoneNumber: req.PhoneNumber,
|
|
Password: req.Password,
|
|
Role: string(domain.RoleAdmin),
|
|
CompanyID: companyID,
|
|
}
|
|
|
|
h.logger.Info("CreateAdmin", slog.Bool("company id", req.CompanyID == nil))
|
|
newUser, err := h.userSvc.CreateUser(c.Context(), user, true)
|
|
if err != nil {
|
|
h.logger.Error("CreateAdmin failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create admin", nil, nil)
|
|
}
|
|
|
|
if req.CompanyID != nil {
|
|
_, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
|
ID: *req.CompanyID,
|
|
AdminID: &newUser.ID,
|
|
})
|
|
if err != nil {
|
|
h.logger.Error("CreateAdmin failed to update company", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update company", nil, nil)
|
|
}
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Admin created successfully", nil, nil)
|
|
}
|
|
|
|
type AdminRes struct {
|
|
ID int64 `json:"id"`
|
|
FirstName string `json:"first_name"`
|
|
LastName string `json:"last_name"`
|
|
Email string `json:"email"`
|
|
PhoneNumber string `json:"phone_number"`
|
|
Role domain.Role `json:"role"`
|
|
EmailVerified bool `json:"email_verified"`
|
|
PhoneVerified bool `json:"phone_verified"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
LastLogin time.Time `json:"last_login"`
|
|
SuspendedAt time.Time `json:"suspended_at"`
|
|
Suspended bool `json:"suspended"`
|
|
}
|
|
|
|
// GetAllAdmins godoc
|
|
// @Summary Get all Admins
|
|
// @Description Get all Admins
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param page query int false "Page number"
|
|
// @Param page_size query int false "Page size"
|
|
// @Success 200 {object} AdminRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /admin [get]
|
|
func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
|
|
|
|
filter := user.Filter{
|
|
Role: string(domain.RoleAdmin),
|
|
CompanyID: domain.ValidInt64{
|
|
Value: int64(c.QueryInt("company_id")),
|
|
Valid: false,
|
|
},
|
|
Page: domain.ValidInt{
|
|
Value: c.QueryInt("page", 1) - 1,
|
|
Valid: true,
|
|
},
|
|
PageSize: domain.ValidInt{
|
|
Value: c.QueryInt("page_size", 10),
|
|
Valid: true,
|
|
},
|
|
}
|
|
valErrs, ok := h.validator.Validate(c, filter)
|
|
if !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
admins, total, err := h.userSvc.GetAllUsers(c.Context(), filter)
|
|
if err != nil {
|
|
h.logger.Error("GetAllAdmins failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Admins", nil, nil)
|
|
}
|
|
|
|
var result []AdminRes = make([]AdminRes, len(admins))
|
|
for index, admin := range admins {
|
|
lastLogin, err := h.authSvc.GetLastLogin(c.Context(), admin.ID)
|
|
if err != nil {
|
|
if err == authentication.ErrRefreshTokenNotFound {
|
|
lastLogin = &admin.CreatedAt
|
|
} else {
|
|
h.logger.Error("Failed to get user last login", "userID", admin.ID, "error", err)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user last login")
|
|
}
|
|
}
|
|
result[index] = AdminRes{
|
|
ID: admin.ID,
|
|
FirstName: admin.FirstName,
|
|
LastName: admin.LastName,
|
|
Email: admin.Email,
|
|
PhoneNumber: admin.PhoneNumber,
|
|
Role: admin.Role,
|
|
EmailVerified: admin.EmailVerified,
|
|
PhoneVerified: admin.PhoneVerified,
|
|
CreatedAt: admin.CreatedAt,
|
|
UpdatedAt: admin.UpdatedAt,
|
|
SuspendedAt: admin.SuspendedAt,
|
|
Suspended: admin.Suspended,
|
|
LastLogin: *lastLogin,
|
|
}
|
|
}
|
|
|
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value, int(total))
|
|
}
|
|
|
|
// GetAdminByID godoc
|
|
// @Summary Get admin by id
|
|
// @Description Get a single admin by id
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "User ID"
|
|
// @Success 200 {object} AdminRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /admin/{id} [get]
|
|
func (h *Handler) GetAdminByID(c *fiber.Ctx) error {
|
|
// branchId := int64(12) //c.Locals("branch_id").(int64)
|
|
// filter := user.Filter{
|
|
// Role: string(domain.RoleUser),
|
|
// BranchId: user.ValidBranchId{
|
|
// Value: branchId,
|
|
// Valid: true,
|
|
// },
|
|
// Page: c.QueryInt("page", 1),
|
|
// PageSize: c.QueryInt("page_size", 10),
|
|
// }
|
|
// valErrs, ok := validator.Validate(c, filter)
|
|
// if !ok {
|
|
// return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
// }
|
|
|
|
userIDstr := c.Params("id")
|
|
userID, err := strconv.ParseInt(userIDstr, 10, 64)
|
|
if err != nil {
|
|
h.logger.Error("failed to fetch user using UserID", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid admin ID", nil, nil)
|
|
}
|
|
|
|
user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
|
if err != nil {
|
|
h.logger.Error("Get User By ID failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get admin", nil, nil)
|
|
}
|
|
|
|
lastLogin, err := h.authSvc.GetLastLogin(c.Context(), user.ID)
|
|
if err != nil {
|
|
if err != authentication.ErrRefreshTokenNotFound {
|
|
h.logger.Error("Failed to get user last login", "userID", user.ID, "error", err)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user last login")
|
|
}
|
|
|
|
lastLogin = &user.CreatedAt
|
|
}
|
|
|
|
res := AdminRes{
|
|
ID: user.ID,
|
|
FirstName: user.FirstName,
|
|
LastName: user.LastName,
|
|
Email: user.Email,
|
|
PhoneNumber: user.PhoneNumber,
|
|
Role: user.Role,
|
|
EmailVerified: user.EmailVerified,
|
|
PhoneVerified: user.PhoneVerified,
|
|
CreatedAt: user.CreatedAt,
|
|
UpdatedAt: user.UpdatedAt,
|
|
SuspendedAt: user.SuspendedAt,
|
|
Suspended: user.Suspended,
|
|
LastLogin: *lastLogin,
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "User retrieved successfully", res, nil)
|
|
}
|
|
|
|
type updateAdminReq struct {
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
Suspended bool `json:"suspended" example:"false"`
|
|
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
|
|
}
|
|
|
|
// UpdateAdmin godoc
|
|
// @Summary Update Admin
|
|
// @Description Update Admin
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param admin body updateAdminReq true "Update Admin"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /admin/{id} [put]
|
|
func (h *Handler) UpdateAdmin(c *fiber.Ctx) error {
|
|
var req updateAdminReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("UpdateAdmin failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
|
|
if !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
AdminIDStr := c.Params("id")
|
|
AdminID, err := strconv.ParseInt(AdminIDStr, 10, 64)
|
|
if err != nil {
|
|
h.logger.Error("UpdateAdmin failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Admin ID", nil, nil)
|
|
}
|
|
var companyID domain.ValidInt64
|
|
if req.CompanyID != nil {
|
|
companyID = domain.ValidInt64{
|
|
Value: *req.CompanyID,
|
|
Valid: true,
|
|
}
|
|
}
|
|
err = h.userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
|
|
UserId: AdminID,
|
|
FirstName: domain.ValidString{
|
|
Value: req.FirstName,
|
|
Valid: req.FirstName != "",
|
|
},
|
|
LastName: domain.ValidString{
|
|
Value: req.LastName,
|
|
Valid: req.LastName != "",
|
|
},
|
|
Suspended: domain.ValidBool{
|
|
Value: req.Suspended,
|
|
Valid: true,
|
|
},
|
|
CompanyID: companyID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
h.logger.Error("UpdateAdmin failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update admin", nil, nil)
|
|
}
|
|
if req.CompanyID != nil {
|
|
_, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
|
ID: *req.CompanyID,
|
|
AdminID: &AdminID,
|
|
})
|
|
if err != nil {
|
|
h.logger.Error("CreateAdmin failed to update company", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update company", nil, nil)
|
|
}
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil)
|
|
|
|
}
|