generated from PenaSide/GolangTemplate
238 lines
6.6 KiB
Go
238 lines
6.6 KiB
Go
package account
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
|
|
"go.uber.org/zap"
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
|
)
|
|
|
|
type accountRepository interface {
|
|
FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error)
|
|
FindMany(ctx context.Context, page, limit int64) ([]models.Account, errors.Error)
|
|
Insert(ctx context.Context, account *models.Account) (*models.Account, errors.Error)
|
|
Remove(ctx context.Context, id string) (*models.Account, errors.Error)
|
|
Delete(ctx context.Context, id string) (*models.Account, errors.Error)
|
|
CountAll(ctx context.Context) (int64, errors.Error)
|
|
SetStatus(ctx context.Context, userID string, status models.AccountStatus) (*models.Account, errors.Error)
|
|
UpdateName(ctx context.Context, userID string, name *models.Name) (*models.Account, errors.Error)
|
|
}
|
|
|
|
type authClient interface {
|
|
GetUser(ctx context.Context, userID string) (*models.User, errors.Error)
|
|
}
|
|
|
|
type Deps struct {
|
|
Logger *zap.Logger
|
|
Repository accountRepository
|
|
AuthClient authClient
|
|
}
|
|
|
|
type Service struct {
|
|
logger *zap.Logger
|
|
repository accountRepository
|
|
authClient authClient
|
|
}
|
|
|
|
func New(deps Deps) *Service {
|
|
if deps.Logger == nil {
|
|
log.Panicln("logger is nil on <New (account service)>")
|
|
}
|
|
|
|
if deps.Repository == nil {
|
|
log.Panicln("repository is nil on <New (account service)>")
|
|
}
|
|
|
|
if deps.AuthClient == nil {
|
|
log.Panicln("auth client is nil on <New (account service)>")
|
|
}
|
|
|
|
return &Service{
|
|
logger: deps.Logger,
|
|
repository: deps.Repository,
|
|
authClient: deps.AuthClient,
|
|
}
|
|
}
|
|
|
|
func (receiver *Service) GetAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
|
account, err := receiver.repository.FindByUserID(ctx, userID)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to get account by id on <GetAccountByUserID> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.String("userID", userID),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|
|
|
|
func (receiver *Service) GetAccountsList(ctx context.Context, pagination *models.Pagination) (*models.PaginationResponse[models.Account], errors.Error) {
|
|
if pagination == nil {
|
|
return nil, errors.New(
|
|
fmt.Errorf("pagination is nil on <GetAccountsList> of <AccountService>: %w", errors.ErrInternalError),
|
|
errors.ErrInternalError,
|
|
)
|
|
}
|
|
|
|
count, err := receiver.repository.CountAll(ctx)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to count accounts on <GetAccountsList> of <AccountService>",
|
|
zap.Error(err),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
if count == 0 {
|
|
return &models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}, nil
|
|
}
|
|
|
|
totalPages := int64(math.Ceil(float64(count) / float64(pagination.Limit)))
|
|
|
|
accounts, err := receiver.repository.FindMany(ctx, pagination.Page, pagination.Limit)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to get accounts list on <GetAccountsList> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.Int64("page", pagination.Page),
|
|
zap.Int64("limit", pagination.Limit),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return &models.PaginationResponse[models.Account]{
|
|
TotalPages: totalPages,
|
|
Records: accounts,
|
|
}, nil
|
|
}
|
|
|
|
func (receiver *Service) CreateAccount(ctx context.Context, account *models.Account) (*models.Account, errors.Error) {
|
|
findedAccount, err := receiver.GetAccountByUserID(ctx, account.UserID)
|
|
if err != nil && err.Type() != errors.ErrNotFound {
|
|
receiver.logger.Error("failed to find account on <CreateAccount> of <AccountService>",
|
|
zap.Error(err),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
if findedAccount != nil {
|
|
return nil, errors.New(
|
|
fmt.Errorf("failed to create account with <%s> on <CreateAccount> of <AccountService>: %w",
|
|
account.UserID,
|
|
errors.ErrConflict,
|
|
),
|
|
errors.ErrConflict,
|
|
)
|
|
}
|
|
|
|
createdAccount, err := receiver.repository.Insert(ctx, account)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to create account on <CreateAccount> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.Any("account", account),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return createdAccount, nil
|
|
}
|
|
|
|
func (receiver *Service) CreateAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
|
account, err := receiver.GetAccountByUserID(ctx, userID)
|
|
if err != nil && err.Type() != errors.ErrNotFound {
|
|
receiver.logger.Error("failed to find account on <CreateAccountByUserID> of <AccountService>",
|
|
zap.Error(err),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
if account != nil {
|
|
return nil, errors.New(
|
|
fmt.Errorf("failed to create account with <%s> on <CreateAccountByUserID> of <AccountService>: %w",
|
|
userID,
|
|
errors.ErrConflict,
|
|
),
|
|
errors.ErrConflict,
|
|
)
|
|
}
|
|
|
|
user, err := receiver.authClient.GetUser(ctx, userID)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to get user on <CreateAccountByUserID> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.String("userID", userID),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
createdAccount, err := receiver.repository.Insert(ctx, &models.Account{UserID: user.ID})
|
|
if err != nil {
|
|
receiver.logger.Error("failed to create account on <CreateAccountByUserID> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.String("userID", userID),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return createdAccount, nil
|
|
}
|
|
|
|
func (receiver *Service) RemoveAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
|
account, err := receiver.repository.Remove(ctx, userID)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to remove account on <RemoveAccount> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.String("userID", userID),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|
|
|
|
func (receiver *Service) DeleteAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
|
account, err := receiver.repository.Delete(ctx, userID)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to delete account on <DeleteAccount> of <AccountService>",
|
|
zap.Error(err),
|
|
zap.String("userID", userID),
|
|
)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|
|
|
|
func (receiver *Service) SetVerificationStatus(ctx context.Context, userID string, status models.AccountStatus) (*models.Account, errors.Error) {
|
|
account, err := receiver.repository.SetStatus(ctx, userID, status)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|
|
|
|
func (receiver *Service) UpdateAccountName(ctx context.Context, userID string, name *models.Name) (*models.Account, errors.Error) {
|
|
account, err := receiver.repository.UpdateName(ctx, userID, name)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to update account name on <UpdateAccountName> of <AccountService>", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|