using System.Text.Json; using Tiku.Domain.Commerce; using Tiku.Domain.Platform; using Tiku.Domain.Tenancy; using Tiku.Domain.Identity; namespace Tiku.Application.PlatformAdmin; public sealed record PlatformAdminActor(Guid UserId); public sealed record PlatformAdminQuery(string? Status = null, string? Search = null, int? Limit = null); public sealed record PlatformOverview( int TenantCount, int ActiveTenantCount, int SuspendedTenantCount, int OrderCount, int PaidOrderCount, int RevenueCents, int QuestionBankCount, int QuestionCount, int LearningActiveUserCount); public sealed record PlatformTenantList(IReadOnlyCollection Items); public sealed record PlatformTenantItem( Guid Id, string Slug, string Name, string? LegalName, TenantStatus Status, TenantMode Mode, BillingStatus BillingStatus, DateTimeOffset? SubscriptionExpiresAt, int DomainCount, DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt); public sealed record PlatformTenantDetail( PlatformTenantItem Tenant, IReadOnlyCollection Domains, IReadOnlyCollection Subscriptions, TenantBillingProfileItem? BillingProfile); public sealed record PlatformTenantDomainItem( Guid Id, Guid TenantId, string Host, TenantDomainType DomainType, TenantDomainStatus Status, bool IsPrimary, DateTimeOffset? VerifiedAt, DateTimeOffset? DnsVerifiedAt, DateTimeOffset? TlsReadyAt, DateTimeOffset? LastCheckedAt, string? LastFailureReason); public sealed record PlatformTenantSubscriptionItem( Guid Id, Guid TenantId, Guid BaseOfferingVersionId, TenantSaasSubscriptionStatus Status, DateTimeOffset StartsAt, DateTimeOffset CurrentPeriodStart, DateTimeOffset CurrentPeriodEnd, bool CancelAtPeriodEnd, JsonElement Metadata); public sealed record TenantBillingProfileItem( Guid TenantId, string? BillingName, string? TaxId, string? ContactName, string? ContactPhoneMasked, string? ContactEmail, string? BillingAddress, string? InvoiceTitle, TenantBillingInvoiceTitleType? InvoiceType, string? BankName, string? BankAccountMasked, JsonElement Metadata); public sealed record CreatePlatformTenantCommand( string Slug, string Name, string? LegalName, TenantStatus Status, BillingStatus BillingStatus, JsonElement Metadata, string? OwnerEmail, string? OwnerPhone, string OwnerName, string TemporaryPassword); public sealed record PlatformTenantProvisioningResult( PlatformTenantItem Tenant, Guid OwnerUserId, string OwnerIdentifier, bool MustChangePassword); public sealed record UpdatePlatformTenantStatusCommand( Guid TenantId, TenantStatus Status, BillingStatus BillingStatus, string? Reason); public sealed record UpsertPlatformTenantBillingProfileCommand( Guid TenantId, string? BillingName, string? TaxId, string? ContactName, string? ContactPhone, string? ContactEmail, string? BillingAddress, string? InvoiceTitle, TenantBillingInvoiceTitleType? InvoiceType, string? BankName, string? BankAccountMasked, JsonElement Metadata); public sealed record PlatformDomainList(IReadOnlyCollection Items); public sealed record PlatformDomainRecheckResult(Guid DomainId, TenantDomainStatus Status, DateTimeOffset LastCheckedAt); public sealed record PlatformStaffList(IReadOnlyCollection Items); public sealed record PlatformStaffItem( Guid UserId, string? Name, string? PhoneMasked, string? Email, UserStatus Status, IReadOnlyCollection RoleCodes, DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt); public sealed record UpsertPlatformStaffCommand( Guid? UserId, string? Email, string? Phone, string? Name, UserStatus Status, IReadOnlyCollection RoleIds); public sealed record UpdatePlatformStaffStatusCommand(Guid UserId, UserStatus Status, string? Reason); public sealed record PlatformAuditLogList(IReadOnlyCollection Items); public sealed record PlatformAuditLogItem( Guid Id, Guid? TenantId, Guid? ActorUserId, string Action, string? TargetType, string? TargetId, JsonElement Details, string? IpAddress, string? UserAgent, DateTimeOffset CreatedAt); public sealed record PlatformAuditAlertList(IReadOnlyCollection Items); public sealed record UpdatePlatformAuditAlertStatusCommand( Guid AlertId, PlatformAuditAlertStatus Status, string? ResolutionNote); public sealed record PlatformBillingDunningChannelList(IReadOnlyCollection Items); public sealed record PlatformBillingDunningChannelItem( Guid Id, string ChannelCode, string Name, string? Description, bool Enabled, PlatformBillingDunningProvider Provider, string WebhookUrlMasked, string? SecretRef, IReadOnlyCollection ReminderTypes, IReadOnlyCollection ReminderChannels, int MinReminderLevel, IReadOnlyCollection TenantIds, int TimeoutSeconds, JsonElement Metadata, DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt); public sealed record UpsertPlatformBillingDunningChannelCommand( Guid? ChannelId, string ChannelCode, string Name, string? Description, bool Enabled, PlatformBillingDunningProvider Provider, string WebhookUrl, string? SecretRef, IReadOnlyCollection ReminderTypes, IReadOnlyCollection ReminderChannels, int MinReminderLevel, IReadOnlyCollection TenantIds, int TimeoutSeconds, JsonElement Metadata); public sealed record DisablePlatformBillingDunningChannelCommand(Guid ChannelId, string? Reason); public sealed record PlatformBillingDunningEventList(IReadOnlyCollection Items); public sealed record PlatformBillingDunningEventItem( Guid Id, Guid TenantId, Guid ChannelId, Guid ReminderId, Guid InvoiceId, PlatformBillingDunningProvider Provider, PlatformBillingDunningNotificationStatus Status, int Attempts, DateTimeOffset ScheduledAt, DateTimeOffset? NextAttemptAt, DateTimeOffset? LastAttemptAt, DateTimeOffset? SentAt, string? LastError, int? LastHttpCode, string? LastResponseSummary, JsonElement RequestPayload, JsonElement Metadata, DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt); public sealed record RetryPlatformBillingDunningEventCommand(Guid EventId, string? Reason); public interface IPlatformAdminService { Task GetOverviewAsync(PlatformAdminActor actor, CancellationToken cancellationToken = default); Task GetTenantsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task GetTenantDetailAsync(PlatformAdminActor actor, Guid tenantId, CancellationToken cancellationToken = default); Task CreateTenantAsync(PlatformAdminActor actor, CreatePlatformTenantCommand command, CancellationToken cancellationToken = default); Task UpdateTenantStatusAsync(PlatformAdminActor actor, UpdatePlatformTenantStatusCommand command, CancellationToken cancellationToken = default); Task UpsertTenantBillingProfileAsync(PlatformAdminActor actor, UpsertPlatformTenantBillingProfileCommand command, CancellationToken cancellationToken = default); Task GetDomainsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task RecheckDomainAsync(PlatformAdminActor actor, Guid domainId, CancellationToken cancellationToken = default); Task GetStaffAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task UpsertStaffAsync(PlatformAdminActor actor, UpsertPlatformStaffCommand command, CancellationToken cancellationToken = default); Task UpdateStaffStatusAsync(PlatformAdminActor actor, UpdatePlatformStaffStatusCommand command, CancellationToken cancellationToken = default); Task GetAuditLogsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task GetAuditAlertsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task UpdateAuditAlertStatusAsync(PlatformAdminActor actor, UpdatePlatformAuditAlertStatusCommand command, CancellationToken cancellationToken = default); Task GetBillingDunningChannelsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task UpsertBillingDunningChannelAsync(PlatformAdminActor actor, UpsertPlatformBillingDunningChannelCommand command, CancellationToken cancellationToken = default); Task DisableBillingDunningChannelAsync(PlatformAdminActor actor, DisablePlatformBillingDunningChannelCommand command, CancellationToken cancellationToken = default); Task GetBillingDunningEventsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default); Task GetBillingDunningEventDetailAsync(PlatformAdminActor actor, Guid eventId, CancellationToken cancellationToken = default); Task RetryBillingDunningEventAsync(PlatformAdminActor actor, RetryPlatformBillingDunningEventCommand command, CancellationToken cancellationToken = default); } public sealed class PlatformAdminException(string message, string code) : Exception(message) { public string Code { get; } = code; }