В Додо это первый случай, когда мы продаём часть системы как услугу для франчайзи. Стоимость Додо ИС входит в роялти. Но тут как бы мы продаём допфункции в приложении, которые не часть кор-функционала. Так что можно накрутить подписку.
Ну и в моей карьере это тоже первый раз, когда мне нужно реализовать чёт такое.
Посему встала задача написать какой-то удобный код, который бы проверял подписку и включал/отключал функционал в зависимости от состояния подписки.
Для себя выделил два типа проблемы, которые нужно решить:
1️⃣ Доступ к определённым функциям по подписке. Если подписка есть — то можно дёрнуть эндпоинт, а если нет, то дёргать нельзя.
2️⃣ Модификация какой-то функции в зависимости от состояния подписки. К примеру, если подписка есть, то возвращаем один список сущностей, а если нет, то обрезанный вариант.
С первым флоу всё просто.
Пишем атрибут и миддлварь, которые делают что-то такое:
public class SubscriptionRequirementAttribute : Attribute, IAuthorizationFilter
{
private readonly string _requiredLevel;
public SubscriptionRequirementAttribute(string requiredLevel)
{
_requiredLevel = requiredLevel;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var user = context.HttpContext.User;
var hasSubscription = user.HasClaim("SubscriptionLevel", _requiredLevel);
if (!hasSubscription)
{
context.Result = new ForbidResult();
}
}
}
[SubscriptionRequirement("Premium")]
public IActionResult GetPremiumContent()
{
// Доступно только для пользователей с подпиской "Premium"
}
И вуаля. Всё закрыто.
А вот со вторым я пока что размышляю, ибо тут есть несколько вариантов:
Во-первых, всё можно просто заифать. Типа прям в коде юзкейса как-то так:
[HttpGet("data")]
public IActionResult GetData()
{
var baseData = GetBaseData();
if (_subscriptionService.HasSubscription("Premium"))
{
var premiumData = GetPremiumData();
return Ok(new { Base = baseData, Premium = premiumData });
}
return Ok(new { Base = baseData });
}
Ну или сделать какой-то fabric, который выдаёт нужный функционал. Но это уже сорта одного и того же ифинга.