package usecase import ( "context" "gateway/internal/model/permission/domain/entity" "gateway/internal/model/permission/domain/enum" domrepo "gateway/internal/model/permission/domain/repository" dom "gateway/internal/model/permission/domain/usecase" ) // AuthorizationQueryUseCaseParam injects all read-side repos. type AuthorizationQueryUseCaseParam struct { Roles domrepo.RoleRepository Permissions domrepo.PermissionRepository RolePermissions domrepo.RolePermissionRepository UserRoles domrepo.UserRoleRepository } type authorizationQueryUseCase struct { roles domrepo.RoleRepository perms domrepo.PermissionRepository rolePerms domrepo.RolePermissionRepository userRoles domrepo.UserRoleRepository } // NewAuthorizationQueryUseCase composes Role + RolePermission + // Permission to produce the menu/permission map used by GET /me. func NewAuthorizationQueryUseCase(param AuthorizationQueryUseCaseParam) dom.AuthorizationQueryUseCase { return &authorizationQueryUseCase{ roles: param.Roles, perms: param.Permissions, rolePerms: param.RolePermissions, userRoles: param.UserRoles, } } func (uc *authorizationQueryUseCase) Me( ctx context.Context, tenantID, uid string, includeTree bool, ) (*dom.MePermissionsResponse, error) { resp := &dom.MePermissionsResponse{ UID: uid, TenantID: tenantID, Roles: []string{}, Permissions: enum.Permissions{}, } urs, err := uc.userRoles.ListByUser(ctx, tenantID, uid) if err != nil { return nil, wrapRepoErr(err) } if len(urs) == 0 { if includeTree { resp.Tree = []*dom.PermissionTreeNode{} } return resp, nil } roleIDs := make([]string, 0, len(urs)) for _, ur := range urs { roleIDs = append(roleIDs, ur.RoleID) } roles, err := uc.roles.ListByTenantAndIDs(ctx, tenantID, roleIDs) if err != nil { return nil, wrapRepoErr(err) } roleByID := make(map[string]*entity.Role, len(roles)) for _, role := range roles { roleByID[role.ID.Hex()] = role if role.Status == enum.StatusOpen { resp.Roles = append(resp.Roles, role.Key) } } rps, err := uc.rolePerms.ListByRoles(ctx, tenantID, roleIDs) if err != nil { return nil, wrapRepoErr(err) } if len(rps) == 0 { if includeTree { resp.Tree = []*dom.PermissionTreeNode{} } return resp, nil } permIDSet := make(map[string]struct{}, len(rps)) for _, rp := range rps { role, ok := roleByID[rp.RoleID] if !ok || role.Status != enum.StatusOpen { continue } permIDSet[rp.PermissionID] = struct{}{} } if len(permIDSet) == 0 { if includeTree { resp.Tree = []*dom.PermissionTreeNode{} } return resp, nil } ids := make([]string, 0, len(permIDSet)) for id := range permIDSet { ids = append(ids, id) } perms, err := uc.perms.GetByIDs(ctx, ids) if err != nil { return nil, wrapRepoErr(err) } for _, perm := range perms { resp.Permissions[perm.Name] = perm.Status } if includeTree { resp.Tree = filterOpenNodes(buildPermissionTree(perms)) } return resp, nil } var _ dom.AuthorizationQueryUseCase = (*authorizationQueryUseCase)(nil)