using System.Text.Json; using Tiku.Domain.Common; namespace Tiku.Domain.Platform; public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned { 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 TenantBillingInvoiceTitleType? 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 TenantBillingPolicy : IHasTimestamps, ITenantOwned { public Guid TenantId { get; set; } public TenantBillingCollectionMode CollectionMode { get; set; } = TenantBillingCollectionMode.Online; public string DefaultPaymentProvider { get; set; } = "manual"; public bool AutoGenerateRenewal { get; set; } = true; public int RenewalLeadDays { get; set; } = 14; public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class TenantOwnerActivationGrant : AuditableTenantEntity { public Guid UserId { get; set; } public Guid CreatedBy { get; set; } public string TokenHash { get; set; } = string.Empty; public DateTimeOffset ExpiresAt { get; set; } public DateTimeOffset? ConsumedAt { get; set; } } public sealed class PlatformOperationIdempotency : AuditableEntity { public Guid ActorUserId { get; set; } public string Scope { get; set; } = string.Empty; public string IdempotencyKey { get; set; } = string.Empty; public string RequestHash { get; set; } = string.Empty; public Guid ResourceId { get; set; } } public sealed class PlatformBillingInvoiceReminder : AuditableTenantEntity { public Guid InvoiceId { get; set; } public Guid? CreatedBy { get; set; } 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; } 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 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 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"]; 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 PlatformBillingDunningNotificationEvent : AuditableTenantEntity { public Guid ChannelId { get; set; } public Guid ReminderId { get; set; } public Guid InvoiceId { get; set; } 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; } 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 sealed class PlatformPaymentApp : AuditableEntity { public string AppCode { get; set; } = string.Empty; public string AppName { get; set; } = string.Empty; public PlatformPaymentAppStatus Status { get; set; } = PlatformPaymentAppStatus.Disabled; public string SettlementMode { get; set; } = "PlatformCollect"; public string? Description { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class PlatformPaymentChannel : AuditableEntity { public Guid AppId { get; set; } public string Provider { get; set; } = "manual"; public string Mode { get; set; } = "PlatformCollect"; public PlatformPaymentChannelStatus Status { get; set; } = PlatformPaymentChannelStatus.Disabled; public string DisplayName { get; set; } = string.Empty; public string? SecretRef { get; set; } public string? CallbackPath { get; set; } public int Priority { get; set; } = 100; public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public enum PlatformBillingCycle { Monthly, Quarterly, Yearly, OneTime } 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 PlatformBillingDunningProvider { Generic, Dingtalk, Feishu, Wecom } public enum PlatformBillingDunningNotificationStatus { Pending, Processing, Sent, Retrying, Failed, Discarded, Acknowledged, Ignored } public enum PlatformPaymentAppStatus { Active, Disabled, Testing } public enum PlatformPaymentChannelStatus { Active, Disabled, Testing } public enum TenantBillingCollectionMode { Online, Manual }