using NetCorePal.Extensions.Domain; namespace Fengling.RiskControl.Domain.Aggregates.RiskScores; public class RiskScore : Entity, IAggregateRoot { public long MemberId { get; private set; } public string EntityType { get; private set; } = string.Empty; public string EntityId { get; private set; } = string.Empty; public int TotalScore { get; private set; } public RiskLevel RiskLevel { get; private set; } private readonly List _factors = new(); public IReadOnlyCollection Factors => _factors.AsReadOnly(); public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; public DateTime? ExpiresAt { get; private set; } private RiskScore() { } public static RiskScore Create(long memberId, string entityType, string entityId, DateTime? expiresAt = null) { return new RiskScore { MemberId = memberId, EntityType = entityType, EntityId = entityId, TotalScore = 0, RiskLevel = RiskLevel.Low, ExpiresAt = expiresAt }; } public void AddRiskFactor(string factorType, int points, string description) { _factors.Add(RiskFactor.Create(factorType, points, description)); RecalculateScore(); } public void Reset() { _factors.Clear(); TotalScore = 0; RiskLevel = RiskLevel.Low; } private static readonly int HIGH_THRESHOLD = 70; private static readonly int MEDIUM_THRESHOLD = 30; private void RecalculateScore() { TotalScore = _factors.Sum(f => f.Points); RiskLevel = TotalScore >= HIGH_THRESHOLD ? RiskLevel.High : TotalScore >= MEDIUM_THRESHOLD ? RiskLevel.Medium : RiskLevel.Low; } public bool IsExpired() { return ExpiresAt.HasValue && DateTime.UtcNow > ExpiresAt.Value; } }