using System.Text.Json; using Tiku.Domain.Common; using Tiku.Domain.Operations; namespace Tiku.Domain.Platform; public sealed class SaasFeature : AuditableEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Category { get; set; } = string.Empty; public string? Description { get; set; } public int ReferencePriceCents { get; set; } public string Currency { get; set; } = "CNY"; public SaasFeatureStatus Status { get; set; } = SaasFeatureStatus.Draft; public bool IsCore { get; set; } public int SortOrder { get; set; } = 100; } public sealed class PermissionModule : AuditableEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant; public string? RequiredFeatureCode { get; set; } public string? Description { get; set; } public int SortOrder { get; set; } = 100; } public sealed class SaasOffering : AuditableEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public SaasOfferingType Type { get; set; } = SaasOfferingType.BasePlan; public SaasOfferingStatus Status { get; set; } = SaasOfferingStatus.Draft; public string? Description { get; set; } public int SortOrder { get; set; } = 100; } public sealed class SaasOfferingVersion : AuditableEntity { public Guid OfferingId { get; set; } public int Version { get; set; } = 1; public SaasOfferingVersionStatus Status { get; set; } = SaasOfferingVersionStatus.Draft; public PlatformBillingCycle BillingCycle { get; set; } = PlatformBillingCycle.Yearly; public int OriginalAmountCents { get; set; } public int AmountCents { get; set; } public string Currency { get; set; } = "CNY"; public DateTimeOffset? EffectiveAt { get; set; } public DateTimeOffset? PublishedAt { get; set; } public DateTimeOffset? RetiredAt { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class SaasOfferingVersionFeature : Entity { public Guid OfferingVersionId { get; set; } public string FeatureCode { get; set; } = string.Empty; } public sealed class SaasFeatureLimitDefinition : AuditableEntity { public string MetricCode { get; set; } = string.Empty; public string FeatureCode { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Unit { get; set; } = "count"; public SaasFeatureLimitKind Kind { get; set; } = SaasFeatureLimitKind.Current; public int WarningPercent { get; set; } = 80; public bool IsHardLimit { get; set; } = true; } public sealed class SaasOfferingVersionLimit : Entity { public Guid OfferingVersionId { get; set; } public string MetricCode { get; set; } = string.Empty; public long LimitValue { get; set; } } public sealed class TenantSaasSubscription : AuditableTenantEntity { public Guid BaseOfferingVersionId { get; set; } public Guid? ScheduledBaseOfferingVersionId { get; set; } public TenantSaasSubscriptionStatus Status { get; set; } = TenantSaasSubscriptionStatus.Trial; public DateTimeOffset StartsAt { get; set; } public DateTimeOffset CurrentPeriodStart { get; set; } public DateTimeOffset CurrentPeriodEnd { get; set; } public bool CancelAtPeriodEnd { get; set; } public DateTimeOffset? CancelledAt { get; set; } public long LifecycleVersion { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class TenantSaasSubscriptionItem : AuditableTenantEntity { public Guid SubscriptionId { get; set; } public Guid OfferingVersionId { get; set; } public Guid? SourceOrderItemId { get; set; } public TenantSaasSubscriptionItemType ItemType { get; set; } = TenantSaasSubscriptionItemType.BasePlan; public TenantSaasSubscriptionItemStatus Status { get; set; } = TenantSaasSubscriptionItemStatus.Active; public DateTimeOffset StartsAt { get; set; } public DateTimeOffset EndsAt { get; set; } } public sealed class TenantFeatureOverride : AuditableTenantEntity { public string FeatureCode { get; set; } = string.Empty; public TenantFeatureOverrideMode Mode { get; set; } = TenantFeatureOverrideMode.Disabled; public DateTimeOffset? ExpiresAt { get; set; } public string Reason { get; set; } = string.Empty; } public sealed class TenantFeatureUsage : AuditableTenantEntity { public string MetricCode { get; set; } = string.Empty; public DateTimeOffset PeriodStart { get; set; } public DateTimeOffset PeriodEnd { get; set; } public long UsedValue { get; set; } public long LimitValueSnapshot { get; set; } public bool WarningIssued { get; set; } public long Version { get; set; } } public sealed class PlatformBillingQuote : AuditableTenantEntity { public string QuoteNo { get; set; } = string.Empty; public string IdempotencyKey { get; set; } = string.Empty; public PlatformBillingQuoteStatus Status { get; set; } = PlatformBillingQuoteStatus.Active; public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription; public int OriginalAmountCents { get; set; } public int DiscountAmountCents { get; set; } public int TotalAmountCents { get; set; } public string Currency { get; set; } = "CNY"; public DateTimeOffset ExpiresAt { get; set; } public JsonElement FeatureSnapshot { get; set; } = JsonDefaults.Array(); public JsonElement LimitSnapshot { get; set; } = JsonDefaults.Object(); } public sealed class PlatformBillingQuoteItem : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid QuoteId { get; set; } public Guid OfferingVersionId { get; set; } public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan; public int Quantity { get; set; } = 1; public int UnitAmountCents { get; set; } public int AmountCents { get; set; } public JsonElement Snapshot { get; set; } = JsonDefaults.Object(); } public sealed class PlatformBillingOrder : AuditableTenantEntity { public Guid QuoteId { get; set; } public string OrderNo { get; set; } = string.Empty; public string IdempotencyKey { get; set; } = string.Empty; public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription; public PlatformBillingOrderStatus Status { get; set; } = PlatformBillingOrderStatus.PendingPayment; public int OriginalAmountCents { get; set; } public int DiscountAmountCents { get; set; } public int TotalAmountCents { get; set; } public string Currency { get; set; } = "CNY"; public DateTimeOffset ExpiresAt { get; set; } public DateTimeOffset? PaidAt { get; set; } public DateTimeOffset? CancelledAt { get; set; } public JsonElement Snapshot { get; set; } = JsonDefaults.Object(); } public sealed class PlatformBillingOrderItem : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid OrderId { get; set; } public Guid OfferingVersionId { get; set; } public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan; public int Quantity { get; set; } = 1; public int UnitAmountCents { get; set; } public int AmountCents { get; set; } public JsonElement Snapshot { get; set; } = JsonDefaults.Object(); } public sealed class PlatformBillingPayment : AuditableTenantEntity { public Guid OrderId { get; set; } public string PaymentNo { get; set; } = string.Empty; public string IdempotencyKey { get; set; } = string.Empty; public string Provider { get; set; } = string.Empty; public string Method { get; set; } = string.Empty; public PlatformBillingPaymentStatus Status { get; set; } = PlatformBillingPaymentStatus.Pending; public int AmountCents { get; set; } public string? ProviderTradeNo { get; set; } public DateTimeOffset? PaidAt { get; set; } public JsonElement ClientPayload { get; set; } = JsonDefaults.Object(); } public sealed class PlatformBillingPaymentEvent : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid PaymentId { get; set; } public string Provider { get; set; } = string.Empty; public string ProviderEventId { get; set; } = string.Empty; public string EventType { get; set; } = string.Empty; public JsonElement Payload { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class PlatformBillingRefund : AuditableTenantEntity { public Guid OrderId { get; set; } public Guid? PaymentId { get; set; } public string RefundNo { get; set; } = string.Empty; public PlatformBillingRefundStatus Status { get; set; } = PlatformBillingRefundStatus.Requested; public int AmountCents { get; set; } public string Reason { get; set; } = string.Empty; public string? ProviderRefundNo { get; set; } public DateTimeOffset? CompletedAt { get; set; } } public sealed class PlatformBillingInvoice : AuditableTenantEntity { public Guid? OrderId { get; set; } public string InvoiceNo { get; set; } = string.Empty; public PlatformBillingInvoiceStatus Status { get; set; } = PlatformBillingInvoiceStatus.Draft; public int TotalAmountCents { get; set; } public string Currency { get; set; } = "CNY"; public DateOnly? DueDate { get; set; } public DateTimeOffset? IssuedAt { get; set; } public DateTimeOffset? PaidAt { get; set; } public JsonElement BillingProfileSnapshot { get; set; } = JsonDefaults.Object(); } public enum SaasFeatureStatus { Draft, Active, Archived } public enum SaasOfferingType { BasePlan, AddOn } public enum SaasOfferingStatus { Draft, Active, Archived } public enum SaasOfferingVersionStatus { Draft, Published, Retired } public enum SaasFeatureLimitKind { Current, Period } public enum TenantSaasSubscriptionStatus { Trial, Active, PastDue, Cancelled, Expired, Suspended } public enum TenantSaasSubscriptionItemType { BasePlan, AddOn } public enum TenantSaasSubscriptionItemStatus { Pending, Active, Scheduled, Cancelled, Expired } public enum TenantFeatureOverrideMode { Enabled, Disabled } public enum PlatformBillingQuoteStatus { Active, Converted, Expired, Cancelled } public enum PlatformBillingOrderPurpose { NewSubscription, Renewal, Upgrade, Downgrade, AddOn } public enum PlatformBillingOrderStatus { PendingPayment, Paid, Cancelled, Expired, Refunded } public enum PlatformBillingItemType { BasePlan, AddOn } public enum PlatformBillingPaymentStatus { Pending, Succeeded, Failed, Refunded } public enum PlatformBillingRefundStatus { Requested, Processing, Succeeded, Failed, Cancelled } public enum PlatformBillingInvoiceStatus { Draft, Issued, Paid, Void, Overdue }