From 35d51b99d0c63ffa3a86bcf2513b6577a83fc0f3 Mon Sep 17 00:00:00 2001 From: pahmiudahgede Date: Wed, 5 Feb 2025 15:21:50 +0700 Subject: [PATCH] feat: add feature get list role for admin user --- dto/role_dto.go | 8 +++ internal/handler/role_handler.go | 47 ++++++++++++- internal/repositories/role_repo.go | 10 +++ internal/services/role_service.go | 104 ++++++++++++++++++++++++++++- presentation/role_route.go | 21 ++++++ router/setup_routes.go.go | 1 + 6 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 dto/role_dto.go create mode 100644 presentation/role_route.go diff --git a/dto/role_dto.go b/dto/role_dto.go new file mode 100644 index 0000000..6002fc7 --- /dev/null +++ b/dto/role_dto.go @@ -0,0 +1,8 @@ +package dto + +type RoleResponseDTO struct { + ID string `json:"role_id"` + RoleName string `json:"role_name"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} diff --git a/internal/handler/role_handler.go b/internal/handler/role_handler.go index cd97792..a4cf541 100644 --- a/internal/handler/role_handler.go +++ b/internal/handler/role_handler.go @@ -1 +1,46 @@ -package handler \ No newline at end of file +package handler + +import ( + "github.com/gofiber/fiber/v2" + "github.com/pahmiudahgede/senggoldong/internal/services" + "github.com/pahmiudahgede/senggoldong/utils" +) + +type RoleHandler struct { + RoleService services.RoleService +} + +func NewRoleHandler(roleService services.RoleService) *RoleHandler { + return &RoleHandler{RoleService: roleService} +} + +func (h *RoleHandler) GetRoles(c *fiber.Ctx) error { + + roleID, ok := c.Locals("roleID").(string) + if !ok || roleID != utils.RoleAdministrator { + return utils.GenericErrorResponse(c, fiber.StatusForbidden, "Forbidden: You don't have permission to access this resource") + } + + roles, err := h.RoleService.GetRoles() + if err != nil { + return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, err.Error()) + } + + return utils.LogResponse(c, roles, "Roles fetched successfully") +} + +func (h *RoleHandler) GetRoleByID(c *fiber.Ctx) error { + roleID := c.Params("role_id") + + roleIDFromSession, ok := c.Locals("roleID").(string) + if !ok || roleIDFromSession != utils.RoleAdministrator { + return utils.GenericErrorResponse(c, fiber.StatusForbidden, "Forbidden: You don't have permission to access this resource") + } + + role, err := h.RoleService.GetRoleByID(roleID) + if err != nil { + return utils.GenericErrorResponse(c, fiber.StatusNotFound, "role id tidak ditemukan") + } + + return utils.LogResponse(c, role, "Role fetched successfully") +} diff --git a/internal/repositories/role_repo.go b/internal/repositories/role_repo.go index f3f8ba4..7abea10 100644 --- a/internal/repositories/role_repo.go +++ b/internal/repositories/role_repo.go @@ -7,6 +7,7 @@ import ( type RoleRepository interface { FindByID(id string) (*model.Role, error) + FindAll() ([]model.Role, error) } type roleRepository struct { @@ -25,3 +26,12 @@ func (r *roleRepository) FindByID(id string) (*model.Role, error) { } return &role, nil } + +func (r *roleRepository) FindAll() ([]model.Role, error) { + var roles []model.Role + err := r.DB.Find(&roles).Error + if err != nil { + return nil, err + } + return roles, nil +} diff --git a/internal/services/role_service.go b/internal/services/role_service.go index c1ce6ce..c8a8741 100644 --- a/internal/services/role_service.go +++ b/internal/services/role_service.go @@ -1 +1,103 @@ -package services \ No newline at end of file +package services + +import ( + "fmt" + "time" + + "github.com/pahmiudahgede/senggoldong/dto" + "github.com/pahmiudahgede/senggoldong/internal/repositories" + "github.com/pahmiudahgede/senggoldong/utils" +) + +type RoleService interface { + GetRoles() ([]dto.RoleResponseDTO, error) + GetRoleByID(roleID string) (*dto.RoleResponseDTO, error) +} + +type roleService struct { + RoleRepo repositories.RoleRepository +} + +func NewRoleService(roleRepo repositories.RoleRepository) RoleService { + return &roleService{RoleRepo: roleRepo} +} + +func (s *roleService) GetRoles() ([]dto.RoleResponseDTO, error) { + + cacheKey := "roles_list" + cachedData, err := utils.GetJSONData(cacheKey) + if err == nil && cachedData != nil { + var roles []dto.RoleResponseDTO + if data, ok := cachedData["data"].([]interface{}); ok { + for _, item := range data { + role, ok := item.(map[string]interface{}) + if ok { + roles = append(roles, dto.RoleResponseDTO{ + ID: role["role_id"].(string), + RoleName: role["role_name"].(string), + CreatedAt: role["createdAt"].(string), + UpdatedAt: role["updatedAt"].(string), + }) + } + } + return roles, nil + } + } + + roles, err := s.RoleRepo.FindAll() + if err != nil { + return nil, fmt.Errorf("failed to fetch roles: %v", err) + } + + var roleDTOs []dto.RoleResponseDTO + for _, role := range roles { + createdAt, _ := utils.FormatDateToIndonesianFormat(role.CreatedAt) + updatedAt, _ := utils.FormatDateToIndonesianFormat(role.UpdatedAt) + + roleDTOs = append(roleDTOs, dto.RoleResponseDTO{ + ID: role.ID, + RoleName: role.RoleName, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + }) + } + + cacheData := map[string]interface{}{ + "data": roleDTOs, + } + err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) + if err != nil { + fmt.Printf("Error caching roles data to Redis: %v\n", err) + } + + return roleDTOs, nil +} + +func (s *roleService) GetRoleByID(roleID string) (*dto.RoleResponseDTO, error) { + + role, err := s.RoleRepo.FindByID(roleID) + if err != nil { + return nil, fmt.Errorf("role not found: %v", err) + } + + createdAt, _ := utils.FormatDateToIndonesianFormat(role.CreatedAt) + updatedAt, _ := utils.FormatDateToIndonesianFormat(role.UpdatedAt) + + roleDTO := &dto.RoleResponseDTO{ + ID: role.ID, + RoleName: role.RoleName, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + } + + cacheKey := fmt.Sprintf("role:%s", roleID) + cacheData := map[string]interface{}{ + "data": roleDTO, + } + err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) + if err != nil { + fmt.Printf("Error caching role data to Redis: %v\n", err) + } + + return roleDTO, nil +} diff --git a/presentation/role_route.go b/presentation/role_route.go new file mode 100644 index 0000000..ff19b49 --- /dev/null +++ b/presentation/role_route.go @@ -0,0 +1,21 @@ +// presentation/role_route.go +package presentation + +import ( + "github.com/gofiber/fiber/v2" + "github.com/pahmiudahgede/senggoldong/config" + "github.com/pahmiudahgede/senggoldong/internal/handler" + "github.com/pahmiudahgede/senggoldong/internal/repositories" + "github.com/pahmiudahgede/senggoldong/internal/services" + "github.com/pahmiudahgede/senggoldong/middleware" + "github.com/pahmiudahgede/senggoldong/utils" +) + +func RoleRouter(api fiber.Router) { + roleRepo := repositories.NewRoleRepository(config.DB) + roleService := services.NewRoleService(roleRepo) + roleHandler := handler.NewRoleHandler(roleService) + + api.Get("/roles", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator), roleHandler.GetRoles) + api.Get("/role/:role_id", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator), roleHandler.GetRoleByID) +} diff --git a/router/setup_routes.go.go b/router/setup_routes.go.go index c538fde..f928fc5 100644 --- a/router/setup_routes.go.go +++ b/router/setup_routes.go.go @@ -12,4 +12,5 @@ func SetupRoutes(app *fiber.App) { presentation.AuthRouter(api) presentation.UserProfileRouter(api) presentation.UserPinRouter(api) + presentation.RoleRouter(api) }