using System.Text.Json; using Tiku.Domain.Common; namespace Tiku.Domain.Learning; public sealed class ExamDate : AuditableTenantEntity { public Guid? RegionId { get; set; } public Guid? SchoolId { get; set; } public string? LegacyId { get; set; } public string ExamName { get; set; } = string.Empty; public DateTimeOffset? ExamAt { get; set; } public string? ExamType { get; set; } public string? Description { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } = true; public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class Report : AuditableTenantEntity { public Guid? QuestionId { get; set; } public Guid? UserId { get; set; } public Guid? HandledBy { get; set; } public string? LegacyId { get; set; } public ReportType? Type { get; set; } public string? Title { get; set; } public string? Category { get; set; } public string? Description { get; set; } public ReportStatus Status { get; set; } = ReportStatus.Pending; public ReportPriority Priority { get; set; } = ReportPriority.Normal; public DateTimeOffset? HandledAt { get; set; } public string? Resolution { get; set; } public string? Contact { get; set; } public JsonElement Attachments { get; set; } = JsonDefaults.Array(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class ReportStatusEvent : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid ReportId { get; set; } public ReportStatus? FromStatus { get; set; } public ReportStatus ToStatus { get; set; } = ReportStatus.Pending; public string? Note { get; set; } public Guid? ActorUserId { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class UserScoreEvent : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid UserId { get; set; } public UserScoreEventType EventType { get; set; } = UserScoreEventType.ManualAdjust; public int Points { get; set; } public int BalanceAfter { get; set; } public string? SourceType { get; set; } public Guid? SourceId { get; set; } public string? IdempotencyKey { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class PracticeDailyUsage : AuditableTenantEntity { public Guid UserId { get; set; } public DateOnly UsageDate { get; set; } = DateOnly.FromDateTime(DateTime.UtcNow); public PracticeUsageScopeType ScopeType { get; set; } = PracticeUsageScopeType.Tenant; public Guid? ScopeId { get; set; } public int FreeLimit { get; set; } = 25; public int UsedCount { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class PracticeAccessEvent : Entity, ITenantOwned { public Guid TenantId { get; set; } public Guid? UserId { get; set; } public Guid? PracticeSessionId { get; set; } public PracticeAccessEventType EventType { get; set; } = PracticeAccessEventType.SessionCreated; public PracticeAccessEventMode AccessMode { get; set; } = PracticeAccessEventMode.Free; public int RequestedCount { get; set; } public int GrantedCount { get; set; } public int ConsumedFreeQuota { get; set; } public string? Reason { get; set; } public PracticeUsageScopeType? ScopeType { get; set; } public Guid? ScopeId { get; set; } public Guid? EntitlementId { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class PracticeSessionReport : AuditableTenantEntity { public Guid UserId { get; set; } public Guid PracticeSessionId { get; set; } public Guid? BlueprintId { get; set; } public Guid? CollectionId { get; set; } public string Mode { get; set; } = "mock_exam"; public int TotalQuestions { get; set; } public int AnsweredCount { get; set; } public int CorrectCount { get; set; } public int WrongCount { get; set; } public int UnansweredCount { get; set; } public decimal Score { get; set; } public decimal TotalScore { get; set; } public decimal Accuracy { get; set; } public int DurationSeconds { get; set; } public DateTimeOffset? StartedAt { get; set; } public DateTimeOffset SubmittedAt { get; set; } = DateTimeOffset.UtcNow; public JsonElement SectionStats { get; set; } = JsonDefaults.Array(); public JsonElement QuestionResults { get; set; } = JsonDefaults.Array(); public JsonElement WrongQuestionIds { get; set; } = JsonDefaults.Array(); public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class PracticeSessionReportSection : AuditableTenantEntity { public Guid ReportId { get; set; } public Guid PracticeSessionId { get; set; } public string SectionKey { get; set; } = string.Empty; public string? SectionName { get; set; } public string? QuestionType { get; set; } public int QuestionCount { get; set; } public int AnsweredCount { get; set; } public int CorrectCount { get; set; } public int WrongCount { get; set; } public int UnansweredCount { get; set; } public decimal Score { get; set; } public decimal TotalScore { get; set; } public decimal Accuracy { get; set; } public int SortOrder { get; set; } public JsonElement Metadata { get; set; } = JsonDefaults.Object(); } public sealed class DashboardDailyStat : AuditableTenantEntity { public Guid? RegionId { get; set; } public string? LegacyId { get; set; } public string? LegacyRegionId { get; set; } public DateOnly StatDate { get; set; } public int NewUsers { get; set; } public int NewQuestions { get; set; } public int NewOrders { get; set; } public int NewRevenueCents { get; set; } public int ActiveUsers { get; set; } public DateTimeOffset? RebuiltAt { get; set; } } public sealed class RevenueDailyStat : AuditableTenantEntity { public Guid? RegionId { get; set; } public string? LegacyId { get; set; } public string? LegacyRegionId { get; set; } public DateOnly StatDate { get; set; } public string? SaleType { get; set; } public int RealRevenueCents { get; set; } public int OrderCount { get; set; } public int CodeCount { get; set; } public int CodeUsed { get; set; } public int CodeEstimated { get; set; } public int EstimatedRevenueCents { get; set; } public DateTimeOffset? RebuiltAt { get; set; } } public enum ReportType { QuestionError, ContentError, VideoError, AssetError, SystemBug, Suggestion, Other } public enum ReportStatus { Pending, Accepted, Rejected, Resolved, Closed } public enum ReportPriority { Low, Normal, High, Urgent } public enum UserScoreEventType { CheckIn, ManualAdjust, FeedbackReward, ActivityReward, RedeemCost } public enum PracticeUsageScopeType { Tenant, Region, Subject, QuestionBank, ContentEntry, ContentNode, Collection, Blueprint } public enum PracticeAccessEventType { SessionCreated, SessionDenied, QuotaConsumed } public enum PracticeAccessEventMode { Free, Svip, Staff, Denied }