feat: complete SaaS commercial delivery workflows

This commit is contained in:
2026-08-01 15:26:21 +08:00
parent 46abf4d62f
commit d58bcd97e9
56 changed files with 27505 additions and 181 deletions

View File

@@ -40,7 +40,8 @@ public sealed record PlatformTenantDetail(
PlatformTenantItem Tenant,
IReadOnlyCollection<PlatformTenantDomainItem> Domains,
IReadOnlyCollection<PlatformTenantSubscriptionItem> Subscriptions,
TenantBillingProfileItem? BillingProfile);
TenantBillingProfileItem? BillingProfile,
TenantBillingPolicyItem? BillingPolicy);
public sealed record PlatformTenantDomainItem(
Guid Id,
@@ -90,18 +91,46 @@ public sealed record CreatePlatformTenantCommand(
string? OwnerEmail,
string? OwnerPhone,
string OwnerName,
string TemporaryPassword);
string? TemporaryPassword,
Guid? InitialOfferingVersionId,
int TrialDays,
TenantBillingCollectionMode CollectionMode,
string DefaultPaymentProvider,
bool AutoGenerateRenewal,
int RenewalLeadDays,
string IdempotencyKey,
bool AllowTemporaryPassword);
public sealed record PlatformTenantProvisioningResult(
PlatformTenantItem Tenant,
Guid OwnerUserId,
string OwnerIdentifier,
bool MustChangePassword);
bool MustChangePassword,
Guid? ActivationId,
string? ActivationToken,
DateTimeOffset? ActivationExpiresAt,
bool IsReplay);
public sealed record TenantBillingPolicyItem(
Guid TenantId,
TenantBillingCollectionMode CollectionMode,
string DefaultPaymentProvider,
bool AutoGenerateRenewal,
int RenewalLeadDays,
DateTimeOffset CreatedAt,
DateTimeOffset UpdatedAt);
public sealed record UpsertTenantBillingPolicyCommand(
Guid TenantId,
TenantBillingCollectionMode CollectionMode,
string DefaultPaymentProvider,
bool AutoGenerateRenewal,
int RenewalLeadDays,
string Reason);
public sealed record UpdatePlatformTenantStatusCommand(
Guid TenantId,
TenantStatus Status,
BillingStatus BillingStatus,
string? Reason);
public sealed record UpsertPlatformTenantBillingProfileCommand(
@@ -227,6 +256,7 @@ public sealed record PlatformBillingDunningEventItem(
DateTimeOffset UpdatedAt);
public sealed record RetryPlatformBillingDunningEventCommand(Guid EventId, string? Reason);
public sealed record ResolvePlatformBillingDunningEventCommand(Guid EventId, string Reason);
public interface IPlatformAdminService
{
@@ -236,6 +266,8 @@ public interface IPlatformAdminService
Task<PlatformTenantProvisioningResult> CreateTenantAsync(PlatformAdminActor actor, CreatePlatformTenantCommand command, CancellationToken cancellationToken = default);
Task<PlatformTenantItem> UpdateTenantStatusAsync(PlatformAdminActor actor, UpdatePlatformTenantStatusCommand command, CancellationToken cancellationToken = default);
Task<TenantBillingProfileItem> UpsertTenantBillingProfileAsync(PlatformAdminActor actor, UpsertPlatformTenantBillingProfileCommand command, CancellationToken cancellationToken = default);
Task<TenantBillingPolicyItem> GetTenantBillingPolicyAsync(PlatformAdminActor actor, Guid tenantId, CancellationToken cancellationToken = default);
Task<TenantBillingPolicyItem> UpsertTenantBillingPolicyAsync(PlatformAdminActor actor, UpsertTenantBillingPolicyCommand command, CancellationToken cancellationToken = default);
Task<PlatformDomainList> GetDomainsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default);
Task<PlatformDomainRecheckResult> RecheckDomainAsync(PlatformAdminActor actor, Guid domainId, CancellationToken cancellationToken = default);
Task<PlatformStaffList> GetStaffAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default);
@@ -250,6 +282,8 @@ public interface IPlatformAdminService
Task<PlatformBillingDunningEventList> GetBillingDunningEventsAsync(PlatformAdminActor actor, PlatformAdminQuery query, CancellationToken cancellationToken = default);
Task<PlatformBillingDunningEventItem> GetBillingDunningEventDetailAsync(PlatformAdminActor actor, Guid eventId, CancellationToken cancellationToken = default);
Task<PlatformBillingDunningEventItem> RetryBillingDunningEventAsync(PlatformAdminActor actor, RetryPlatformBillingDunningEventCommand command, CancellationToken cancellationToken = default);
Task<PlatformBillingDunningEventItem> AcknowledgeBillingDunningEventAsync(PlatformAdminActor actor, ResolvePlatformBillingDunningEventCommand command, CancellationToken cancellationToken = default);
Task<PlatformBillingDunningEventItem> IgnoreBillingDunningEventAsync(PlatformAdminActor actor, ResolvePlatformBillingDunningEventCommand command, CancellationToken cancellationToken = default);
}
public sealed class PlatformAdminException(string message, string code) : Exception(message)