Files
tiku-backend.net/Tiku.Domain/Tenancy/TenantOperationsEntities.cs

186 lines
8.3 KiB
C#

using System.Text.Json;
using Tiku.Domain.Common;
namespace Tiku.Domain.Tenancy;
public sealed class TenantExternalProvider : AuditableTenantEntity
{
public TenantExternalProviderCapability Capability { get; set; } = TenantExternalProviderCapability.Identity;
public string Provider { get; set; } = string.Empty;
public TenantExternalProviderStatus Status { get; set; } = TenantExternalProviderStatus.Disabled;
public string? DisplayName { get; set; }
public string? SecretRef { get; set; }
public int Priority { get; set; } = 100;
public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class TenantSecret : AuditableTenantEntity
{
public string Purpose { get; set; } = string.Empty;
public string Provider { get; set; } = string.Empty;
public string SecretKey { get; set; } = string.Empty;
public string SecretRef { get; set; } = string.Empty;
public TenantSecretStatus Status { get; set; } = TenantSecretStatus.Active;
public string EncryptionKeyId { get; set; } = string.Empty;
public byte[] EncryptedPayload { get; set; } = [];
public byte[] EncryptionNonce { get; set; } = [];
public byte[] EncryptionTag { get; set; } = [];
public DateTimeOffset? RotatedAt { get; set; }
public DateTimeOffset? ExpiresAt { get; set; }
}
public sealed class SmsVerificationCode : Entity, ITenantOwned
{
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 : AuditableEntity
{
public AuthRealm Realm { get; set; } = AuthRealm.Tenant;
public Guid? TenantId { get; set; }
public Guid UserId { get; set; }
public Guid TokenFamilyId { get; set; }
public Guid? ParentSessionId { get; set; }
public Guid? ReplacedBySessionId { get; set; }
public string TokenHash { get; set; } = string.Empty;
public string SecurityStamp { get; set; } = string.Empty;
public bool MfaSatisfied { get; set; }
public string Provider { get; set; } = string.Empty;
public DateTimeOffset ExpiresAt { get; set; }
public DateTimeOffset? RevokedAt { get; set; }
public string? RevokedReason { get; set; }
public string? IpAddress { get; set; }
public string? UserAgent { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public enum AuthRealm { Tenant, Platform }
public sealed class AuthChallenge : Entity
{
public Guid UserId { get; set; }
public AuthRealm Realm { get; set; }
public Guid? TenantId { get; set; }
public AuthChallengePurpose Purpose { get; set; }
public string TokenHash { get; set; } = string.Empty;
public string SecurityStamp { get; set; } = string.Empty;
public string Provider { get; set; } = string.Empty;
public DateTimeOffset ExpiresAt { get; set; }
public DateTimeOffset? ConsumedAt { get; set; }
public string? IpAddress { get; set; }
public string? UserAgent { get; set; }
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}
public enum AuthChallengePurpose { MfaEnrollment, MfaVerification, PasswordChange }
public sealed class SmsSendRateLimit : ITenantOwned
{
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 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 TenantExternalProviderCapability { Identity, ObjectStorage, Sms, Payment, Notification }
public enum TenantExternalProviderStatus { Active, Disabled, Testing }
public enum TenantSecretStatus { Active, Disabled, Rotating }
public enum SmsPurpose { Login, BindPhone, ResetPassword }
public enum SmsVerificationStatus { Pending, Sent, Verified, Expired, Blocked, Failed }
public enum AuthLoginResult { Sent, Success, Failed, Blocked }
public enum SmsRateLimitDimension { Tenant, Phone, Ip, Device }
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 }