template-monorepo/internal/model/member/usecase/verify_rate_usecase.go

56 lines
1.6 KiB
Go
Raw Normal View History

package usecase
import (
"context"
"time"
member "gateway/internal/model/member/domain"
domrepo "gateway/internal/model/member/domain/repository"
domusecase "gateway/internal/model/member/domain/usecase"
)
type verifyRateUseCase struct {
store domrepo.VerifyRateStore
}
// VerifyRateUseCaseParam wires VerifyRateUseCase.
type VerifyRateUseCaseParam struct {
Store domrepo.VerifyRateStore
}
// MustVerifyRateUseCase constructs VerifyRateUseCase.
func MustVerifyRateUseCase(param VerifyRateUseCaseParam) domusecase.VerifyRateUseCase {
if param.Store == nil {
panic("member: verify rate store is required")
}
return &verifyRateUseCase{store: param.Store}
}
func (uc *verifyRateUseCase) AssertResendAllowed(ctx context.Context, key string, cooldown time.Duration) error {
if key == "" {
return errb.InputMissingRequired("rate limit key is required")
}
ok, err := uc.store.TryResendLock(ctx, key, cooldown)
if err != nil {
return errb.DBError("rate limit check failed").WithCause(err)
}
if !ok {
return errb.SysTooManyRequest("resend cooldown active").WithCause(member.ErrResendCooldown)
}
return nil
}
func (uc *verifyRateUseCase) AssertDailyAllowed(ctx context.Context, key string, window time.Duration, limit int) error {
if key == "" {
return errb.InputMissingRequired("daily limit key is required")
}
count, err := uc.store.IncrDaily(ctx, key, window)
if err != nil {
return errb.DBError("daily limit check failed").WithCause(err)
}
if count > int64(limit) {
return errb.ResInsufficientQuota("daily verification limit exceeded").WithCause(member.ErrDailyLimit)
}
return nil
}