Files
tiku-backend.net/Tiku.Infrastructure/PlatformAdmin/Dashboard/PlatformDashboardService.cs

55 lines
3.5 KiB
C#

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<PlatformOverview> 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<PlatformOverviewRow>($"""
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; }
}
}