using System.Text.Json; using Microsoft.EntityFrameworkCore; using Tiku.Application.PlatformAdmin; using Tiku.Application.Security; using Tiku.Domain.Operations; using Tiku.Domain.Tenancy; namespace Tiku.Infrastructure.PlatformAdmin; internal sealed class PlatformTenantDomainService(PlatformAdministrationDependencies dependencies) : PlatformAdministrationServiceBase(dependencies), IPlatformTenantDomainService { public async Task GetDomainsAsync( PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default) { await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformTenantManage, cancellationToken); return await ExecuteSystemAsync("platform domain list", async dbContext => { var domains = dbContext.TenantDomains.AsNoTracking(); if (!string.IsNullOrWhiteSpace(query.Status)) domains = domains.Where(domain => domain.Status == ParseDomainStatus(query.Status)); if (!string.IsNullOrWhiteSpace(query.Search)) { var search = query.Search.Trim(); domains = domains.Where(domain => domain.Host.Contains(search)); } return new PlatformDomainList(await domains .OrderByDescending(domain => domain.UpdatedAt) .Take(Limit(query.Limit)) .Select(domain => ToDomainItem(domain)) .ToArrayAsync(cancellationToken)); }, cancellationToken); } public async Task RecheckDomainAsync( PlatformAdminActor actor, Guid domainId, CancellationToken cancellationToken = default) { await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformTenantManage, cancellationToken); return await ExecuteSystemAsync("platform domain recheck", async dbContext => { var domain = await dbContext.TenantDomains.SingleOrDefaultAsync(domain => domain.Id == domainId, cancellationToken) ?? throw new PlatformAdminException("Tenant domain was not found.", "domain_not_found"); domain.Status = domain.Status == TenantDomainStatus.Disabled ? TenantDomainStatus.Disabled : TenantDomainStatus.Pending; domain.LastCheckedAt = DateTimeOffset.UtcNow; domain.LastFailureReason = null; dbContext.BackgroundJobs.Add(new BackgroundJob { TenantId = domain.TenantId, JobType = "tenant_domain_recheck", Payload = JsonSerializer.SerializeToElement(new { domain.Id, domain.Host }), MaxRetries = 3 }); AddAudit(dbContext, actor, "platform.tenant_domain.recheck_requested", domain.TenantId, new { domain.Id, domain.Host }); await dbContext.SaveChangesAsync(cancellationToken); return new PlatformDomainRecheckResult(domain.Id, domain.Status, domain.LastCheckedAt.Value); }, cancellationToken); } }