feat(saas): implement marketplace and tenant onboarding
This commit is contained in:
@@ -2,7 +2,9 @@ using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Tiku.Application.Tenancy;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Domain.Common;
|
||||
using Tiku.Domain.Platform;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
@@ -10,7 +12,8 @@ namespace Tiku.Infrastructure.Tenancy;
|
||||
|
||||
public sealed class TenantFrontendConfigService(
|
||||
TikuDbContext dbContext,
|
||||
IMemoryCache cache) : ITenantFrontendConfigService
|
||||
IMemoryCache cache,
|
||||
IFeatureAccessService featureAccessService) : ITenantFrontendConfigService
|
||||
{
|
||||
private static readonly TimeSpan RuntimeCacheDuration = TimeSpan.FromMinutes(2);
|
||||
|
||||
@@ -90,6 +93,16 @@ public sealed class TenantFrontendConfigService(
|
||||
item => item.Id == tenantId && item.Status == TenantStatus.Active,
|
||||
cancellationToken)
|
||||
?? throw new TenantFrontendConfigException("tenant_not_found", "Active tenant was not found.");
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var hasActiveSubscription = await dbContext.TenantSaasSubscriptions.AsNoTracking().AnyAsync(item =>
|
||||
item.TenantId == tenantId &&
|
||||
(item.Status == TenantSaasSubscriptionStatus.Trial || item.Status == TenantSaasSubscriptionStatus.Active) &&
|
||||
item.StartsAt <= now && item.CurrentPeriodEnd > now,
|
||||
cancellationToken);
|
||||
if (!hasActiveSubscription)
|
||||
{
|
||||
throw new TenantFrontendConfigException("subscription_inactive", "An active tenant subscription is required.");
|
||||
}
|
||||
var config = await dbContext.TenantFrontendConfigs.AsNoTracking()
|
||||
.SingleOrDefaultAsync(item => item.TenantId == tenantId, cancellationToken)
|
||||
?? CreateDefault(tenantId);
|
||||
@@ -102,7 +115,20 @@ public sealed class TenantFrontendConfigService(
|
||||
config.PublishedTheme.Clone(),
|
||||
config.PublishedFeatures.Clone(),
|
||||
config.PublishedNavigation.Clone(),
|
||||
config.PublishedHomeModules.Clone());
|
||||
config.PublishedHomeModules.Clone(),
|
||||
(await featureAccessService.GetEnabledFeaturesAsync(tenantId, FeatureAccessOperation.Read, cancellationToken))
|
||||
.Where(code => code != SaasFeatureCatalog.CoreBackoffice)
|
||||
.Order(StringComparer.Ordinal)
|
||||
.ToArray(),
|
||||
(await dbContext.TenantAuthPolicies.AsNoTracking()
|
||||
.Where(item => item.TenantId == tenantId)
|
||||
.Select(item => item.AllowedStudentLoginMethods)
|
||||
.SingleOrDefaultAsync(cancellationToken) ?? ["password"])
|
||||
.Select(value => value.Trim().ToLowerInvariant())
|
||||
.Where(value => value.Length > 0)
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.Order(StringComparer.Ordinal)
|
||||
.ToArray());
|
||||
cache.Set(CacheKey(tenantId), result, RuntimeCacheDuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user