using System.Text.Json; using Tiku.Domain.Common; namespace Tiku.Domain.Tenancy; public sealed class TenantAuthProvider : AuditableTenantEntity { public string Provider { get; set; } = string.Empty; public TenantAuthProviderStatus Status { get; set; } = TenantAuthProviderStatus.Disabled; public string? DisplayName { get; set; } public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object(); } public sealed class SmsVerificationCode : Entity { public Guid TenantId { get; set; } public string Phone { get; set; } = string.Empty; public SmsPurpose Purpose { get; set; } = SmsPurpose.Login; public string CodeHash { get; set; } = string.Empty; public string Provider { get; set; } = "mock"; public SmsVerificationStatus Status { get; set; } = SmsVerificationStatus.Pending; public int Attempts { get; set; } public DateTimeOffset ExpiresAt { get; set; } public DateTimeOffset? ConsumedAt { get; set; } public string? IpAddress { get; set; } public string? UserAgent { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class AuthLoginEvent : Entity { public Guid TenantId { get; set; } public Guid? UserId { get; set; } public string Provider { get; set; } = string.Empty; public string? Identifier { get; set; } public AuthLoginResult Result { get; set; } = AuthLoginResult.Failed; public string? FailureCode { get; set; } public string? IpAddress { get; set; } public string? UserAgent { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class AuthSession : AuditableTenantEntity { public Guid UserId { get; set; } public string TokenHash { get; set; } = string.Empty; public string Provider { get; set; } = string.Empty; public DateTimeOffset ExpiresAt { get; set; } public DateTimeOffset? RevokedAt { get; set; } public string? IpAddress { get; set; } public string? UserAgent { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class SmsSendRateLimit { public Guid TenantId { get; set; } public SmsRateLimitDimension Dimension { get; set; } = SmsRateLimitDimension.Phone; public string ScopeHash { get; set; } = string.Empty; public DateTimeOffset BucketStart { get; set; } public int RequestCount { get; set; } public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class TenantRoleTemplate : AuditableTenantEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string? Description { get; set; } public TenantRole BaseRole { get; set; } = TenantRole.TenantOperator; public TenantRoleTemplateStatus Status { get; set; } = TenantRoleTemplateStatus.Active; public JsonElement Permissions { get; set; } = JsonDefaults.Object(); public JsonElement MenuPermissions { get; set; } = JsonDefaults.Object(); public JsonElement ModulePermissions { get; set; } = JsonDefaults.Object(); public JsonElement FieldPermissions { get; set; } = JsonDefaults.Object(); public JsonElement DataScope { get; set; } = JsonDefaults.Object(); public bool IsSystem { get; set; } public int SortOrder { get; set; } = 100; public Guid? CreatedBy { get; set; } public Guid? UpdatedBy { get; set; } } public sealed class TenantClass : AuditableTenantEntity { public Guid? RegionId { get; set; } public string? LegacyId { get; set; } public string? Code { get; set; } public string Name { get; set; } = string.Empty; public string? Description { get; set; } public TenantRecordStatus Status { get; set; } = TenantRecordStatus.Active; public int SortOrder { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public Guid? CreatedBy { get; set; } public Guid? UpdatedBy { get; set; } } public sealed class TenantClassMember : AuditableTenantEntity { public Guid ClassId { get; set; } public Guid UserId { get; set; } public TenantClassMemberType MemberType { get; set; } = TenantClassMemberType.Student; public TenantClassMemberStatus Status { get; set; } = TenantClassMemberStatus.Active; public DateTimeOffset JoinedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? LeftAt { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public Guid? CreatedBy { get; set; } public Guid? UpdatedBy { get; set; } } public sealed class TenantStudentNote : AuditableTenantEntity { public Guid StudentUserId { get; set; } public StudentNoteType NoteType { get; set; } = StudentNoteType.General; public string Content { get; set; } = string.Empty; public StudentNoteVisibility Visibility { get; set; } = StudentNoteVisibility.TenantStaff; public bool IsPinned { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public Guid? CreatedBy { get; set; } public Guid? UpdatedBy { get; set; } } public sealed class TenantStudentFollowup : AuditableTenantEntity { public Guid StudentUserId { get; set; } public Guid? AssignedToUserId { get; set; } public Guid? ClassId { get; set; } public string Title { get; set; } = string.Empty; public string? Description { get; set; } public StudentFollowupType FollowupType { get; set; } = StudentFollowupType.Learning; public StudentFollowupPriority Priority { get; set; } = StudentFollowupPriority.Normal; public StudentFollowupStatus Status { get; set; } = StudentFollowupStatus.Open; public DateTimeOffset? DueAt { get; set; } public DateTimeOffset? CompletedAt { get; set; } public Guid? CompletedBy { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public Guid? CreatedBy { get; set; } public Guid? UpdatedBy { get; set; } } public enum TenantAuthProviderStatus { Active, Disabled, Testing } public enum SmsPurpose { Login, BindPhone, ResetPassword } public enum SmsVerificationStatus { Pending, Sent, Verified, Expired, Blocked } public enum AuthLoginResult { Sent, Success, Failed, Blocked } public enum SmsRateLimitDimension { Tenant, Phone, Ip, Device } public enum TenantRoleTemplateStatus { Active, Disabled, Archived } public enum TenantRecordStatus { Active, Disabled, Archived } public enum TenantClassMemberType { Student, Teacher, Assistant, HeadTeacher } public enum TenantClassMemberStatus { Active, Disabled, Removed } public enum StudentNoteType { General, Learning, Service, Sales, Risk, FollowUp } public enum StudentNoteVisibility { TenantStaff, ClassStaff, AuthorOnly } public enum StudentFollowupType { Learning, Service, Sales, Renewal, Risk, Custom } public enum StudentFollowupPriority { Low, Normal, High, Urgent } public enum StudentFollowupStatus { Open, InProgress, Done, Cancelled }