From 4bd48c3bca74ad77ce9c8cb42d64c05ad5b26ed3 Mon Sep 17 00:00:00 2001 From: Habib Fatkhul Rohman Date: Tue, 21 Oct 2025 15:04:58 +0700 Subject: [PATCH] Add role management module with controller, service, repository, DTOs, and routes --- modules/role/controller/role_controller.go | 129 +++++++++++++ modules/role/dto/role_dto.go | 75 ++++++++ modules/role/query/role_query.go | 66 +++++++ modules/role/repository/role_repository.go | 207 +++++++++++++++++++++ modules/role/routes.go | 39 ++++ modules/role/service/role_service.go | 131 +++++++++++++ 6 files changed, 647 insertions(+) create mode 100644 modules/role/controller/role_controller.go create mode 100644 modules/role/dto/role_dto.go create mode 100644 modules/role/query/role_query.go create mode 100644 modules/role/repository/role_repository.go create mode 100644 modules/role/routes.go create mode 100644 modules/role/service/role_service.go diff --git a/modules/role/controller/role_controller.go b/modules/role/controller/role_controller.go new file mode 100644 index 0000000..ff99115 --- /dev/null +++ b/modules/role/controller/role_controller.go @@ -0,0 +1,129 @@ +package controller + +import ( + "net/http" + + "github.com/Caknoooo/go-gin-clean-starter/modules/role/dto" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/query" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/service" + "github.com/Caknoooo/go-gin-clean-starter/pkg/constants" + "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" + "github.com/Caknoooo/go-pagination" + "github.com/gin-gonic/gin" + "github.com/samber/do" + "gorm.io/gorm" +) + +type ( + RoleController interface { + CreateRole(ctx *gin.Context) + GetRoles(ctx *gin.Context) + GetRoleByID(ctx *gin.Context) + UpdateRole(ctx *gin.Context) + DeleteRole(ctx *gin.Context) + AssignPermissionsToRole(ctx *gin.Context) + RemovePermissionsFromRole(ctx *gin.Context) + AssignRoleToUser(ctx *gin.Context) + RemoveRoleFromUser(ctx *gin.Context) + GetRolesByUserID(ctx *gin.Context) + } + + roleController struct { + roleService service.RoleService + db *gorm.DB + } +) + +// AssignPermissionsToRole implements RoleController. +func (r *roleController) AssignPermissionsToRole(ctx *gin.Context) { + panic("unimplemented") +} + +// AssignRoleToUser implements RoleController. +func (r *roleController) AssignRoleToUser(ctx *gin.Context) { + panic("unimplemented") +} + +// CreateRole implements RoleController. +func (r *roleController) CreateRole(ctx *gin.Context) { + var role dto.RoleCreateRequest + if err := ctx.ShouldBind(&role); err != nil { + res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil) + ctx.AbortWithStatusJSON(http.StatusBadRequest, res) + return + } + + result, err := r.roleService.CreateRole(ctx.Request.Context(), role) + if err != nil { + res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_REGISTER_ROLE, err.Error(), nil) + ctx.JSON(http.StatusBadRequest, res) + return + } + + res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_REGISTER_ROLE, result) + ctx.JSON(http.StatusOK, res) + +} + +// DeleteRole implements RoleController. +func (r *roleController) DeleteRole(ctx *gin.Context) { + panic("unimplemented") +} + +// GetRoleByID implements RoleController. +func (r *roleController) GetRoleByID(ctx *gin.Context) { + panic("unimplemented") +} + +// GetRoles implements RoleController. +func (r *roleController) GetRoles(ctx *gin.Context) { + clientId := ctx.MustGet("client_id").(string) + // logrus.Info("Client ID: ", clientId) + var filter = &query.RoleFilter{ + ClientID: clientId, + Name: ctx.Query("name"), + } + // logrus.Info("Filter: ", filter) + filter.BindPagination(ctx) + + ctx.ShouldBindQuery(filter) + + roles, total, err := pagination.PaginatedQueryWithIncludable[query.M_Role](r.db, filter) + if err != nil { + res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_ROLE, err.Error(), nil) + ctx.JSON(http.StatusBadRequest, res) + return + } + + paginationResponse := pagination.CalculatePagination(filter.Pagination, total) + response := pagination.NewPaginatedResponse(http.StatusOK, dto.MESSAGE_SUCCESS_GET_LIST_ROLE, roles, paginationResponse) + ctx.JSON(http.StatusOK, response) +} + +// GetRolesByUserID implements RoleController. +func (r *roleController) GetRolesByUserID(ctx *gin.Context) { + panic("unimplemented") +} + +// RemovePermissionsFromRole implements RoleController. +func (r *roleController) RemovePermissionsFromRole(ctx *gin.Context) { + panic("unimplemented") +} + +// RemoveRoleFromUser implements RoleController. +func (r *roleController) RemoveRoleFromUser(ctx *gin.Context) { + panic("unimplemented") +} + +// UpdateRole implements RoleController. +func (r *roleController) UpdateRole(ctx *gin.Context) { + panic("unimplemented") +} + +func NewRoleController(injector *do.Injector, rs service.RoleService) RoleController { + db := do.MustInvokeNamed[*gorm.DB](injector, constants.DB) + return &roleController{ + roleService: rs, + db: db, + } +} diff --git a/modules/role/dto/role_dto.go b/modules/role/dto/role_dto.go new file mode 100644 index 0000000..bde8b6f --- /dev/null +++ b/modules/role/dto/role_dto.go @@ -0,0 +1,75 @@ +package dto + +import "errors" + +const ( + // Failed + MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body" + MESSAGE_FAILED_REGISTER_ROLE = "failed create user" + MESSAGE_FAILED_GET_LIST_ROLE = "failed get list user" + MESSAGE_FAILED_TOKEN_NOT_VALID = "token not valid" + MESSAGE_FAILED_TOKEN_NOT_FOUND = "token not found" + MESSAGE_FAILED_GET_ROLE = "failed get role" + MESSAGE_FAILED_LOGIN = "failed login" + MESSAGE_FAILED_UPDATE_ROLE = "failed update role" + MESSAGE_FAILED_DELETE_ROLE = "failed delete role" + MESSAGE_FAILED_PROSES_REQUEST = "failed proses request" + MESSAGE_FAILED_DENIED_ACCESS = "denied access" + MESSAGE_FAILED_VERIFY_EMAIL = "failed verify email" + + // Success + MESSAGE_SUCCESS_REGISTER_ROLE = "success create role" + MESSAGE_SUCCESS_GET_LIST_ROLE = "success get list role" + MESSAGE_SUCCESS_GET_ROLE = "success get role" + MESSAGE_SUCCESS_LOGIN = "success login" + MESSAGE_SUCCESS_UPDATE_ROLE = "success update role" + MESSAGE_SUCCESS_DELETE_ROLE = "success delete role" + MESSAGE_SEND_VERIFICATION_EMAIL_SUCCESS = "success send verification email" + MESSAGE_SUCCESS_VERIFY_EMAIL = "success verify email" +) + +var ( + ErrCreateRole = errors.New("failed to create role") + ErrGetRoleById = errors.New("failed to get role by id") + ErrGetRoleByName = errors.New("failed to get role by name") + ErrRoleAlreadyExists = errors.New("role already exist") + ErrUpdateRole = errors.New("failed to update role") + ErrRoleNotFound = errors.New("role not found") + ErrDeleteRole = errors.New("failed to delete role") +) + +type RoleCreateRequest struct { + Name string `json:"name" binding:"required"` + Description string `json:"description" binding:"omitempty"` + IconUrl string `json:"icon_url" binding:"omitempty"` + Type string `json:"type" binding:"omitempty"` + HomeUrl string `json:"home_url" binding:"omitempty"` + ClientID string `json:"client_id" binding:"required,uuid4"` + + RoleMenus []string `json:"role_menus" binding:"omitempty"` + RolePermissions []string `json:"role_permissions" binding:"omitempty"` + UserRoles []string `json:"user_roles" binding:"omitempty"` + Users []string `json:"users" binding:"omitempty"` + Permissions []string `json:"permissions" binding:"omitempty"` +} + +type RoleUpdateRequest struct { + Name string `json:"name" binding:"omitempty"` + Description string `json:"description" binding:"omitempty"` + IconUrl string `json:"icon_url" binding:"omitempty"` + Type string `json:"type" binding:"omitempty"` + HomeUrl string `json:"home_url" binding:"omitempty"` + ClientID string `json:"client_id" binding:"omitempty,uuid4"` + Permissions []string `json:"permissions" binding:"omitempty"` +} + +type RoleResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + IconUrl string `json:"icon_url"` + Type string `json:"type"` + HomeUrl string `json:"home_url"` + ClientID string `json:"client_id"` + Permissions []string `json:"permissions"` +} diff --git a/modules/role/query/role_query.go b/modules/role/query/role_query.go new file mode 100644 index 0000000..8455c73 --- /dev/null +++ b/modules/role/query/role_query.go @@ -0,0 +1,66 @@ +package query + +import ( + "github.com/Caknoooo/go-gin-clean-starter/database/entities" + "github.com/Caknoooo/go-pagination" + "gorm.io/gorm" +) + +type M_Role struct { + ID string `json:"id"` + Name string `json:"name"` + Permissions []entities.M_Permissions `json:"permissions" gorm:"many2many:m_role_permissions;joinForeignKey:RoleID;JoinReferences:PermissionID"` + ClientID string `json:"client_id"` +} + +type RoleFilter struct { + pagination.BaseFilter + Name string `form:"name"` // tambahkan ini + ClientID string `form:"client_id"` // tambahkan ini +} + +func (f *RoleFilter) ApplyFilters(query *gorm.DB) *gorm.DB { + // Apply your filters here + if f.Name != "" { + query = query.Where("name ILIKE ?", "%"+f.Name+"%") + } + if f.ClientID != "" { + query = query.Where("client_id = ?", f.ClientID) + } + return query +} + +func (f *RoleFilter) GetTableName() string { + return "m_roles" +} + +func (f *RoleFilter) GetSearchFields() []string { + return []string{"name"} +} + +func (f *RoleFilter) GetDefaultSort() string { + return "id asc" +} + +func (f *RoleFilter) GetIncludes() []string { + return f.Includes +} + +func (f *RoleFilter) GetPagination() pagination.PaginationRequest { + return f.Pagination +} + +func (f *RoleFilter) Validate() { + var validIncludes []string + allowedIncludes := f.GetAllowedIncludes() + for _, include := range f.Includes { + if allowedIncludes[include] { + validIncludes = append(validIncludes, include) + } + } + f.Includes = validIncludes +} + +func (f *RoleFilter) GetAllowedIncludes() map[string]bool { + return map[string]bool{} +} diff --git a/modules/role/repository/role_repository.go b/modules/role/repository/role_repository.go new file mode 100644 index 0000000..05363f6 --- /dev/null +++ b/modules/role/repository/role_repository.go @@ -0,0 +1,207 @@ +package repository + +import ( + "context" + + "github.com/Caknoooo/go-gin-clean-starter/database/entities" + "github.com/google/uuid" + "gorm.io/gorm" +) + +// UserRepository interface { +// Register(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error) +// GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entities.M_User, error) +// GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, error) +// CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, bool, error) +// Update(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error) +// Delete(ctx context.Context, tx *gorm.DB, userId string) error +// SwitchRole(ctx context.Context, tx *gorm.DB, userId string, roleId string) (entities.M_User, error) +// } + +type RoleRepository interface { + CreateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error) + GetRoleByID(ctx context.Context, tx *gorm.DB, id string) (entities.M_Role, error) + UpdateRole(ctx context.Context, tx *gorm.DB, id string, role entities.M_Role) (entities.M_Role, error) + DeleteRole(ctx context.Context, tx *gorm.DB, id string) error + AssignPermissionsToRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error + RemovePermissionsFromRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error + AssignRoleToUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error + RemoveRoleFromUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error + GetRolesByUserID(ctx context.Context, tx *gorm.DB, userId string) ([]entities.M_Role, error) + CheckRoleName(ctx context.Context, tx *gorm.DB, name string) (entities.M_Role, bool, error) +} + +type roleRepository struct { + db *gorm.DB +} + +// CheckRoleName implements RoleRepository. +func (r *roleRepository) CheckRoleName(ctx context.Context, tx *gorm.DB, name string) (entities.M_Role, bool, error) { + if tx == nil { + tx = r.db + } + var role entities.M_Role + if err := tx.WithContext(ctx).Where("name = ?", name).First(&role).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return entities.M_Role{}, false, nil + } + return entities.M_Role{}, false, err + } + return role, true, nil +} + +// AssignPermissionsToRole implements RoleRepository. +func (r *roleRepository) AssignPermissionsToRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error { + if tx == nil { + tx = r.db + } + if err := tx.WithContext(ctx).Model(&entities.M_Role{}).Where("id = ?", roleId).Update("permissions", gorm.Expr("array_cat(permissions, ?)", permissions)).Error; err != nil { + return err + } + return nil +} + +func (r *roleRepository) AssignRoleToUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error { + if tx == nil { + tx = r.db + } + userUUID, err := uuid.Parse(userId) + if err != nil { + return err + } + roleUUID, err := uuid.Parse(roleId) + if err != nil { + return err + } + + var count int64 + if err := tx.WithContext(ctx). + Model(&entities.M_User_Role{}). + Where("user_id = ? AND role_id = ?", userUUID, roleUUID). + Count(&count).Error; err != nil { + return err + } + if count > 0 { + return nil + } + userRole := entities.M_User_Role{ + UserID: userUUID, + RoleID: roleUUID, + } + // Insert ke tabel user_roles, bukan update ke M_User + if err := tx.WithContext(ctx).Create(&userRole).Error; err != nil { + return err + } + return nil +} + +// CreateRole implements RoleRepository. +func (r *roleRepository) CreateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error) { + if tx == nil { + tx = r.db + } + + if err := tx.WithContext(ctx).Create(&role).Error; err != nil { + return entities.M_Role{}, err + } + + return role, nil +} + +// DeleteRole implements RoleRepository. +func (r *roleRepository) DeleteRole(ctx context.Context, tx *gorm.DB, id string) error { + if tx == nil { + tx = r.db + } + if err := tx.WithContext(ctx).Where("id = ?", id).Delete(&entities.M_Role{}).Error; err != nil { + return err + } + return nil +} + +// GetRoleByID implements RoleRepository. +func (r *roleRepository) GetRoleByID(ctx context.Context, tx *gorm.DB, id string) (entities.M_Role, error) { + if tx == nil { + tx = r.db + } + var role entities.M_Role + if err := tx.WithContext(ctx).Where("id = ?", id).First(&role).Error; err != nil { + return entities.M_Role{}, err + } + return role, nil +} + +// GetRolesByUserID implements RoleRepository. +func (r *roleRepository) GetRolesByUserID(ctx context.Context, tx *gorm.DB, userId string) ([]entities.M_Role, error) { + if tx == nil { + tx = r.db + } + var roles []entities.M_Role + if err := tx.WithContext(ctx).Where("user_id = ?", userId).Find(&roles).Error; err != nil { + return nil, err + } + return roles, nil +} + +// RemovePermissionsFromRole implements RoleRepository. +func (r *roleRepository) RemovePermissionsFromRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error { + if tx == nil { + tx = r.db + } + if err := tx.WithContext(ctx).Model(&entities.M_Role{}).Where("id = ?", roleId).Update("permissions", gorm.Expr("array_remove(permissions, ?)", permissions)).Error; err != nil { + return err + } + return nil +} + +// RemoveRoleFromUser implements RoleRepository. +func (r *roleRepository) RemoveRoleFromUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error { + if tx == nil { + tx = r.db + } + userUUID, err := uuid.Parse(userId) + if err != nil { + return err + } + roleUUID, err := uuid.Parse(roleId) + if err != nil { + return err + } + + var count int64 + if err := tx.WithContext(ctx). + Model(&entities.M_User_Role{}). + Where("user_id = ? AND role_id = ?", userUUID, roleUUID). + Count(&count).Error; err != nil { + return err + } + if count > 0 { + return nil + } + userRole := entities.M_User_Role{ + UserID: userUUID, + RoleID: roleUUID, + } + // Delete ke tabel user_roles, bukan update ke M_User + if err := tx.WithContext(ctx).Delete(&userRole).Error; err != nil { + return err + } + return nil +} + +// UpdateRole implements RoleRepository. +func (r *roleRepository) UpdateRole(ctx context.Context, tx *gorm.DB, id string, role entities.M_Role) (entities.M_Role, error) { + if tx == nil { + tx = r.db + } + if err := tx.WithContext(ctx).Where("id = ?", id).Updates(&role).Error; err != nil { + return entities.M_Role{}, err + } + return role, nil +} + +func NewRoleRepository(db *gorm.DB) RoleRepository { + return &roleRepository{ + db: db, + } +} diff --git a/modules/role/routes.go b/modules/role/routes.go new file mode 100644 index 0000000..494ad8e --- /dev/null +++ b/modules/role/routes.go @@ -0,0 +1,39 @@ +package role + +import ( + "github.com/Caknoooo/go-gin-clean-starter/middlewares" + "github.com/Caknoooo/go-gin-clean-starter/modules/auth/service" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/controller" + "github.com/Caknoooo/go-gin-clean-starter/pkg/constants" + "github.com/gin-gonic/gin" + "github.com/samber/do" +) + +func RegisterRoutes(server *gin.Engine, injector *do.Injector) { + roleController := do.MustInvoke[controller.RoleController](injector) + jwtService := do.MustInvokeNamed[service.JWTService](injector, constants.JWTService) + + roleRoutes := server.Group("/api/v1/role") + { + roleRoutes.POST("", middlewares.Authenticate(jwtService), roleController.CreateRole) + roleRoutes.GET("", middlewares.Authenticate(jwtService), roleController.GetRoles) + roleRoutes.GET("/:id", middlewares.Authenticate(jwtService), roleController.GetRoleByID) + roleRoutes.PUT("/:id", middlewares.Authenticate(jwtService), roleController.UpdateRole) + roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.DeleteRole) + roleRoutes.POST("/:id/permissions", middlewares.Authenticate(jwtService), roleController.AssignPermissionsToRole) + roleRoutes.DELETE("/:id/permissions", middlewares.Authenticate(jwtService), roleController.RemovePermissionsFromRole) + roleRoutes.POST("/assign-role", middlewares.Authenticate(jwtService), roleController.AssignRoleToUser) + roleRoutes.POST("/remove-role", middlewares.Authenticate(jwtService), roleController.RemoveRoleFromUser) + roleRoutes.GET("/user/:id", middlewares.Authenticate(jwtService), roleController.GetRolesByUserID) + // roleRoutes.POST("", roleController.CreateRole) + // roleRoutes.GET("", roleController.GetRoles) + // roleRoutes.GET("/:id", roleController.GetRoleByID) + // roleRoutes.PUT("/:id", middlewares.Authenticate(jwtService), roleController.Update) + // roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.Delete) + + // userRoutes.PUT("/:id", middlewares.Authenticate(jwtService), userController.Update) + // roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.Delete) + // roleRoutes.POST("/send-verification-email", roleController.SendVerificationEmail) + // roleRoutes.POST("/refresh", middlewares.Authenticate(jwtService), roleController.Refresh) + } +} diff --git a/modules/role/service/role_service.go b/modules/role/service/role_service.go new file mode 100644 index 0000000..4e5c81b --- /dev/null +++ b/modules/role/service/role_service.go @@ -0,0 +1,131 @@ +package service + +import ( + "context" + + "github.com/Caknoooo/go-gin-clean-starter/database/entities" + authRepo "github.com/Caknoooo/go-gin-clean-starter/modules/auth/repository" + "github.com/Caknoooo/go-gin-clean-starter/modules/auth/service" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/dto" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/query" + "github.com/Caknoooo/go-gin-clean-starter/modules/role/repository" + "github.com/google/uuid" + "gorm.io/gorm" +) + +type RoleService interface { + CreateRole(ctx context.Context, role dto.RoleCreateRequest) (dto.RoleResponse, error) + GetRoles(ctx context.Context, filter query.RoleFilter) ([]dto.RoleResponse, error) + GetRoleByID(ctx context.Context, id string) (dto.RoleResponse, error) + UpdateRole(ctx context.Context, id string, role dto.RoleUpdateRequest) (dto.RoleResponse, error) + DeleteRole(ctx context.Context, id string) error + AssignPermissionsToRole(ctx context.Context, roleId string, permissions []string) error + RemovePermissionsFromRole(ctx context.Context, roleId string, permissions []string) error + AssignRoleToUser(ctx context.Context, userId string, roleId string) error + RemoveRoleFromUser(ctx context.Context, userId string, roleId string) error + GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error) +} + +type roleService struct { + roleRepo repository.RoleRepository + refreshTokenRepository authRepo.RefreshTokenRepository + jwtService service.JWTService + db *gorm.DB +} + +// AssignPermissionsToRole implements RoleService. +func (r *roleService) AssignPermissionsToRole(ctx context.Context, roleId string, permissions []string) error { + panic("unimplemented") +} + +// AssignRoleToUser implements RoleService. +func (r *roleService) AssignRoleToUser(ctx context.Context, userId string, roleId string) error { + panic("unimplemented") +} + +// CreateRole implements RoleService. +func (r *roleService) CreateRole(ctx context.Context, req dto.RoleCreateRequest) (dto.RoleResponse, error) { + _, exists, err := r.roleRepo.CheckRoleName(ctx, r.db, req.Name) + if err != nil && err != gorm.ErrRecordNotFound { + return dto.RoleResponse{}, err + } + if exists { + return dto.RoleResponse{}, dto.ErrRoleAlreadyExists + } + + clientUUID, err := uuid.Parse(req.ClientID) + if err != nil { + return dto.RoleResponse{}, err + } + role := entities.M_Role{ + Name: req.Name, + Description: req.Description, + IconUrl: req.IconUrl, + Type: req.Type, + HomeUrl: req.HomeUrl, + ClientID: clientUUID, + } + + createdRole, err := r.roleRepo.CreateRole(ctx, r.db, role) + if err != nil { + return dto.RoleResponse{}, err + } + return dto.RoleResponse{ + ID: createdRole.ID.String(), + Name: createdRole.Name, + Description: createdRole.Description, + IconUrl: createdRole.IconUrl, + Type: createdRole.Type, + HomeUrl: createdRole.HomeUrl, + ClientID: createdRole.ClientID.String(), + }, nil +} + +// DeleteRole implements RoleService. +func (r *roleService) DeleteRole(ctx context.Context, id string) error { + panic("unimplemented") +} + +// GetRoleByID implements RoleService. +func (r *roleService) GetRoleByID(ctx context.Context, id string) (dto.RoleResponse, error) { + panic("unimplemented") +} + +// GetRoles implements RoleService. +func (r *roleService) GetRoles(ctx context.Context, filter query.RoleFilter) ([]dto.RoleResponse, error) { + panic("unimplemented") +} + +// GetRolesByUserID implements RoleService. +func (r *roleService) GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error) { + panic("unimplemented") +} + +// RemovePermissionsFromRole implements RoleService. +func (r *roleService) RemovePermissionsFromRole(ctx context.Context, roleId string, permissions []string) error { + panic("unimplemented") +} + +// RemoveRoleFromUser implements RoleService. +func (r *roleService) RemoveRoleFromUser(ctx context.Context, userId string, roleId string) error { + panic("unimplemented") +} + +// UpdateRole implements RoleService. +func (r *roleService) UpdateRole(ctx context.Context, id string, role dto.RoleUpdateRequest) (dto.RoleResponse, error) { + panic("unimplemented") +} + +func NewRoleService( + roleRepo repository.RoleRepository, + refreshTokenRepo authRepo.RefreshTokenRepository, + jwtService service.JWTService, + db *gorm.DB, +) RoleService { + return &roleService{ + roleRepo: roleRepo, + refreshTokenRepository: refreshTokenRepo, + jwtService: jwtService, + db: db, + } +}