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, } }