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, code int64) (*model.InviteCode, error) { return s.inviteRepo.FindByCode(ctx, code) }