Check verifies if the user can create another instance of the given entity.
( ctx context.Context, userID entities.UserID, entityName string, countFunc func() (int, error), )
| 58 | |
| 59 | // Check verifies if the user can create another instance of the given entity. |
| 60 | func (service *EntitlementService) Check( |
| 61 | ctx context.Context, |
| 62 | userID entities.UserID, |
| 63 | entityName string, |
| 64 | countFunc func() (int, error), |
| 65 | ) (*EntitlementCheckResult, error) { |
| 66 | ctx, span := service.tracer.Start(ctx) |
| 67 | defer span.End() |
| 68 | |
| 69 | if !service.enabled { |
| 70 | return &EntitlementCheckResult{Allowed: true}, nil |
| 71 | } |
| 72 | |
| 73 | limits, exists := entityLimits[entityName] |
| 74 | if !exists { |
| 75 | return &EntitlementCheckResult{Allowed: true}, nil |
| 76 | } |
| 77 | |
| 78 | user, err := service.userRepository.Load(ctx, userID) |
| 79 | if err != nil { |
| 80 | return nil, service.tracer.WrapErrorSpan( |
| 81 | span, |
| 82 | stacktrace.Propagate(err, fmt.Sprintf("cannot load user [%s] for entitlement check", userID)), |
| 83 | ) |
| 84 | } |
| 85 | |
| 86 | limit, hasLimit := limits[user.SubscriptionName] |
| 87 | if !hasLimit || limit == 0 { |
| 88 | return &EntitlementCheckResult{Allowed: true}, nil |
| 89 | } |
| 90 | |
| 91 | currentCount, err := countFunc() |
| 92 | if err != nil { |
| 93 | return nil, service.tracer.WrapErrorSpan( |
| 94 | span, |
| 95 | stacktrace.Propagate(err, fmt.Sprintf("cannot count entities [%s] for user [%s]", entityName, userID)), |
| 96 | ) |
| 97 | } |
| 98 | |
| 99 | if currentCount >= limit { |
| 100 | return &EntitlementCheckResult{ |
| 101 | Allowed: false, |
| 102 | Message: fmt.Sprintf( |
| 103 | "Upgrade to a paid plan to create more than [%d] %s. Visit https://httpsms.com/pricing for details.", |
| 104 | limit, |
| 105 | formatEntityName(entityName, true), |
| 106 | ), |
| 107 | }, nil |
| 108 | } |
| 109 | |
| 110 | return &EntitlementCheckResult{Allowed: true}, nil |
| 111 | } |
| 112 | |
| 113 | // formatEntityName converts a PascalCase entity name to lowercase words and optionally pluralizes it. |
| 114 | // Consecutive uppercase letters (acronyms like API) are kept together as a single word. |
no test coverage detected