feat(shop-role): 实现店铺角色继承功能和权限检查优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m39s

- 新增店铺角色管理 API 和数据模型
- 实现角色继承和权限检查逻辑
- 添加流程测试框架和集成测试
- 更新权限服务和账号管理逻辑
- 添加数据库迁移脚本
- 归档 OpenSpec 变更文档

Ultraworked with Sisyphus
This commit is contained in:
2026-02-03 10:06:13 +08:00
parent bc7e5d6f6d
commit 5a90caa619
61 changed files with 21284 additions and 131 deletions

View File

@@ -0,0 +1,37 @@
package account
import (
"context"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
func (s *Service) GetRoleIDsForAccount(ctx context.Context, accountID uint) ([]uint, error) {
account, err := s.accountStore.GetByID(ctx, accountID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询账号失败")
}
if account.UserType == constants.UserTypeSuperAdmin {
return []uint{}, nil
}
accountRoles, err := s.accountRoleStore.GetRoleIDsByAccountID(ctx, accountID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询账号角色失败")
}
if len(accountRoles) > 0 {
return accountRoles, nil
}
if account.UserType == constants.UserTypeAgent && account.ShopID != nil {
shopRoles, err := s.shopRoleStore.GetRoleIDsByShopID(ctx, *account.ShopID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺角色失败")
}
return shopRoles, nil
}
return []uint{}, nil
}

View File

@@ -0,0 +1,211 @@
package account
import (
"context"
"testing"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/tests/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetRoleIDsForAccount(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
accountStore := postgres.NewAccountStore(tx, rdb)
roleStore := postgres.NewRoleStore(tx)
accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
shopRoleStore := postgres.NewShopRoleStore(tx, rdb)
service := New(
accountStore,
roleStore,
accountRoleStore,
shopRoleStore,
nil,
nil,
nil,
)
ctx := context.Background()
t.Run("超级管理员返回空数组", func(t *testing.T) {
account := &model.Account{
Username: "admin_roletest",
Phone: "13800010001",
Password: "hashed",
UserType: constants.UserTypeSuperAdmin,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Empty(t, roleIDs)
})
t.Run("平台用户返回账号级角色", func(t *testing.T) {
account := &model.Account{
Username: "platform_roletest",
Phone: "13800010002",
Password: "hashed",
UserType: constants.UserTypePlatform,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
role := &model.Role{
RoleName: "平台管理员",
RoleType: constants.RoleTypePlatform,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, role))
accountRole := &model.AccountRole{
AccountID: account.ID,
RoleID: role.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
require.NoError(t, accountRoleStore.Create(ctx, accountRole))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Equal(t, []uint{role.ID}, roleIDs)
})
t.Run("代理账号有账号级角色,不继承店铺角色", func(t *testing.T) {
shopID := uint(1)
account := &model.Account{
Username: "agent_with_roletest",
Phone: "13800010003",
Password: "hashed",
UserType: constants.UserTypeAgent,
ShopID: &shopID,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
accountRole := &model.Role{
RoleName: "账号角色",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, accountRole))
shopRole := &model.Role{
RoleName: "店铺角色",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, shopRole))
require.NoError(t, accountRoleStore.Create(ctx, &model.AccountRole{
AccountID: account.ID,
RoleID: accountRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
require.NoError(t, shopRoleStore.Create(ctx, &model.ShopRole{
ShopID: shopID,
RoleID: shopRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Equal(t, []uint{accountRole.ID}, roleIDs)
})
t.Run("代理账号无账号级角色,继承店铺角色", func(t *testing.T) {
shopID := uint(2)
account := &model.Account{
Username: "agent_inheritest",
Phone: "13800010004",
Password: "hashed",
UserType: constants.UserTypeAgent,
ShopID: &shopID,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
shopRole := &model.Role{
RoleName: "店铺默认角色",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, shopRole))
require.NoError(t, shopRoleStore.Create(ctx, &model.ShopRole{
ShopID: shopID,
RoleID: shopRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Equal(t, []uint{shopRole.ID}, roleIDs)
})
t.Run("代理账号无角色且店铺无角色,返回空数组", func(t *testing.T) {
shopID := uint(3)
account := &model.Account{
Username: "agent_notest",
Phone: "13800010005",
Password: "hashed",
UserType: constants.UserTypeAgent,
ShopID: &shopID,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Empty(t, roleIDs)
})
t.Run("企业账号返回账号级角色", func(t *testing.T) {
enterpriseID := uint(1)
account := &model.Account{
Username: "enterprise_roletest",
Phone: "13800010006",
Password: "hashed",
UserType: constants.UserTypeEnterprise,
EnterpriseID: &enterpriseID,
Status: constants.StatusEnabled,
}
require.NoError(t, accountStore.Create(ctx, account))
role := &model.Role{
RoleName: "企业管理员",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, role))
accountRole := &model.AccountRole{
AccountID: account.ID,
RoleID: role.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
require.NoError(t, accountRoleStore.Create(ctx, accountRole))
roleIDs, err := service.GetRoleIDsForAccount(ctx, account.ID)
require.NoError(t, err)
assert.Equal(t, []uint{role.ID}, roleIDs)
})
}

View File

@@ -22,6 +22,7 @@ type Service struct {
accountStore *postgres.AccountStore
roleStore *postgres.RoleStore
accountRoleStore *postgres.AccountRoleStore
shopRoleStore *postgres.ShopRoleStore
shopStore middleware.ShopStoreInterface
enterpriseStore middleware.EnterpriseStoreInterface
auditService AuditServiceInterface
@@ -36,6 +37,7 @@ func New(
accountStore *postgres.AccountStore,
roleStore *postgres.RoleStore,
accountRoleStore *postgres.AccountRoleStore,
shopRoleStore *postgres.ShopRoleStore,
shopStore middleware.ShopStoreInterface,
enterpriseStore middleware.EnterpriseStoreInterface,
auditService AuditServiceInterface,
@@ -44,6 +46,7 @@ func New(
accountStore: accountStore,
roleStore: roleStore,
accountRoleStore: accountRoleStore,
shopRoleStore: shopRoleStore,
shopStore: shopStore,
enterpriseStore: enterpriseStore,
auditService: auditService,

View File

@@ -69,7 +69,7 @@ func TestAccountService_Create_SuperAdminSuccess(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -111,7 +111,7 @@ func TestAccountService_Create_PlatformUserCreatePlatformAccount(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -150,7 +150,7 @@ func TestAccountService_Create_PlatformUserCreateAgentAccount(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -192,7 +192,7 @@ func TestAccountService_Create_AgentCreateSubordinateShopAccount(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
agentShopID := uint(10)
subordinateShopID := uint(11)
@@ -238,7 +238,7 @@ func TestAccountService_Create_AgentCreateOtherShopAccountForbidden(t *testing.T
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
agentShopID := uint(10)
otherShopID := uint(99)
@@ -281,7 +281,7 @@ func TestAccountService_Create_AgentCreatePlatformAccountForbidden(t *testing.T)
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -318,7 +318,7 @@ func TestAccountService_Create_EnterpriseUserForbidden(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -355,7 +355,7 @@ func TestAccountService_Create_UsernameDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -404,7 +404,7 @@ func TestAccountService_Create_PhoneDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -453,7 +453,7 @@ func TestAccountService_Create_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -488,7 +488,7 @@ func TestAccountService_Update_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -534,7 +534,7 @@ func TestAccountService_Update_NotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -565,7 +565,7 @@ func TestAccountService_Update_AgentUnauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -619,7 +619,7 @@ func TestAccountService_Update_UsernameDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -676,7 +676,7 @@ func TestAccountService_Update_PhoneDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -735,7 +735,7 @@ func TestAccountService_Delete_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -778,7 +778,7 @@ func TestAccountService_Delete_NotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -804,7 +804,7 @@ func TestAccountService_Delete_AgentUnauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -855,7 +855,7 @@ func TestAccountService_AssignRoles_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -906,7 +906,7 @@ func TestAccountService_AssignRoles_SuperAdminForbidden(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -947,7 +947,7 @@ func TestAccountService_AssignRoles_RoleTypeMismatch(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -997,7 +997,7 @@ func TestAccountService_AssignRoles_EmptyArrayClearsRoles(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1049,7 +1049,7 @@ func TestAccountService_RemoveRole_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1104,7 +1104,7 @@ func TestAccountService_RemoveRole_AccountNotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1132,7 +1132,7 @@ func TestAccountService_GetRoles_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1183,7 +1183,7 @@ func TestAccountService_GetRoles_EmptyArray(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1224,7 +1224,7 @@ func TestAccountService_List_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1269,7 +1269,7 @@ func TestAccountService_List_FilterByUsername(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1318,7 +1318,7 @@ func TestAccountService_ValidatePassword_Correct(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1357,7 +1357,7 @@ func TestAccountService_ValidatePassword_Incorrect(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1398,7 +1398,7 @@ func TestAccountService_UpdatePassword_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1449,7 +1449,7 @@ func TestAccountService_UpdateStatus_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1494,7 +1494,7 @@ func TestAccountService_Get_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1534,7 +1534,7 @@ func TestAccountService_Get_NotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1560,7 +1560,7 @@ func TestAccountService_UpdatePassword_AccountNotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1586,7 +1586,7 @@ func TestAccountService_UpdateStatus_AccountNotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1612,7 +1612,7 @@ func TestAccountService_UpdatePassword_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1635,7 +1635,7 @@ func TestAccountService_UpdateStatus_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1658,7 +1658,7 @@ func TestAccountService_Delete_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1681,7 +1681,7 @@ func TestAccountService_AssignRoles_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1704,7 +1704,7 @@ func TestAccountService_RemoveRole_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1727,7 +1727,7 @@ func TestAccountService_Update_Unauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -1755,7 +1755,7 @@ func TestAccountService_AssignRoles_NotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1781,7 +1781,7 @@ func TestAccountService_GetRoles_NotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1807,7 +1807,7 @@ func TestAccountService_List_FilterByUserType(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1854,7 +1854,7 @@ func TestAccountService_List_FilterByStatus(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1901,7 +1901,7 @@ func TestAccountService_List_FilterByPhone(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1947,7 +1947,7 @@ func TestAccountService_Update_UpdatePassword(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -1993,7 +1993,7 @@ func TestAccountService_Update_UpdateStatus(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2037,7 +2037,7 @@ func TestAccountService_Update_UpdatePhone(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2081,7 +2081,7 @@ func TestAccountService_AssignRoles_AgentUnauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2130,7 +2130,7 @@ func TestAccountService_Create_EnterpriseAccountSuccess(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2173,7 +2173,7 @@ func TestAccountService_Create_AgentMissingShopID(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2209,7 +2209,7 @@ func TestAccountService_Create_EnterpriseMissingEnterpriseID(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2245,7 +2245,7 @@ func TestAccountService_RemoveRole_AgentUnauthorized(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2294,7 +2294,7 @@ func TestAccountService_AssignRoles_MultipleRoles(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2353,7 +2353,7 @@ func TestAccountService_Update_AllFields(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2409,7 +2409,7 @@ func TestAccountService_ListPlatformAccounts_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2454,7 +2454,7 @@ func TestAccountService_CreateSystemAccount_Success(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2486,7 +2486,7 @@ func TestAccountService_CreateSystemAccount_MissingUsername(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2517,7 +2517,7 @@ func TestAccountService_CreateSystemAccount_MissingPhone(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2548,7 +2548,7 @@ func TestAccountService_CreateSystemAccount_MissingPassword(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2579,7 +2579,7 @@ func TestAccountService_CreateSystemAccount_UsernameDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2625,7 +2625,7 @@ func TestAccountService_CreateSystemAccount_PhoneDuplicate(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := context.Background()
@@ -2671,7 +2671,7 @@ func TestAccountService_ListPlatformAccounts_FilterByUsername(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2717,7 +2717,7 @@ func TestAccountService_ListPlatformAccounts_FilterByPhone(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2763,7 +2763,7 @@ func TestAccountService_ListPlatformAccounts_FilterByStatus(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2810,7 +2810,7 @@ func TestAccountService_Create_PlatformUserCreateEnterpriseAccount(t *testing.T)
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2852,7 +2852,7 @@ func TestAccountService_List_DefaultPagination(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2882,7 +2882,7 @@ func TestAccountService_ListPlatformAccounts_DefaultPagination(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2912,7 +2912,7 @@ func TestAccountService_AssignRoles_RoleNotFound(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2953,7 +2953,7 @@ func TestAccountService_Update_SameUsername(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -2996,7 +2996,7 @@ func TestAccountService_Update_SamePhone(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3039,7 +3039,7 @@ func TestAccountService_AssignRoles_DuplicateRoles(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3086,7 +3086,7 @@ func TestAccountService_Create_PlatformUserCreateAgentWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3129,7 +3129,7 @@ func TestAccountService_AssignRoles_CustomerAccountType(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3179,7 +3179,7 @@ func TestAccountService_Delete_AgentAccountWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3231,7 +3231,7 @@ func TestAccountService_Update_AgentAccountWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3286,7 +3286,7 @@ func TestAccountService_AssignRoles_AgentAccountWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3344,7 +3344,7 @@ func TestAccountService_RemoveRole_AgentAccountWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3408,7 +3408,7 @@ func TestAccountService_Create_EnterpriseAccountWithShop(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3454,7 +3454,7 @@ func TestAccountService_Delete_PlatformAccountByAgent(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3501,7 +3501,7 @@ func TestAccountService_Update_PlatformAccountByAgent(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3553,7 +3553,7 @@ func TestAccountService_AssignRoles_PlatformAccountByAgent(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
@@ -3600,7 +3600,7 @@ func TestAccountService_RemoveRole_PlatformAccountByAgent(t *testing.T) {
mockShop := new(MockShopStore)
mockEnterprise := new(MockEnterpriseStore)
svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)
svc := New(accountStore, roleStore, accountRoleStore, nil, mockShop, mockEnterprise, mockAudit)
superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,

View File

@@ -22,11 +22,16 @@ import (
// permCodeRegex 权限编码格式验证正则module:action
var permCodeRegex = regexp.MustCompile(`^[a-z][a-z0-9_]*:[a-z][a-z0-9_]*$`)
type AccountServiceInterface interface {
GetRoleIDsForAccount(ctx context.Context, accountID uint) ([]uint, error)
}
// Service 权限业务服务
type Service struct {
permissionStore *postgres.PermissionStore
accountRoleStore *postgres.AccountRoleStore
rolePermStore *postgres.RolePermissionStore
accountService AccountServiceInterface
redisClient *redis.Client
}
@@ -35,12 +40,14 @@ func New(
permissionStore *postgres.PermissionStore,
accountRoleStore *postgres.AccountRoleStore,
rolePermStore *postgres.RolePermissionStore,
accountService AccountServiceInterface,
redisClient *redis.Client,
) *Service {
return &Service{
permissionStore: permissionStore,
accountRoleStore: accountRoleStore,
rolePermStore: rolePermStore,
accountService: accountService,
redisClient: redisClient,
}
}
@@ -298,7 +305,7 @@ func (s *Service) CheckPermission(ctx context.Context, userID uint, permCode str
}
}
roleIDs, err := s.accountRoleStore.GetRoleIDsByAccountID(ctx, userID)
roleIDs, err := s.accountService.GetRoleIDsForAccount(ctx, userID)
if err != nil {
return false, errors.Wrap(errors.CodeInternalError, err, "查询用户角色失败")
}

View File

@@ -15,14 +15,23 @@ import (
)
type Service struct {
shopStore *postgres.ShopStore
accountStore *postgres.AccountStore
shopStore *postgres.ShopStore
accountStore *postgres.AccountStore
shopRoleStore *postgres.ShopRoleStore
roleStore *postgres.RoleStore
}
func New(shopStore *postgres.ShopStore, accountStore *postgres.AccountStore) *Service {
func New(
shopStore *postgres.ShopStore,
accountStore *postgres.AccountStore,
shopRoleStore *postgres.ShopRoleStore,
roleStore *postgres.RoleStore,
) *Service {
return &Service{
shopStore: shopStore,
accountStore: accountStore,
shopStore: shopStore,
accountStore: accountStore,
shopRoleStore: shopRoleStore,
roleStore: roleStore,
}
}

View File

@@ -0,0 +1,145 @@
package shop
import (
"context"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
)
func (s *Service) AssignRolesToShop(ctx context.Context, shopID uint, roleIDs []uint) ([]*model.ShopRole, error) {
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
return nil, err
}
shop, err := s.shopStore.GetByID(ctx, shopID)
if err != nil {
return nil, errors.New(errors.CodeNotFound, "店铺不存在")
}
currentUserID := middleware.GetUserIDFromContext(ctx)
if len(roleIDs) == 0 {
if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "清空店铺角色失败")
}
return []*model.ShopRole{}, nil
}
roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色失败")
}
if len(roles) != len(roleIDs) {
return nil, errors.New(errors.CodeNotFound, "部分角色不存在")
}
for _, role := range roles {
if role.RoleType != constants.RoleTypeCustomer {
return nil, errors.New(errors.CodeInvalidParam, "店铺只能分配客户角色")
}
if role.Status != constants.StatusEnabled {
return nil, errors.New(errors.CodeInvalidParam, "角色已禁用")
}
}
if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "删除现有店铺角色失败")
}
shopRoles := make([]*model.ShopRole, 0, len(roleIDs))
for _, roleID := range roleIDs {
shopRole := &model.ShopRole{
ShopID: shop.ID,
RoleID: roleID,
Status: constants.StatusEnabled,
Creator: currentUserID,
Updater: currentUserID,
}
shopRoles = append(shopRoles, shopRole)
}
if err := s.shopRoleStore.BatchCreate(ctx, shopRoles); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "批量创建店铺角色失败")
}
return shopRoles, nil
}
func (s *Service) GetShopRoles(ctx context.Context, shopID uint) (*dto.ShopRolesResponse, error) {
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
return nil, err
}
_, err := s.shopStore.GetByID(ctx, shopID)
if err != nil {
return nil, errors.New(errors.CodeNotFound, "店铺不存在")
}
shopRoles, err := s.shopRoleStore.GetByShopID(ctx, shopID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺角色失败")
}
if len(shopRoles) == 0 {
return &dto.ShopRolesResponse{
ShopID: shopID,
Roles: []*dto.ShopRoleResponse{},
}, nil
}
roleIDs := make([]uint, 0, len(shopRoles))
for _, sr := range shopRoles {
roleIDs = append(roleIDs, sr.RoleID)
}
roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色详情失败")
}
roleMap := make(map[uint]*model.Role)
for _, role := range roles {
roleMap[role.ID] = role
}
responses := make([]*dto.ShopRoleResponse, 0, len(shopRoles))
for _, sr := range shopRoles {
role, exists := roleMap[sr.RoleID]
if !exists {
continue
}
responses = append(responses, &dto.ShopRoleResponse{
ShopID: sr.ShopID,
RoleID: sr.RoleID,
RoleName: role.RoleName,
RoleDesc: role.RoleDesc,
Status: sr.Status,
})
}
return &dto.ShopRolesResponse{
ShopID: shopID,
Roles: responses,
}, nil
}
func (s *Service) DeleteShopRole(ctx context.Context, shopID, roleID uint) error {
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
return err
}
_, err := s.shopStore.GetByID(ctx, shopID)
if err != nil {
return errors.New(errors.CodeNotFound, "店铺不存在")
}
if err := s.shopRoleStore.Delete(ctx, shopID, roleID); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "删除店铺角色失败")
}
return nil
}

View File

@@ -0,0 +1,243 @@
package shop
import (
"context"
"testing"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
"github.com/break/junhong_cmp_fiber/tests/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAssignRolesToShop(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
shopStore := postgres.NewShopStore(tx, rdb)
accountStore := postgres.NewAccountStore(tx, rdb)
shopRoleStore := postgres.NewShopRoleStore(tx, rdb)
roleStore := postgres.NewRoleStore(tx)
service := New(shopStore, accountStore, shopRoleStore, roleStore)
shop := &model.Shop{
ShopName: "测试店铺",
ShopCode: "TEST_SHOP_001",
Level: 1,
Status: constants.StatusEnabled,
}
require.NoError(t, tx.Create(shop).Error)
role := &model.Role{
RoleName: "代理店长",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(context.Background(), role))
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
UserType: constants.UserTypeSuperAdmin,
})
t.Run("成功分配单个角色", func(t *testing.T) {
result, err := service.AssignRolesToShop(ctx, shop.ID, []uint{role.ID})
require.NoError(t, err)
assert.Len(t, result, 1)
assert.Equal(t, shop.ID, result[0].ShopID)
assert.Equal(t, role.ID, result[0].RoleID)
})
t.Run("清空所有角色", func(t *testing.T) {
result, err := service.AssignRolesToShop(ctx, shop.ID, []uint{})
require.NoError(t, err)
assert.Empty(t, result)
roles, err := service.GetShopRoles(ctx, shop.ID)
require.NoError(t, err)
assert.Empty(t, roles.Roles)
})
t.Run("替换现有角色", func(t *testing.T) {
require.NoError(t, shopRoleStore.Create(ctx, &model.ShopRole{
ShopID: shop.ID,
RoleID: role.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
newRole := &model.Role{
RoleName: "代理经理",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, newRole))
result, err := service.AssignRolesToShop(ctx, shop.ID, []uint{newRole.ID})
require.NoError(t, err)
assert.Len(t, result, 1)
assert.Equal(t, newRole.ID, result[0].RoleID)
})
t.Run("角色类型校验失败", func(t *testing.T) {
platformRole := &model.Role{
RoleName: "平台角色",
RoleType: constants.RoleTypePlatform,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(ctx, platformRole))
_, err := service.AssignRolesToShop(ctx, shop.ID, []uint{platformRole.ID})
require.Error(t, err)
assert.Contains(t, err.Error(), "店铺只能分配客户角色")
})
t.Run("角色不存在", func(t *testing.T) {
_, err := service.AssignRolesToShop(ctx, shop.ID, []uint{99999})
require.Error(t, err)
assert.Contains(t, err.Error(), "部分角色不存在")
})
t.Run("店铺不存在", func(t *testing.T) {
_, err := service.AssignRolesToShop(ctx, 99999, []uint{role.ID})
require.Error(t, err)
assert.Contains(t, err.Error(), "店铺不存在")
})
}
func TestGetShopRoles(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
shopStore := postgres.NewShopStore(tx, rdb)
accountStore := postgres.NewAccountStore(tx, rdb)
shopRoleStore := postgres.NewShopRoleStore(tx, rdb)
roleStore := postgres.NewRoleStore(tx)
service := New(shopStore, accountStore, shopRoleStore, roleStore)
shop := &model.Shop{
ShopName: "测试店铺2",
ShopCode: "TEST_SHOP_002",
Level: 1,
Status: constants.StatusEnabled,
}
require.NoError(t, tx.Create(shop).Error)
role := &model.Role{
RoleName: "代理店长",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(context.Background(), role))
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
UserType: constants.UserTypeSuperAdmin,
})
t.Run("查询已分配角色", func(t *testing.T) {
require.NoError(t, shopRoleStore.Create(ctx, &model.ShopRole{
ShopID: shop.ID,
RoleID: role.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
result, err := service.GetShopRoles(ctx, shop.ID)
require.NoError(t, err)
assert.Len(t, result.Roles, 1)
assert.Equal(t, shop.ID, result.ShopID)
assert.Equal(t, role.ID, result.Roles[0].RoleID)
assert.Equal(t, "代理店长", result.Roles[0].RoleName)
})
t.Run("查询未分配角色的店铺", func(t *testing.T) {
emptyShop := &model.Shop{
ShopName: "空店铺",
ShopCode: "EMPTY_SHOP",
Level: 1,
Status: constants.StatusEnabled,
}
require.NoError(t, tx.Create(emptyShop).Error)
result, err := service.GetShopRoles(ctx, emptyShop.ID)
require.NoError(t, err)
assert.Empty(t, result.Roles)
})
t.Run("店铺不存在", func(t *testing.T) {
_, err := service.GetShopRoles(ctx, 99999)
require.Error(t, err)
assert.Contains(t, err.Error(), "店铺不存在")
})
}
func TestDeleteShopRole(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
shopStore := postgres.NewShopStore(tx, rdb)
accountStore := postgres.NewAccountStore(tx, rdb)
shopRoleStore := postgres.NewShopRoleStore(tx, rdb)
roleStore := postgres.NewRoleStore(tx)
service := New(shopStore, accountStore, shopRoleStore, roleStore)
shop := &model.Shop{
ShopName: "测试店铺3",
ShopCode: "TEST_SHOP_003",
Level: 1,
Status: constants.StatusEnabled,
}
require.NoError(t, tx.Create(shop).Error)
role := &model.Role{
RoleName: "代理店长",
RoleType: constants.RoleTypeCustomer,
Status: constants.StatusEnabled,
}
require.NoError(t, roleStore.Create(context.Background(), role))
ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
UserID: 1,
UserType: constants.UserTypeSuperAdmin,
})
t.Run("成功删除角色", func(t *testing.T) {
require.NoError(t, shopRoleStore.Create(ctx, &model.ShopRole{
ShopID: shop.ID,
RoleID: role.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}))
err := service.DeleteShopRole(ctx, shop.ID, role.ID)
require.NoError(t, err)
result, err := service.GetShopRoles(ctx, shop.ID)
require.NoError(t, err)
assert.Empty(t, result.Roles)
})
t.Run("删除不存在的角色关联(幂等)", func(t *testing.T) {
err := service.DeleteShopRole(ctx, shop.ID, role.ID)
require.NoError(t, err)
})
t.Run("店铺不存在", func(t *testing.T) {
err := service.DeleteShopRole(ctx, 99999, role.ID)
require.Error(t, err)
assert.Contains(t, err.Error(), "店铺不存在")
})
}