using Microsoft.EntityFrameworkCore; using Tiku.Application.PlatformAdmin; using Tiku.Application.Security; namespace Tiku.Infrastructure.PlatformAdmin; internal sealed class PlatformDashboardService(PlatformAdministrationDependencies dependencies) : PlatformAdministrationServiceBase(dependencies), IPlatformDashboardService { public async Task GetOverviewAsync( PlatformAdminActor actor, CancellationToken cancellationToken = default) { await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformDashboardView, cancellationToken); return await ExecuteSystemAsync("platform overview", async dbContext => { var row = await dbContext.Database.SqlQuery($""" SELECT (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned') AS "TenantCount", (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned' AND status = 'active') AS "ActiveTenantCount", (SELECT count(*)::integer FROM tenants WHERE mode <> 'platform_owned' AND status = 'suspended') AS "SuspendedTenantCount", (SELECT count(*)::integer FROM orders) AS "OrderCount", (SELECT count(*)::integer FROM orders WHERE status = 'paid') AS "PaidOrderCount", (SELECT COALESCE(sum(amount_cents - refunded_amount_cents), 0)::integer FROM orders WHERE status IN ('paid', 'partially_refunded')) AS "RevenueCents", (SELECT count(*)::integer FROM question_banks) AS "QuestionBankCount", (SELECT count(*)::integer FROM questions WHERE status = 'published') AS "QuestionCount", (SELECT count(DISTINCT user_id)::integer FROM practice_sessions WHERE started_at >= {DateTimeOffset.UtcNow.AddDays(-7)}) AS "LearningActiveUserCount" """).SingleAsync(cancellationToken); return new PlatformOverview( row.TenantCount, row.ActiveTenantCount, row.SuspendedTenantCount, row.OrderCount, row.PaidOrderCount, row.RevenueCents, row.QuestionBankCount, row.QuestionCount, row.LearningActiveUserCount); }, cancellationToken); } private sealed class PlatformOverviewRow { public int TenantCount { get; init; } public int ActiveTenantCount { get; init; } public int SuspendedTenantCount { get; init; } public int OrderCount { get; init; } public int PaidOrderCount { get; init; } public int RevenueCents { get; init; } public int QuestionBankCount { get; init; } public int QuestionCount { get; init; } public int LearningActiveUserCount { get; init; } } }