sprints enhancements
This commit is contained in:
@@ -43,6 +43,18 @@ internal sealed class PolicyEvaluator
|
||||
}
|
||||
|
||||
public PolicyEvaluationResult Evaluate(PolicyEvaluationRequest request)
|
||||
{
|
||||
return Evaluate(request, injectedScore: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluate a policy with an optional pre-computed EWS score.
|
||||
/// When injectedScore is provided, it will be used instead of computing EWS from context.
|
||||
/// This is primarily for testing score-based policy rules.
|
||||
/// </summary>
|
||||
public PolicyEvaluationResult Evaluate(
|
||||
PolicyEvaluationRequest request,
|
||||
global::StellaOps.Signals.EvidenceWeightedScore.EvidenceWeightedScoreResult? injectedScore)
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
@@ -54,8 +66,8 @@ internal sealed class PolicyEvaluator
|
||||
throw new ArgumentNullException(nameof(request.Document));
|
||||
}
|
||||
|
||||
// Pre-compute EWS so it's available during rule evaluation for score-based rules
|
||||
var precomputedScore = PrecomputeEvidenceWeightedScore(request.Context);
|
||||
// Use injected score if provided, otherwise compute from context
|
||||
var precomputedScore = injectedScore ?? PrecomputeEvidenceWeightedScore(request.Context);
|
||||
|
||||
var evaluator = new PolicyExpressionEvaluator(request.Context, precomputedScore);
|
||||
var orderedRules = request.Document.Rules
|
||||
|
||||
@@ -282,9 +282,34 @@ internal sealed class PolicyExpressionEvaluator
|
||||
{
|
||||
var leftValue = Evaluate(left, scope).Raw;
|
||||
var rightValue = Evaluate(right, scope).Raw;
|
||||
|
||||
// For ScoreScope, use the numeric value for comparison
|
||||
if (leftValue is ScoreScope leftScope)
|
||||
{
|
||||
leftValue = leftScope.ScoreValue;
|
||||
}
|
||||
|
||||
if (rightValue is ScoreScope rightScope)
|
||||
{
|
||||
rightValue = rightScope.ScoreValue;
|
||||
}
|
||||
|
||||
// Normalize numeric types for comparison (decimal vs int, etc.)
|
||||
if (IsNumeric(leftValue) && IsNumeric(rightValue))
|
||||
{
|
||||
var leftDecimal = Convert.ToDecimal(leftValue, CultureInfo.InvariantCulture);
|
||||
var rightDecimal = Convert.ToDecimal(rightValue, CultureInfo.InvariantCulture);
|
||||
return new EvaluationValue(comparer(leftDecimal, rightDecimal));
|
||||
}
|
||||
|
||||
return new EvaluationValue(comparer(leftValue, rightValue));
|
||||
}
|
||||
|
||||
private static bool IsNumeric(object? value)
|
||||
{
|
||||
return value is decimal or double or float or int or long or short or byte;
|
||||
}
|
||||
|
||||
private EvaluationValue CompareNumeric(PolicyExpression left, PolicyExpression right, EvaluationScope scope, Func<decimal, decimal, bool> comparer)
|
||||
{
|
||||
var leftValue = Evaluate(left, scope);
|
||||
@@ -314,6 +339,13 @@ internal sealed class PolicyExpressionEvaluator
|
||||
return true;
|
||||
}
|
||||
|
||||
// Support direct score comparisons (score >= 70)
|
||||
if (value.Raw is ScoreScope scoreScope)
|
||||
{
|
||||
number = scoreScope.ScoreValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
number = 0m;
|
||||
return false;
|
||||
}
|
||||
@@ -384,6 +416,7 @@ internal sealed class PolicyExpressionEvaluator
|
||||
int i => i,
|
||||
long l => l,
|
||||
string s when decimal.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var value) => value,
|
||||
ScoreScope scoreScope => scoreScope.ScoreValue,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
@@ -968,6 +1001,11 @@ internal sealed class PolicyExpressionEvaluator
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the numeric score value for direct comparison (e.g., score >= 80).
|
||||
/// </summary>
|
||||
public decimal ScoreValue => score.Score;
|
||||
|
||||
public EvaluationValue Get(string member) => member.ToLowerInvariant() switch
|
||||
{
|
||||
// Core score value (allows direct comparison: score >= 80)
|
||||
|
||||
Reference in New Issue
Block a user