using Core.Entities; namespace Core.Validation.Rules.BaseRules; /// /// Base class for validation rules that check event counts against thresholds for student rankings /// Similar to EventCountThresholdRuleBase but works with Student entities instead of StudentEventStatistics /// public abstract class EventCountThresholdRankingRuleBase : IValidationRule { /// /// Get the actual count to validate /// protected abstract int GetCount(Student student); /// /// Get the threshold value from configuration /// protected abstract int GetThreshold(ValidationConfiguration config); /// /// Check if the count violates the threshold /// protected abstract bool ViolatesThreshold(int count, int threshold); /// /// Get the severity from configuration /// protected abstract ValidationSeverity GetSeverity(ValidationConfiguration config); /// /// The validation warning code /// protected abstract string Code { get; } /// /// Build the display message /// protected abstract string GetMessage(int count, int threshold); /// /// Icon identifier for the warning (can be null) /// protected virtual string? IconIdentifier => null; /// /// Build additional metadata beyond the standard fields /// protected virtual Dictionary BuildAdditionalMetadata(Student student, ValidationConfiguration config) { return new Dictionary(); } public ValidationWarning? Validate(Student entity, ValidationConfiguration config) { var count = GetCount(entity); var threshold = GetThreshold(config); if (!ViolatesThreshold(count, threshold)) return null; var metadata = new Dictionary { { "StudentId", entity.Id }, { "StudentName", entity.FirstNameLastName } }; // Add any additional metadata from derived class foreach (var kvp in BuildAdditionalMetadata(entity, config)) { metadata[kvp.Key] = kvp.Value; } return new ValidationWarning { Code = Code, Message = GetMessage(count, threshold), Severity = GetSeverity(config), Context = ValidationContext.StudentRanking, IconIdentifier = IconIdentifier, Metadata = metadata }; } public bool AppliesTo(ValidationContext context) => context == ValidationContext.StudentRanking || context == ValidationContext.StudentRegistration; }