feat(saas): implement marketplace and tenant onboarding

This commit is contained in:
2026-07-29 13:58:59 +08:00
parent 76606029e2
commit 6db200a2fc
145 changed files with 16862 additions and 94529 deletions

View File

@@ -3,45 +3,6 @@ using Tiku.Domain.Common;
namespace Tiku.Domain.Platform;
public sealed class PlatformSaasPlan : AuditableEntity
{
public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public PlatformBillingCycle BillingCycle { get; set; } = PlatformBillingCycle.Yearly;
public int BaseAmountCents { get; set; }
public string Currency { get; set; } = "CNY";
public JsonElement IncludedQuotas { get; set; } = JsonDefaults.Object();
public JsonElement OveragePrices { get; set; } = JsonDefaults.Object();
public JsonElement FeatureFlags { get; set; } = JsonDefaults.Object();
public PlatformSaasPlanStatus Status { get; set; } = PlatformSaasPlanStatus.Active;
public int SortOrder { get; set; }
}
public sealed class ProductModule : AuditableEntity
{
public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public ProductModuleStatus Status { get; set; } = ProductModuleStatus.Active;
public int SortOrder { get; set; }
}
public sealed class PlanModuleEntitlement : Entity
{
public string PlanCode { get; set; } = string.Empty;
public string ModuleCode { get; set; } = string.Empty;
public bool Enabled { get; set; } = true;
}
public sealed class TenantModuleOverride : AuditableTenantEntity
{
public string ModuleCode { get; set; } = string.Empty;
public TenantModuleOverrideMode Mode { get; set; } = TenantModuleOverrideMode.Disabled;
public DateTimeOffset? ExpiresAt { get; set; }
public string? Reason { get; set; }
}
public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
{
public Guid TenantId { get; set; }
@@ -52,7 +13,7 @@ public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
public string? ContactEmail { get; set; }
public string? BillingAddress { get; set; }
public string? InvoiceTitle { get; set; }
public TenantInvoiceTitleType? InvoiceType { get; set; }
public TenantBillingInvoiceTitleType? InvoiceType { get; set; }
public string? BankName { get; set; }
public string? BankAccountMasked { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
@@ -60,63 +21,13 @@ public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
}
public sealed class TenantInvoice : AuditableTenantEntity
{
public Guid? CreatedBy { get; set; }
public string InvoiceNo { get; set; } = string.Empty;
public TenantInvoiceType InvoiceType { get; set; } = TenantInvoiceType.Subscription;
public TenantInvoiceStatus Status { get; set; } = TenantInvoiceStatus.Draft;
public string Currency { get; set; } = "CNY";
public int SubtotalCents { get; set; }
public int DiscountCents { get; set; }
public int TaxCents { get; set; }
public int TotalCents { get; set; }
public int PaidCents { get; set; }
public int BalanceCents { get; set; }
public DateOnly? BillingPeriodStart { get; set; }
public DateOnly? BillingPeriodEnd { get; set; }
public DateOnly? DueDate { get; set; }
public DateTimeOffset? IssuedAt { get; set; }
public DateTimeOffset? PaidAt { get; set; }
public string? Note { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class TenantInvoiceItem : Entity, ITenantOwned
{
public Guid TenantId { get; set; }
public Guid InvoiceId { get; set; }
public string ItemType { get; set; } = "subscription";
public Guid? ItemRefId { get; set; }
public string Description { get; set; } = string.Empty;
public decimal Quantity { get; set; } = 1;
public int UnitAmountCents { get; set; }
public int AmountCents { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}
public sealed class TenantInvoicePayment : AuditableTenantEntity
{
public Guid InvoiceId { get; set; }
public Guid? ReceivedBy { get; set; }
public string PaymentNo { get; set; } = string.Empty;
public string Provider { get; set; } = "manual";
public string? Method { get; set; }
public TenantInvoicePaymentStatus Status { get; set; } = TenantInvoicePaymentStatus.Paid;
public int AmountCents { get; set; }
public DateTimeOffset? PaidAt { get; set; }
public string? ProviderTradeNo { get; set; }
public JsonElement RawPayload { get; set; } = JsonDefaults.Object();
}
public sealed class TenantInvoiceReminder : AuditableTenantEntity
public sealed class PlatformBillingInvoiceReminder : AuditableTenantEntity
{
public Guid InvoiceId { get; set; }
public Guid? CreatedBy { get; set; }
public TenantInvoiceReminderType ReminderType { get; set; } = TenantInvoiceReminderType.Overdue;
public TenantInvoiceReminderChannel Channel { get; set; } = TenantInvoiceReminderChannel.Manual;
public TenantInvoiceReminderStatus Status { get; set; } = TenantInvoiceReminderStatus.Pending;
public PlatformBillingInvoiceReminderType ReminderType { get; set; } = PlatformBillingInvoiceReminderType.Overdue;
public PlatformBillingInvoiceReminderChannel Channel { get; set; } = PlatformBillingInvoiceReminderChannel.Manual;
public PlatformBillingInvoiceReminderStatus Status { get; set; } = PlatformBillingInvoiceReminderStatus.Pending;
public DateOnly ReminderDate { get; set; }
public int ReminderLevel { get; set; } = 1;
public DateOnly? DueDate { get; set; }
@@ -163,13 +74,13 @@ public sealed class PlatformAuditAlert : AuditableEntity
public string? ResolutionNote { get; set; }
}
public sealed class PlatformDunningNotificationChannel : AuditableEntity
public sealed class PlatformBillingDunningNotificationChannel : AuditableEntity
{
public string ChannelCode { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public bool Enabled { get; set; } = true;
public PlatformDunningProvider Provider { get; set; } = PlatformDunningProvider.Generic;
public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
public string WebhookUrl { get; set; } = string.Empty;
public string? SecretRef { get; set; }
public string[] ReminderTypes { get; set; } = ["overdue", "final_notice"];
@@ -180,13 +91,13 @@ public sealed class PlatformDunningNotificationChannel : AuditableEntity
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class PlatformDunningNotificationEvent : AuditableTenantEntity
public sealed class PlatformBillingDunningNotificationEvent : AuditableTenantEntity
{
public Guid ChannelId { get; set; }
public Guid ReminderId { get; set; }
public Guid InvoiceId { get; set; }
public PlatformDunningProvider Provider { get; set; } = PlatformDunningProvider.Generic;
public PlatformDunningNotificationStatus Status { get; set; } = PlatformDunningNotificationStatus.Pending;
public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
public PlatformBillingDunningNotificationStatus Status { get; set; } = PlatformBillingDunningNotificationStatus.Pending;
public int Attempts { get; set; }
public DateTimeOffset ScheduledAt { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? NextAttemptAt { get; set; }
@@ -200,17 +111,11 @@ public sealed class PlatformDunningNotificationEvent : AuditableTenantEntity
}
public enum PlatformBillingCycle { Monthly, Quarterly, Yearly, OneTime }
public enum PlatformSaasPlanStatus { Active, Archived }
public enum ProductModuleStatus { Active, Archived }
public enum TenantModuleOverrideMode { Enabled, Disabled }
public enum TenantInvoiceTitleType { None, NormalVat, SpecialVat }
public enum TenantInvoiceType { Subscription, ServiceFee, UsageOverage, ManualAdjustment }
public enum TenantInvoiceStatus { Draft, Issued, Paid, Void, Overdue }
public enum TenantInvoicePaymentStatus { Pending, Paid, Failed, Refunded }
public enum TenantInvoiceReminderType { DueSoon, Overdue, FinalNotice, Manual }
public enum TenantInvoiceReminderChannel { Manual, Internal, Sms, Email, Wechat, Crm }
public enum TenantInvoiceReminderStatus { Pending, Sent, Acknowledged, Dismissed, Failed }
public enum TenantBillingInvoiceTitleType { None, NormalVat, SpecialVat }
public enum PlatformBillingInvoiceReminderType { DueSoon, Overdue, FinalNotice, Manual }
public enum PlatformBillingInvoiceReminderChannel { Manual, Internal, Sms, Email, Wechat, Crm }
public enum PlatformBillingInvoiceReminderStatus { Pending, Sent, Acknowledged, Dismissed, Failed }
public enum PlatformAlertSeverity { Low, Medium, High, Critical }
public enum PlatformAuditAlertStatus { Open, Acknowledged, Resolved, Ignored }
public enum PlatformDunningProvider { Generic, Dingtalk, Feishu, Wecom }
public enum PlatformDunningNotificationStatus { Pending, Processing, Sent, Retrying, Failed, Discarded }
public enum PlatformBillingDunningProvider { Generic, Dingtalk, Feishu, Wecom }
public enum PlatformBillingDunningNotificationStatus { Pending, Processing, Sent, Retrying, Failed, Discarded }