Add three-layer feature gating for AI Catalog Price Check
Adds platform-level, plan-level (Enterprise only), and per-company toggles for the AI Catalog Price Check feature. Includes: - Company.AiCatalogPriceCheckEnabled per-company flag - SubscriptionPlanConfig.AllowAiCatalogPriceCheck plan-level flag - PlatformSetting 'AiCatalogPriceCheckEnabled' global kill switch - IPlatformSettingsService.GetBoolAsync helper - ISubscriptionService.CanUseAiCatalogPriceCheckAsync - UI controls in Companies/Edit, PlatformSubscription/Edit+Index, and SubscriptionManagement/Manage - Migration AddAiCatalogPriceCheckGating applied Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ namespace PowderCoating.Web.Controllers
|
||||
private readonly ISubscriptionService _subscriptionService;
|
||||
private readonly ICatalogImageService _catalogImageService;
|
||||
private readonly IAiCatalogPriceCheckService _priceCheckService;
|
||||
private readonly IPlatformSettingsService _platformSettings;
|
||||
|
||||
public CatalogItemsController(
|
||||
IUnitOfWork unitOfWork,
|
||||
@@ -50,7 +51,8 @@ namespace PowderCoating.Web.Controllers
|
||||
IMeasurementConversionService measurementService,
|
||||
ISubscriptionService subscriptionService,
|
||||
ICatalogImageService catalogImageService,
|
||||
IAiCatalogPriceCheckService priceCheckService)
|
||||
IAiCatalogPriceCheckService priceCheckService,
|
||||
IPlatformSettingsService platformSettings)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_mapper = mapper;
|
||||
@@ -62,6 +64,7 @@ namespace PowderCoating.Web.Controllers
|
||||
_subscriptionService = subscriptionService;
|
||||
_catalogImageService = catalogImageService;
|
||||
_priceCheckService = priceCheckService;
|
||||
_platformSettings = platformSettings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -934,6 +937,11 @@ namespace PowderCoating.Web.Controllers
|
||||
var currentUser = await _userManager.GetUserAsync(User);
|
||||
if (currentUser == null) return Forbid();
|
||||
|
||||
// Three-layer gate: platform setting → plan (Enterprise) → per-company toggle
|
||||
var platformEnabled = await _platformSettings.GetBoolAsync(PlatformSettingKeys.AiCatalogPriceCheckEnabled, true);
|
||||
var companyEnabled = platformEnabled && await _subscriptionService.CanUseAiCatalogPriceCheckAsync(currentUser.CompanyId);
|
||||
ViewBag.AiPriceCheckEnabled = companyEnabled;
|
||||
|
||||
var existing = await _unitOfWork.CatalogPriceCheckReports.FindAsync(
|
||||
r => r.CompanyId == currentUser.CompanyId);
|
||||
var report = existing.OrderByDescending(r => r.RunAt).FirstOrDefault();
|
||||
@@ -995,6 +1003,14 @@ namespace PowderCoating.Web.Controllers
|
||||
var currentUser = await _userManager.GetUserAsync(User);
|
||||
if (currentUser == null) return Forbid();
|
||||
|
||||
// Three-layer gate: platform setting → plan → per-company toggle
|
||||
var platformEnabled = await _platformSettings.GetBoolAsync(PlatformSettingKeys.AiCatalogPriceCheckEnabled, true);
|
||||
if (!platformEnabled || !await _subscriptionService.CanUseAiCatalogPriceCheckAsync(currentUser.CompanyId))
|
||||
{
|
||||
TempData["Error"] = "AI Catalog Price Check is not available on your current plan.";
|
||||
return RedirectToAction(nameof(AiPriceCheck));
|
||||
}
|
||||
|
||||
// Enforce quarterly run limit — check the most recent report for this company.
|
||||
var lastReport = (await _unitOfWork.CatalogPriceCheckReports.FindAsync(
|
||||
r => r.CompanyId == currentUser.CompanyId))
|
||||
|
||||
Reference in New Issue
Block a user