69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"git.techease.ru/Smart-search/smart-search-back/internal/model"
|
|
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
|
"git.techease.ru/Smart-search/smart-search-back/pkg/errors"
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
type inviteService struct {
|
|
inviteRepo repository.InviteRepository
|
|
userRepo repository.UserRepository
|
|
txManager *repository.TxManager
|
|
}
|
|
|
|
func NewInviteService(inviteRepo repository.InviteRepository, userRepo repository.UserRepository, txManager *repository.TxManager) InviteService {
|
|
return &inviteService{
|
|
inviteRepo: inviteRepo,
|
|
userRepo: userRepo,
|
|
txManager: txManager,
|
|
}
|
|
}
|
|
|
|
func (s *inviteService) Generate(ctx context.Context, userID, maxUses, ttlDays int) (*model.InviteCode, error) {
|
|
code := rand.Int63n(90000000) + 10000000
|
|
|
|
invite := &model.InviteCode{
|
|
UserID: userID,
|
|
Code: code,
|
|
CanBeUsedCount: maxUses,
|
|
ExpiresAt: time.Now().Add(time.Duration(ttlDays) * 24 * time.Hour),
|
|
}
|
|
|
|
err := s.txManager.WithTx(ctx, func(tx pgx.Tx) error {
|
|
canIssue, err := s.userRepo.CheckInviteLimitTx(ctx, tx, userID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !canIssue {
|
|
return errors.NewBusinessError(errors.InviteLimitReached, "User reached maximum invite codes limit")
|
|
}
|
|
|
|
if err := s.inviteRepo.CreateTx(ctx, tx, invite); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := s.userRepo.IncrementInvitesIssuedTx(ctx, tx, userID); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return invite, nil
|
|
}
|
|
|
|
func (s *inviteService) GetInfo(ctx context.Context, userID int) (*model.InviteCode, error) {
|
|
return s.inviteRepo.FindActiveByUserID(ctx, userID)
|
|
}
|