using Tiku.Domain.Common; namespace Tiku.Domain.Learning; public sealed class BusinessLine : AuditableEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public LearningRegionAccessStrategy RegionAccessStrategy { get; set; } = LearningRegionAccessStrategy.LicensedRegions; public bool RequiresBaseRegion { get; set; } public int TargetRegionCooldownDays { get; set; } = 30; public bool IsActive { get; set; } = true; } public sealed class MarketRegion : AuditableEntity { public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string? ParentCode { get; set; } public bool IsActive { get; set; } = true; } public sealed class TenantLearningLicense : AuditableTenantEntity { public Guid BusinessLineId { get; set; } public bool IsPrimary { get; set; } = true; public bool IncludesNational { get; set; } public bool AllowsAnyTargetRegion { get; set; } public LearningLicenseStatus Status { get; set; } = LearningLicenseStatus.Active; public DateTimeOffset StartsAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? EndsAt { get; set; } public long Version { get; set; } = 1; } public sealed class TenantLearningLicenseRegion : Entity, ITenantOwned { public Guid LicenseId { get; set; } public Guid MarketRegionId { get; set; } public bool IsBaseRegion { get; set; } public Guid TenantId { get; set; } } public sealed class LearningProduct : AuditableTenantEntity { public Guid BusinessLineId { get; set; } public string Code { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public bool IsActive { get; set; } = true; } public sealed class LearningProductScope : Entity, ITenantOwned { public Guid ProductId { get; set; } public Guid ContentSliceOwnerTenantId { get; set; } public Guid ContentSliceId { get; set; } public Guid TenantId { get; set; } } public sealed class ContentSlice : AuditableTenantEntity { public Guid BusinessLineId { get; set; } public Guid? MarketRegionId { get; set; } public LearningRegionScopeKind RegionScope { get; set; } = LearningRegionScopeKind.Region; public LearningContentResourceType ResourceType { get; set; } = LearningContentResourceType.QuestionBank; public Guid ResourceId { get; set; } public long ContentVersion { get; set; } = 1; public ContentSliceStatus Status { get; set; } = ContentSliceStatus.Active; } public sealed class StudentTargetRegionHistory : AuditableTenantEntity { public Guid UserId { get; set; } public Guid BusinessLineId { get; set; } public Guid MarketRegionId { get; set; } public DateTimeOffset EffectiveAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? EndedAt { get; set; } public bool IsCurrent { get; set; } = true; public Guid? ChangedBy { get; set; } public string? Reason { get; set; } } public sealed class ClassContentAssignment : AuditableTenantEntity { public Guid ClassId { get; set; } public Guid ContentSliceOwnerTenantId { get; set; } public Guid ContentSliceId { get; set; } public LearningContentResourceType ResourceType { get; set; } public Guid ResourceId { get; set; } public DateTimeOffset StartsAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? EndsAt { get; set; } public ClassContentAssignmentStatus Status { get; set; } = ClassContentAssignmentStatus.Active; public Guid? CreatedBy { get; set; } public Guid? RevokedBy { get; set; } public string? RevokedReason { get; set; } } public sealed class LearningAccessVersion : TenantEntity { public Guid UserId { get; set; } public long GrantVersion { get; set; } = 1; public long ContentVersion { get; set; } = 1; public long StrongRevocationVersion { get; set; } = 1; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; } public enum LearningRegionAccessStrategy { NationalOnly, LicensedRegions, NationalWithStudentTargetRegion, NationalWithLicensedRegions } public enum LearningLicenseStatus { Active, Suspended, Expired, Cancelled } public enum LearningRegionScopeKind { National, Region } public enum LearningContentResourceType { QuestionBank, Collection, Blueprint, ContentEntry, ContentNode } public enum ContentSliceStatus { Draft, Active, Retired } public enum ClassContentAssignmentStatus { Active, Revoked, Expired }