using System.Text.Json; 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 TenantBillingProfile : IHasTimestamps { public Guid TenantId { get; set; } public string? BillingName { get; set; } public string? TaxId { get; set; } public string? ContactName { get; set; } public string? ContactPhone { get; set; } public string? ContactEmail { get; set; } public string? BillingAddress { get; set; } public string? InvoiceTitle { get; set; } public TenantInvoiceTitleType? InvoiceType { get; set; } public string? BankName { get; set; } public string? BankAccountMasked { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; 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 { 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 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 DateOnly ReminderDate { get; set; } public int ReminderLevel { get; set; } = 1; public DateOnly? DueDate { get; set; } public int BalanceCentsSnapshot { get; set; } public string? Message { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset? SentAt { get; set; } public DateTimeOffset? AcknowledgedAt { get; set; } } public sealed class PlatformAuditAlertRule : AuditableEntity { public Guid? TenantId { get; set; } public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string? Description { get; set; } public bool Enabled { get; set; } = true; public PlatformAlertSeverity Severity { get; set; } = PlatformAlertSeverity.Medium; public string[] ActionPatterns { get; set; } = []; public string[] TargetTypes { get; set; } = []; public JsonElement Conditions { get; set; } = JsonDefaults.Object(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class PlatformAuditAlert : AuditableEntity { public Guid RuleId { get; set; } public Guid AuditLogId { get; set; } public Guid? TenantId { get; set; } public Guid? AcknowledgedBy { get; set; } public Guid? ResolvedBy { get; set; } public PlatformAlertSeverity Severity { get; set; } = PlatformAlertSeverity.Medium; public PlatformAuditAlertStatus Status { get; set; } = PlatformAuditAlertStatus.Open; public string Action { get; set; } = string.Empty; public string? TargetType { get; set; } public string? TargetId { get; set; } public string Title { get; set; } = string.Empty; public string? Summary { get; set; } public JsonElement Details { get; set; } = JsonDefaults.Object(); public DateTimeOffset FirstSeenAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset LastSeenAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? AcknowledgedAt { get; set; } public DateTimeOffset? ResolvedAt { get; set; } public string? ResolutionNote { get; set; } } public sealed class PlatformDunningNotificationChannel : 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 string WebhookUrl { get; set; } = string.Empty; public string? SecretRef { get; set; } public string[] ReminderTypes { get; set; } = ["overdue", "final_notice"]; public string[] ReminderChannels { get; set; } = ["internal"]; public int MinReminderLevel { get; set; } = 1; public Guid[] TenantIds { get; set; } = []; public int TimeoutSeconds { get; set; } = 10; public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class PlatformDunningNotificationEvent : 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 int Attempts { get; set; } public DateTimeOffset ScheduledAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? NextAttemptAt { get; set; } public DateTimeOffset? LastAttemptAt { get; set; } public DateTimeOffset? SentAt { get; set; } public string? LastError { get; set; } public int? LastHttpCode { get; set; } public string? LastResponseSummary { get; set; } public JsonElement RequestPayload { get; set; } = JsonDefaults.Object(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public enum PlatformBillingCycle { Monthly, Quarterly, Yearly, OneTime } public enum PlatformSaasPlanStatus { Active, Archived } 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 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 }